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.
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!