Here is a script that terminates all workflows based on their status. It is also possible to filter for specific items with a CAML query and it iterates trough large lists in batch size (of eg. 2000 items), so you won't run in a timeout or memory issue.
In the script there is a second part that will take care of the 2010 workflows, which is located between comment tags.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add-PSSnapin "Microsoft.SharePoint.PowerShell" -ErrorAction SilentlyContinue | |
$webURL = "https://webapplication/sitecollection/site" #change this to the url of the site | |
$listName = "Listname" #change this to the corresponding list | |
$web = Get-SPWeb $webURL | |
$count = 0 | |
$countTarget = 0 | |
$spQuery = New-Object Microsoft.SharePoint.SPQuery | |
$spQuery.ViewAttributes = "Scope='Recursive'"; | |
$spQuery.RowLimit = 2000 #terminates the workflows in batches | |
$caml = "<Where><Eq><FieldRef Name='Fieldname' /><Value Type='Text'>Contenttofilter</Value></Neq></Where>" #this filter will be used to terminate workflows on specific items | |
$spQuery.Query = $caml | |
if($web -ne $null) { | |
$web.AllowUnsafeUpdates = $true; | |
$list = $web.Lists[$listName] | |
$wfm = New-object Microsoft.SharePoint.WorkflowServices.WorkflowServicesManager($web) | |
$sub = $wfm.GetWorkflowSubscriptionService() | |
$wfs = $sub.EnumerateSubscriptionsByList($list.ID) | |
$wfis = $wfm.GetWorkflowInstanceService() | |
do { | |
$listItems = $list.GetItems($spQuery) | |
$spQuery.ListItemCollectionPosition = $listItems.ListItemCollectionPosition | |
foreach($item in $listItems) | |
{ | |
$countTarget++; | |
#Write-Host "Working on item $($item.ID)" -ForegroundColor Cyan | |
#SP2013 WORKFLOWS | |
$workflowInstances = $wfis.EnumerateInstancesForListItem($list.ID,$item.ID) | |
foreach($wf in $workflowInstances) | |
{ | |
if($wf.Status -eq "Suspended") { #status to get and terminate, can also be -ne "Completed" or -eq "Started" | |
$wfName = $wfs | ?{$_.Id -eq $wf.WorkflowSubscriptionId} | select -ExpandProperty Name | |
$wfID= $wf.ID | |
$wfStatus = $wf.Status | |
$wfListItem = $item.Name | |
$count++; | |
$wfis.TerminateWorkflow($wf); | |
Write-Host "Workflow $($wfName) cancelled for: $wfListItem - $($wf.Status)"; | |
#write-host "Workflow Title: $wfName Status: $wfStatus ListItem: $wfListItem" | |
} | |
} | |
#SP2010 WORKFLOWS | |
<# | |
foreach ($workflow in $item.Workflows) | |
{ | |
$wfName = $workflow.ParentAssociation.Name | |
$wfStatus = $workflow.InternalState | |
write-host "Workflow Title: $wfName Status: $wfStatus" | |
#Disregard Completed Workflows | |
if($workflow.InternalState -ne "Completed") | |
{ | |
#Cancel Workflows | |
#[Microsoft.SharePoint.Workflow.SPWorkflowManager]::CancelWorkflow($workflow); | |
Write-Host "Workflow $($workflow.Title) cancelled for: " $item.ID; | |
#$count++; | |
} | |
} | |
#> | |
} | |
} | |
while ($spQuery.ListItemCollectionPosition -ne $null) | |
$web.AllowUnsafeUpdates = $false; | |
$web.Dispose(); | |
Write-Host "Processed $countTarget items and found $count workflows" | |
} else { | |
Write-Host "Web not configured" -ForegroundColor Red | |
} |
No comments:
Post a Comment