SharePoint Server WFE High CPU caused by workflow.

Today I had some complaints that the SharePoint farm was slow – one of our teams noticed that an automated site creation process they used was timing out which is rare.

I brought up task manager which showed one of the w3wp.exe processes taking up about 25% CPU on a 4 core system.

I then launched Sysinternals process explorer, which if launched as an administrator, has some nice features.

Using Process Explorer, I was able to tell which IIS site the w3wp runaway process belonged to.
Then I was able to look at the threads to see what thread was consuming CPU in the process
and then I was able to look at the call stack for the thread, which shows the name of the DLL/EXE that was being called – it indicated that Workflow was the likely culprit.

Process explorer1

I then searched the internet for a powershell command to list workflows in the farm and found this one:

With a little bit of fiddling, I was able to alter the script to just the web application (IIS site) in question.

A little bit more fiddling and I added the number of RunningInstances and added an if statement to the output so that it would only output the workflows with running instances.

I was then able to send that to our development team to check up on things

The completed script:
(All credit really goes to Nico Martens at,
I’m only including the script here because I altered it to add the Running count which wasn’t in his original script):

param ([boolean] $writeToFile = $true) 
#List all workflows in farm 
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
#If boolean is set to true, you can specify an outputlocation, to save to textfile.
if($writeToFile -eq $true) 
$outputPath = Read-Host "Outputpath (e.g. C:\directory\filename.txt)" 
#Counter variables 
$webcount = 0 
$listcount = 0 
$associationcount = 0
#Grab all webs 
Get-SPSite -webapplication "" -Limit All | % {$webs += $_.Allwebs} 
if($webs.count -ge 1) 
	write-host "Starting"
    foreach($web in $webs) 
	#write-host $web
    #Grab all lists in the current web 
    $lists = $web.Lists    
        foreach($list in $lists) 
        $associations = @() 
        #Get all workflows that are associated with the current list 
            foreach($listassociation in $list.WorkflowAssociations) 
            $associations += $($ + " running:" + $($listassociation.RunningInstances)
            $listcount +=1        
            if($associations.count -ge 1) 
			if ($listassociation.RunningInstances -gt 0) {
            Write-Host "Website"$web.url -ForegroundColor Green    
            Write-Host "  List:"$list.Title -ForegroundColor Yellow 
            foreach($association in $associations){Write-Host "   -"$association} 
                if($WriteToFile -eq $true) 
                Add-Content -Path $outputPath -Value "Website $($web.url)" 
                Add-Content -Path $outputPath -Value "  List: $($list.Title)" 
                foreach($association in $associations){Add-Content -Path $outputPath -Value "   -$association"} 
                Add-Content -Path $outputPath -Value "`n" 
            } }
$webcount +=1 
#Show total counter for checked webs & lists 
Write-Host "Amount of webs checked:"$webcount 
Write-Host "Amount of lists checked:"$listcount 
Write-Host "No webs retrieved, please check your permissions" -ForegroundColor Red -BackgroundColor Black 

PS, I kept this script Private for a while because I wanted to get Nico’s permission to include his script with my revisions here.
I’m happy to report that Nico was ok with that – thanks to his generosity, this is now a public post!
Nico Martens

Leave a Reply