You have multiple running workflows in a list either in ‘pause’ or ‘wait for item change’. You make a modification to the workflow and publish again. All existing running workflows become ‘workflow name (previous version: date – time). The next time someone updates the list item, you end up with 2 running workflows. This can be problematic if the workflows are used for notification. For example, the user ends up with 2 notification e-mails.


You need to find a way to safely cancel all existing workflows and start the new ones. Note, I have checks / conditions in my workflows so that all the restarted workflows pause / wait at the same state as before. This may not be the case for you, so it is best to run this script in a test environment first.

This script will:

  • Look for a particular list in a site/subsite.
  • Go through all items in the list
  • Go through all workflows in each item
  • Cancel workflows with names matching ‘wftocancel’.
  • Go through the same list
  • Look for all items with the field ‘Verified’ = ‘Completed’.
  • Start the workflow with name matching ‘wftostart’.

Here is the script, update the lines in bold as required.

If you found this helpful, please like my post. Thank you!

#Site and List
$web = Get-SPWeb http://sitename;
$site = Get-SPSite "http://sitecollection"
$listToCancel = "Listname";
$web.AllowUnsafeUpdates = $true;
#Workflows to Remove
$WfToCancel = "Workflow name (previous version...)";
$wfToStart= "Workflow name"
#List Name
$list = $web.Lists[$listToCancel];
#Workflow Manager
$association=$list.WorkFlowAssociations | where {$_.Name -eq $wfToStart}
# Iterate through all Items in List and all Workflows on Items.
foreach ($item in $list.Items) {
foreach ($wf in $item.Workflows) {
#Test for workflow complete and match criteria
if (($wf.ParentAssociation.Name -eq $wfToCancel) -and ($wf.IsCompleted -ne $true))        {
#Show status and cancel Workflows
write-Host $wf.ItemName -nonewline;
write-host "     " -nonewline;
write-host $wf.ParentAssociation.InternalName;
Write-Host " Status " -nonewline;
Write-host $wf.InternalState;
#Filtered List
foreach ($item in $list.Items) {
if ($item["Verified"] -ne "Completed") {
Write-Host "$wftoStart started on " $item.Name
else {
Write-Host $item.Name " - no action taken"