SOLVED

Converting code to run on single item by disabling for loop

Occasional Contributor

 

 

 

 

hi,

Below i have a chunk of code which is running on each item in my SharePoint online classic document library using a for loop. I want to modify it as a test to run on a single item or any specific item by disabling for loop. How can  I achieve that?

Thanks

 

 

 

#Load SharePoint CSOM Assemblies
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll"
Add-Type -Path "C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll"
Add-Type -Path "C:\Program Files\Common Files\microsoft shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.WorkflowServices.dll"
 
#Set Parameters
$SiteURL="https://xxxx.sharepoint.com/sites"
$ListName =" Documents"
 
#Get Credentials to connect
$Cred= Get-Credential
 
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
}

 

 

 

 

13 Replies
You could use a breakpoint in VSCode?
is there anything i can use in powershell code itself. its a try and catch code with for loop but if i want to test this code on only one single item then what modification i can do? any idea?
If it's not a specific item, then you could use 'break' to stop the script at any point, after line 23 I guess. That way you have all the data in the variables and only process the first item in the foreach loop. If it's a specific item, then you could insert a line before 10 with an 'if ($WorkflowInstance -eq 'xxxx) {' and then a break after line 23 so that it stops processing other items
sorry for not very clear on my query but its for first loop. i am looking for specific ListItem. I have pasted full code in question now just incase
Then perhaps after ForEach($ListItem in $ListItems) a if ($ListItem -eq xxxx) { ?
yes i tried and it giving error
Id is read only property

@Harm_Veenstra 

 

Audi86_0-1661526364046.png

 

 

Something in this part or in the ctx.executequery ?
[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"]

}
this part is just displaying the results.

i am also suggested by someone to try using
$ListItem | where id -eq 10

but not sure how to put it or use it in my case
best response confirmed by Audi86 (Occasional Contributor)
Solution
After line 36 with a if ($ListItem | where id -eq 10) {