I have a Nintex 2010 Standard Site Collection Reusable workflow template called 'reminders' that runs on a content type called 'requirements' which is basically a task list with a Due Date. I have just made a very important improvement to it. I'd like to stop all instances of it that have not completed and restart it. my architecture is something like this:
site collection
site
project sites
project site 1
requirements list 1
project site 2
requirements list 2
project site 3
requirements list 3
. . .
So I want to iterate over all of the project sites, and then over all of the requirements list items and stop the old version of 'site n reminders' and then start the new version if the Reminder workflow has not completed and the due date is more than 14 days out.
Here are the problems:
- The $list.WorkflowAssociations only gives you the associated list workflows - not the site collection re-usable template (SCRUT) workflows that are associated with the list because of the content type, even though you have to make the association in order to be able to run the SCRUT workflow. This means the association and association data are null and the .StartWorkflow method fails.
- The Cancel workflow portion does not work, but does not throw an error either. The next time you run the workflow, it tries to cancel the same items' workflows all over again.
Here is my powershell (I've attached it as well.
------------------------------
cls
$deadline = (get-date).AddDays(14)
Write-Host "Deadline $deadline"
$site = Get-SPSite "http://sharepoint/site collection"
#Your SharePoint Site URL
$web = Get-SPWeb "http://sharepoint/site collection/site/project sites/";
$web.AllowUnsafeUpdates = $true;
foreach ($subsite in $web.Webs)
{
Write-Host $subsite.Name
$list = $subsite.Lists["Requirements"];
$count = 0
#Workflow Manager
$wfToStart = $subsite.Name
$wfToStart = "$wfToStart Requirement Reminders"
$manager = $subsite.Site.WorkFlowManager
Write-Host "manager: " $manager
$wfas = $site.WorkFlowAssociations
foreach ($wfa in $wfas)
{
Write-Host "associated workflow " $wfa.Name
}
$association = $list.WorkFlowAssociations.GetAssociationByName($wfToStart,"en-US")
Write-Host "association: " $association
$data = $association.AssociationData
Write-Host "Data: " $data
#Loop through all Items in List then loop through all Workflows on each List Items.
foreach ($listItem in $list.Items)
{
$duedate = [datetime]$listItem["Due Date"]
Write-Host " " $listItem["Title"] " " $duedate
if ($duedate -gt $deadline)
{
foreach ($wf in $listItem.Workflows)
{
if(($wf.ParentAssociation.InternalName.contains("Reminders")) -and ($wf.IsCompleted -ne $true))
{
#Cancel Workflow
[Microsoft.SharePoint.Workflow.SPWorkflowManager]::CancelWorkflow($wf);
write-host $wf.ParentAssociation.InternalName" stopped on " $listItem["Name"]
}
}
$wf = $manager.StartWorkFlow($item, $assoc, $data, $true)
}
}
$manager.Dispose()
}
$web.Dispose();
-----------------------------------------------
I've also tried to start the workflow using the webservice Emily Billing, but that does not work either
Start a Workflow using a Web Service
PowerShell - Cancel all Running Workflows - Vadim Tabakman
Aaron Labiosa
How to bulk cancel list item workflows with a status of "Error Occurred"