Aug 24 2022 03:31 PM - edited Aug 25 2022 09:21 AM
Hi I have a PS script which is terminating workflows in SharePoint. I don't want to run this script in one go rather I want to add user intervention as well. Below is my script portion. In line 44, I added a read host command to see which instance is being terminated. What I want is when I press yes then it executes the next command and terminate the workflow but if I press No then it skips the execution of next command and loop to next instance. How can I achieve that?
Thanks
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)
$ListItems = $List.GetItems([Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery())
$Ctx.Load($List)
$Ctx.Load($ListItems)
$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()
#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 "Suspended"})
{
[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"]
}
$WorkflowInstanceService.TerminateWorkflow($WorkflowInstance)
Read-Host -Prompt "Do you want to Terminate this instance:"
$Ctx.ExecuteQuery()
Write-host -f Green "'$($WorkflowAssociations | where {$_.ID -eq $WorkflowInstance.WorkflowSubscriptionId} | Select -ExpandProperty Name)'is Terminated"
}
}
}
Catch {
Write-host -f Red "Error:" $_.Exception.Message
}
Aug 24 2022 11:03 PM
Do{
$Confirmation = Read-Host -Prompt "Are you sure (y/n)?"
if ($Confirmation -like "y"){write-host "The user says Yes" -ForegroundColor Green}
if ($Confirmation -like "n"){write-host "The user says No" -ForegroundColor red;Return}
}
while ($Confirmation -ne "y")
Write-Host "The Other code"
Aug 24 2022 11:46 PM
SolutionAug 25 2022 12:40 AM - edited Aug 25 2022 12:41 AM
Focusing on this part of your problem statement:
"... when I press yes then it executes the next command and terminate the script ..."
I'd suggest this as a replacement for your original lines 44 to 46:
if (Read-Host -Prompt "Do you want to Terminate this instance:" -in @("y", "yes"))
{
$Ctx.ExecuteQuery() ;
Write-host -f Green "'$($WorkflowAssociations | Where-Object {$_.ID -eq $WorkflowInstance.WorkflowSubscriptionId} | Select-Object -ExpandProperty Name)'is Terminated";
return;
}
I don't work with SharePoint, but I do wonder if the original line 43 could also be moved inside this block?
Still, this has the desired effect of only executing the termination if either "y" or "yes" is entered, and if something else is entered, proceeding to the next iteration.
Cheers,
Lain
Aug 25 2022 09:22 AM - edited Aug 25 2022 10:19 AM
good pick, actually its a typo. it should be "terminate the workflow instance." But thanks for the example code
Aug 25 2022 09:24 AM
Aug 25 2022 11:10 AM
Aug 25 2022 01:06 PM - edited Aug 25 2022 01:09 PM
nevermind I got it with following code. Thanks alot all!
$Answer = Read-Host -Prompt "Do you want to Terminate this instance (y or n)?"
if ($Answer -eq "n")
{
Continue
}
$WorkflowInstanceService.TerminateWorkflow($WorkflowInstance)
$Ctx.ExecuteQuery()
Write-host -f Green "'$($WorkflowAssociations | where {$_.ID -eq $WorkflowInstance.WorkflowSubscriptionId} | Select -ExpandProperty Name)'is Terminated"
Aug 24 2022 11:46 PM
Solution