SOLVED

Add a line to skip or continue loop execution

Brass Contributor

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
}

 

 

 

 

7 Replies

@Audi86 

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"
best response confirmed by Audi86 (Brass Contributor)
Solution
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?vi...

@Audi86 

 

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

good pick, actually its a typo. it should be "terminate the workflow instance." But thanks for the example code

thats exactly what I am looking for. let me try to include it the code.
@Vasil Michev 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;
}

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"

1 best response

Accepted Solutions
best response confirmed by Audi86 (Brass Contributor)
Solution
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?vi...

View solution in original post