Forum Discussion
Add a line to skip or continue loop execution
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
}
- If you want to skip to the next loop iteration, without existing the loop/script, use the continue statement: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_continue?view=powershell-7.2
- farismalaebSteel Contributor
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"
- If you want to skip to the next loop iteration, without existing the loop/script, use the continue statement: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.core/about/about_continue?view=powershell-7.2
- Audi86Brass Contributorthats exactly what I am looking for. let me try to include it the code.
- Audi86Brass ContributorVasilMichev using LainRobertson code, what will be my code with continue command. Is it something like that?
{
if (Read-Host -Prompt "Do you want to Terminate this instance:" -in @("n", "no"))
{
Continue
}
$Ctx.ExecuteQuery() ;
Write-host -f Green "'$($WorkflowAssociations | Where-Object {$_.ID -eq $WorkflowInstance.WorkflowSubscriptionId} | Select-Object -ExpandProperty Name)'is Terminated";
return;
} - Audi86Brass Contributor
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"
- LainRobertsonSilver Contributor
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
- Audi86Brass Contributor
good pick, actually its a typo. it should be "terminate the workflow instance." But thanks for the example code