One of my clients running SharePoint 2013 on-premises contacted me with a strange issue. They had some SharePoint 2013 platform workflows that were getting suspended, but was not sure why. We got past that initial issue, but what I wanted to talk about today is what we did with all the active workflows that were suspended. 

Resume SharePoint 2013 Suspended Workflows Instead of Cancelling with PowerShell

Normally, when a workflow fails, what do we do? Right, we cancel it and restart it. But that’s a pain, especially for the workflow, and in this case, my client. The workflows had already run through many iterations of approvals, data gathering, and sending out emails only to fail halfway through. We certainly did not want to confuse every users and have to do everything all over again. What do we do?

Solution: PowerShell 

Well, there is a clue if you look at the error in the workflow history:

Resume SharePoint 2013 Suspended Workflows Instead of Cancelling

In 2010, all we could do was terminate the process. In SharePoint 2013 workflows, we can tell the workflow to retry the last action. After fixing the initial issue stopping the workflow at a certain step, we want to just tell it to retry that particular step. If you have 1 or 2 steps, this works great. Unfortunately, we had quite a few more. In this case, we turn to PowerShell.

Using a PowerShell script, we can get all 2013 workflows that are suspended and tell the workflow to resume the last step. Brilliant! Here’s what that looks like:

Add-PSSnapin microsoft.sharepoint.powershell -ErrorAction SilentlyContinue
[Reflection.Assembly]::Load("Microsoft.Workflow.Client, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35") | Out-Null

$web = get-spweb "http://intranet/subsite"
$list = $web.lists["Shared Documents"]
$items = $List.getItems()

#-- Getting a Workflow manager object to work with.
$wfm = New-object Microsoft.SharePoint.WorkflowServices.WorkflowServicesManager($web)
#-- Getting the subscriptions
$sub = $wfm.GetWorkflowSubscriptionService()
#-- Getting the specific workflow within the list of subscriptions on the specific list. (SP2013 associated workflows basically)
$WF = $sub.EnumerateSubscriptionsByList($list.ID) | Where-Object {$_.Name -eq "Workflow_Name"}
#-- Getting a Workflow instance in order to perform my commands.
$wfis=$wfm.GetWorkflowInstanceService()

Foreach($item in $items){
     $wfinstances =  $wfis.EnumerateInstancesForListItem($list.ID, $item.ID);
     foreach($instance in $wfInstances)
     {
         if($instance.status -eq "Suspended")
         {            
             write-host $item.ID "-" $item.Name "is" $instance.status
             $wfis.ResumeWorkflow($instance);            
             Write-Host "Resumed"
         }
     }
}

What you want to note here is the highlighted method of the workflow instance. We can cancel it or resume it. So we connect to the site and list, get the workflow, get all items with that workflow whose status is suspended, and proceed to resume it. 

We can see our options by running this – “$wfis | get-member”:

Get-member of SharePoint 2013 workflow instance

If you need any help with workflows, PowerShell, SharePoint or anything else related, please reach out to us! We are happy to assist.