SharePoint Online: Get Workflow Inventory using PowerShell

Requirement: Find all workflows in a SharePoint Online site collection and export the workflow inventory to a CSV report.

PowerShell to Get Workflow Inventory in SharePoint Online

PowerShell to Export Workflow Inventory in SharePoint Online:

This script gets all workflows from all lists and libraries from a given SharePoint Online site collection and exports the workflow data into a CSV file.

#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.WorkflowServices.dll"

#Function to Get workflows in a site
Function Get-SPOWorkflowInventory($SiteURL, $CSVPath)
{
    Try{
        $WorkflowInventory = @()
        #Setup the context
        $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
        $Ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
    
        #Get the Web and its Subsites
        $Web = $Ctx.Web
        $Ctx.Load($Web)
        $Ctx.Load($Web.Webs)
        $Lists = $Web.Lists
        $Ctx.Load($Lists)
        $Ctx.ExecuteQuery()

        #Initialize Workflow Manager Object
        $WorkflowServicesManager = New-Object Microsoft.SharePoint.Client.WorkflowServices.WorkflowServicesManager($Ctx, $Web)

        Write-host -f Yellow "Searching Workflows in Site: $SiteURL"
        #Loop through each list and get all workflows sharepoint online powershell
        ForEach($List in $Lists)
        {
            #Get SharePoint 2013 Workflows Associated with the List    
            $WorkflowSubscriptionService = $workflowServicesManager.GetWorkflowSubscriptionService()
            $WorkflowAssociations = $WorkflowSubscriptionService.EnumerateSubscriptionsByList($List.Id)
            $Ctx.Load($WorkflowAssociations)
            $Ctx.ExecuteQuery()

            #Loop through each workflow associated with the List
            Foreach ($Association in $WorkflowAssociations | Where {$_.Name -notlike "*Previous Version*"})
            { 
                $WorkflowData = New-Object PSObject
                $WorkflowData | Add-Member NoteProperty WorkflowName($Association.Name)
                $WorkflowData | Add-Member NoteProperty SiteURL($Web.Url)
                $WorkflowData | Add-Member NoteProperty ListName($List.Title)
                Write-host -f Green "`t Found Workflow '$($Association.Name)' in list '$($List.Title)'"
                $WorkflowInventory+=$WorkflowData
            }

            #Get SharePoint 2010 Workflows Associated
            $WorkflowAssociations = $List.WorkflowAssociations
            $Ctx.Load($WorkflowAssociations)
            $Ctx.ExecuteQuery()
            ForEach($Association in $WorkflowAssociations | Where {$_.Name -notlike "*Previous Version*"})
            {
                $WorkflowData = New-Object PSObject
                $WorkflowData | Add-Member NoteProperty WorkflowName($Association.Name)
                $WorkflowData | Add-Member NoteProperty SiteURL($Web.Url)
                $WorkflowData | Add-Member NoteProperty ListName($List.Title)
                Write-host -f Green "`t Found Workflow '$($Association.Name)' in list '$($List.Title)'"
                $WorkflowInventory+=$WorkflowData
            }
        }
        #Export Workflow data to CSV File
        If($WorkflowInventory) { $WorkflowInventory | Export-CSV -LiteralPath $CSVPath -NoTypeInformation -Append}

        #Process Subsites
        Foreach($Subweb in $Web.Webs)
        {
            Get-SPOWorkflowInventory -SiteURL $Subweb.url
        }
    }
    Catch {
    Write-host -f Red "Error:" $_.Exception.Message
    }
}

#Set Parameters
$SiteURL="https://Crescent.sharepoint.com"
$CSVPath = "C:\Temp\WorkflowInventory.csv"

#Remove the CSV file if exists
If(Test-Path $CSVPath) { Remove-Item $CSVPath}

#Get Credentials to connect
$Cred= Get-Credential

#Call the function to get workflow inventory
Get-SPOWorkflowInventory $SiteURL $CSVPath

Get All Running Workflow Instances on a SharePoint Online List

To get a list of all running instances, we got to iterate through each item in the list and fetch the workflow status:

#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.WorkflowServices.dll"

#Set Parameters
$SiteURL="https://Crescent.sharepoint.com/sites/Retail"
$ListName ="Project Tasks"

#Get Credentials to connect
$Cred= Get-Credential

Try{
    #Setup the context
    $Ctx = New-Object Microsoft.SharePoint.Client.ClientContext($SiteURL)
    $Ctx.Credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($Cred.Username, $Cred.Password)
    
    #Get the Web, List and List Item Objects
    $Web = $Ctx.Web
    $Ctx.Load($Web)
    $List = $Web.Lists.GetByTitle($ListName)
    $Ctx.Load($List)
    $Ctx.ExecuteQuery()

    #Initialize Workflow Manager and other related objects
    $WorkflowServicesManager = New-Object Microsoft.SharePoint.Client.WorkflowServices.WorkflowServicesManager($Ctx, $Web)
    $WorkflowSubscriptionService = $workflowServicesManager.GetWorkflowSubscriptionService()
    $WorkflowInstanceService = $WorkflowServicesManager.GetWorkflowInstanceService() 
    $WorkflowAssociations = $WorkflowSubscriptionService.EnumerateSubscriptionsByList($List.Id)
    $Ctx.Load($WorkflowAssociations)
    $Ctx.ExecuteQuery()
    
    #Define Query to get List Items in batch
    $Query = New-Object Microsoft.SharePoint.Client.CamlQuery
    $Query.ViewXml = "<View Scope='RecursiveAll'><RowLimit>2000</RowLimit></View>"
  
    #Batch process list items - to mitigate list threshold issue on larger lists
    Do {  
        #Get items from the list in batches
        $ListItems = $List.GetItems($Query)
        $Ctx.Load($ListItems)
        $Ctx.ExecuteQuery()            
        $Query.ListItemCollectionPosition = $ListItems.ListItemCollectionPosition

        #Loop through each List Item
        ForEach($ListItem in $ListItems)
        {
            #Get Workflow Instances of the List Item            
            $WorkflowInstanceCollection = $WorkflowInstanceService.EnumerateInstancesForListItem($List.Id, $ListItem.Id) 
            $Ctx.Load($WorkflowInstanceCollection)
            $Ctx.ExecuteQuery()
        
            #Get all Workflow Instances in progress
            ForEach ($WorkflowInstance in $WorkflowInstanceCollection | Where {$_.Status -eq "Started"}) 
            { 
                [PSCustomObject] @{
                                    ItemID              = $ListItem.ID
                                    Status              = $WorkflowInstance.Status
                                    WorkflowStarted     = $WorkflowInstance.InstanceCreated
                                    WorkflowAssociation = $WorkflowAssociations | where {$_.ID -eq $WorkflowInstance.WorkflowSubscriptionId} | Select -ExpandProperty Name
                                    ItemUrl = "$($Web.Context.Web.Url)/$($workflowInstance.Properties["Microsoft.SharePoint.ActivationProperties.CurrentItemUrl"])"
                                    StartedBy = $workflowInstance.Properties["Microsoft.SharePoint.ActivationProperties.InitiatorUserId"]
                }
            }
        }
    }While($Query.ListItemCollectionPosition -ne $null)
}
Catch {
Write-host -f Red "Error:" $_.Exception.Message
}

Salaudeen Rajack

Salaudeen Rajack - SharePoint Expert with Two decades of SharePoint Experience. Love to Share my knowledge and experience with the SharePoint community, through real-time articles!

8 thoughts on “SharePoint Online: Get Workflow Inventory using PowerShell

  • Hi Salaudeen,

    Thanks for this, really helpful.

    Is there a way to batch process this script as I ran into “The attempted operation is prohibited because it exceeds the list view threshold.”

    Thanks in advance

    Reply
  • Hi Sir,

    Is there any script to get suspected workflows in sharepoint online site? Can you please help me on it.

    Thanks,
    SV

    Reply
  • Get All Running Workflow Instances on a SharePoint Online List for SP 2010 Workflows

    #Read more: https://www.sharepointdiary.com/2018/05/sharepoint-online-get-workflow-inventory-using-powershell.html#ixzz6W8jdITUa

    Reply
  • PSCustomObject , do we need to define?

    Reply
  • An awesome site for PowerShell!

    Reply
  • Hi, Get All Running Workflow Instances on a SharePoint Online List for SP 2010 Workflows and on diffrent Content types?

    Reply

Leave a Reply

Your email address will not be published. Required fields are marked *