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:

http://sharepointrelated.com/2011/11/21/get-all-workflows-in-all-sites-and-lists/

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 sharepointrelated.com,
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 "https://www.mywebsite.com" -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 += $($listassociation.name) + " 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 
$web.Dispose() 
    } 
#Show total counter for checked webs & lists 
Write-Host "Amount of webs checked:"$webcount 
Write-Host "Amount of lists checked:"$listcount 
} 
else 
{ 
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