Summary: This blog post describes how to get all workflows in all sites and lists in SharePoint 2010 and SharePoint 2013.
From an administrator point of view, it can be hard to keep track of all workflows used in your SharePoint 2010 environment. To make things a little easier, I created a script that will tell you the names of all workflows that are used within your SharePoint farm.
Please make sure that the user running this script has at least read permissions to the webs you are trying to check.
*UPDATE* Version 1.1 *UPDATE*
– Increased performance by using the .allwebs property instead of Get-SPWeb
– Changed the script so you can run the script as any other PowerShell 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:directoryfilename.txt)" } #Counter variables $webcount = 0 $listcount = 0 $associationcount = 0 #Grab all webs Get-SPSite -Limit All | % {$webs += $_.Allwebs} if($webs.count -ge 1) { foreach($web in $webs) { #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) } $listcount +=1 if($associations.count -ge 1) { 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 $webcount = "0" } else { Write-Host "No webs retrieved, please check your permissions" -ForegroundColor Red -BackgroundColor Black $webcount = "0" }
As you can see the script has only 1 parameter, $writeToFile. Without specifying this parameter, the script will ask for an output location, to save the results. If you do not want the script to save the output, you can call the function like this:
.Get-SPWorkflow -writeToFile $false
I have tested this script on several environments, the largest having 4815 lists checked.
For privacy reasons, I can only show the output from my own testing environment, this is a possible outcome:
would this work for a 2007 farm?
Hi Marc,
I don’t think the current script works for SharePoint 2007.
If I have some spare time, I will look into this as well, since I have the same need for this!
If you run this script more than once, you might want to set the $web = $null, otherwise the number of webs/lists will never reset
Did a version for sp 2007 powershell ever get written? I am trying to find something like this. Thank you.
Hi Larry,
Sorry I haven’t had time to do this. If anyone found a script, I’ll be happy to share it with everyone.
Does your script only identify the “out of the box” SharePoint workflows, or also C# and SharePoint Designer workflows?
Here is the code modifications I did for this script. I have executed it against a 2007 Farm.
param ([boolean] $writeToFile = $true)
#List all workflows in farm
#
# SP2010 and above
#Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
#Load the DLL if it is not already for SharePoint 2007
[void][System.Reflection.Assembly]::LoadWithPartialName(“Microsoft.SharePoint”)
#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:directoryfilename.txt)”
}
#Counter variables
$webcount = 0
$listcount = 0
$associationcount = 0
#Grab all webs
#
# To get all the site collections in SP2007
$WebAppUrl = “http://your web application”
$WebApp = [Microsoft.SharePoint.Administration.SPWebApplication]::Lookup($WebAppUrl)
#Loop through the sites (SPSite)
foreach($site in $WebApp.Sites)
{
# AllWebs is a SPWebCollection for the specified SPSite
# Gets the collection of all Web sites that are
# contained within the site collection, including the
# top-level site and its subsites.
$webs += $site.AllWebs
}
#
# How to get all the webs for SP2010 and above
#Get-SPSite -Limit All | % {$webs += $_.Allwebs}
if($webs.count -ge 1)
{
foreach($web in $webs)
{
#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)
}
$listcount +=1
if($associations.count -ge 1)
{
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
$webcount = “0”
}
else
{
Write-Host “No webs retrieved, please check your permissions” -ForegroundColor Red -BackgroundColor Black
$webcount = “0”
}
I have an SP 2010 question about your script, if you do not mind.
I have executed this against my SP 2010 test farm, and it produces a series of lines.
how would one tweak this script to mark an active workflow – that is, one which would allow new workflows to be run against it? I see many times where there are a series of previous versions of a workflow listed in the above script’s output. That is okay – but today I am not as interested in the older versions as I am the versions which might be able to generate a new instance.
Another thing in which I am interested is being able to determine details of the workflow itself – in particular, the users or groups to which a task in the workflow might be assigned.
How would one enhance the above script to provide that information?
Thank you for this script – it is a useful model.
Thanks for posting this – it works perfectly on our setup. I now trying to understand whet the script does exactly. Please can you tell me what this line does? $associations = @()
Hi,
That line creates an array that I use later in the script to add the running workflows to.
If you have any questions, let me know.
Regards, Nico
Thank you for your quick response. I tried to find something about it on google, but with more words (like ‘array’) I should be able to progress that.
What I’d ideally like to do is to add in a code section that removes the workflow once it has been identified and listed, and then of course write back to say that has been done.
Am I right in thinking that I can do this by modifying your code, adding in the new code after this one: foreach($association in $associations){Write-Host ” -“$association}
You should take a look at this blog: http://blogs.msdn.com/b/guruketepalli/archive/2012/11/06/add-remove-sharepoint-workflows-thru-powershell.aspx
It has a script that removes workflows, maybe you can edit my script using pieces of that script, or the script might be good enough for you! 🙂
Hi Nico, I was looking at that script when you suggested it. The one I used in the end was the one below which I modified slightly from this: http://sharepoint.stackexchange.com/questions/76661/how-to-delete-sharepoint-workflow-from-powershell
Add-PSSnapin Microsoft.SharePoint.PowerShell -ErrorAction SilentlyContinue
$spsite = Get-SPSite “”
$spsite.AllWebs |
Foreach-Object {
$wfas = ($_.Lists |
Select-Object -Expand WorkFlowAssociations |
Select-Object Id, ParentList);
$wfas |
Foreach-Object {
if ($_ -ne $null) {
$_.ParentList.WorkflowAssociations.Remove($_.Id)
}
}
}
Thanks for your help 🙂
Glad I could help!
Hello, I am new to powershell and all I need to do is list all workflows running across the SharePoint 2010 Farm and send it to a .csv with the site url, list/library, and the associated workflow. The script above appears like it may partially do the job, but I do not want to remove the workflow. Any help?
Hi Gordon,
Thanks for taking your time to give some feedback. The script that is provided in the blog post (not the one in the comments) will only display the workflows, it will not remove any workflows.
Regards,
Nico
can i get a script which will only return designer workflow not OOB. for 2010 and 2013
Does this have to be ran on each web server or can it be ran on one server and just add the sites you want to get the workflows on? Example: I would like to run it on server A, but get the workflows for server b, c, d, e, f, etc. but run it on server A the entire time
You only have to run it on 1 server, just use the correct URL. As long as all your servers are in the same SharePoint farm, there should be no problem.
Where do I add the URL? Currently I don’t see a place to specify what URL to use
Hi, you do not have to provide an URL. It will retrieve workflows for all site collections.
ok, so how can I run it on a server but get all workflows within my farm? Currently, I’m only getting the workflows that the script is running on. I now want to get to all the workflows. Or does this have to run on the main server (central admin server) and then it gets all workflows? If so, I unable to run this on that server, I was hoping that I could run this on my developer server and get all workflows on the prod server.
Really good script Nico, this one had been bothering me for ages and helped a lot with producing monthly reports on new workflows.
One problem I’ve found with one of our clients is that it doesn’t detect 2013 workflows, even though they work fine and the farm uses the 2013 engine. Whenever I use the workflowassociations member of a list, or the workflows member of an item, the count method against them only seems to count 2010 workflows. Have you seen this problem before?
Hi Thomas,
Thanks for the feedback. I have to say that I never tried this with SharePoint 2013 workflows.
If I have some free time next week I’ll test it out!
Thanks, for sharing, Nico!
I found a way to enumerate SharePoint 2013 Workflows as well.
See my post:
http://bliblablog.net/powershell-script-get-sharepoint-workflows-farm/
Cool Marksu, thanks for sharing.
Awesome – I had got in touch with MS about it and they sent me the class details, but still been struggling with getting them going… not keen on CSOM at all.
Works perfectly on SP 2013 with a web app in 2010 compatibility mode, tested on 1944 Webs with 29484 lists, now I’m going to modify to remove all Previous Versions Wf
Thanks for the feedback!
Hi Nico,
can code be added to your script that also retrieves the date each workflow was created?
This script returns workflow which are of SharePoint 2010 types not SharePoint 2013 types.
Any idea how to fetch workflows which are of SharePoint 2013 typ.
Hi, Nico thanks for sharing, Any idea on how to get all the workflows running in an office 365 farm? Thanks
how to modify the samescript for sharpoint O365
How to Identify the workflows which are used and unused in the site collection.
Used the above Script it’s just giving the series of lines and later my Windows Powershell ISE is automatically closing.
I couldn’t able to get the total no of workflows
Hi,
Is there a way to get the id list and the id of the workflows?
Thank you!
Hi Esther,
I’ve emailed you an updated script that should also get the information you require.
Regards,
Nico
Thanks for the fast reply yesterday 🙂
I was also wondering if you know how to get the Workflow History Parent Instance?