none
Sharepoint Online Powershell script to run a list workflow

    Question

  • I have a workflow that emails people. I am trying to write a powershell script for the sharepoint management PS environment. I am struggling to find the right call to the right method to run just one workflow. I have not found a method in the client SDK that takes the workflow name as a parameter. 

    I leveraged a script I found at Rapid Circle. It iterates over a list of workflow subscriptions. I would like to pass in just one named workflow but have been unsuccessful creating the GUID in the powershell script and then passing it as an argument to return just one  instance of a subscription. Here is the code. I have more comments posted with *** around them:

    # Add Wave16 references to SharePoint client assemblies and authenticate to Office 365 site - required for CSOM
    Add-Type -Path (Resolve-Path "$env:CommonProgramFiles\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll")
    Add-Type -Path (Resolve-Path "$env:CommonProgramFiles\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll")
    Add-Type -Path (Resolve-Path "$env:CommonProgramFiles\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.WorkflowServices.dll")
     
    # Specify tenant admin and site URL
    $SiteUrl = "[TENANT].sharepoint.com/"
    $ListName = "[TITLE OF THE LIST]"
    $UserName = "[USERNAME]"
    $SecurePassword = Read-Host -Prompt "Enter password" -AsSecureString
     
    # Connect to site
    $ClientContext = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl)
    $credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $SecurePassword)
    $ClientContext.Credentials = $credentials
    $ClientContext.ExecuteQuery()
     
    # Get List and List Items
    $List = $ClientContext.Web.Lists.GetByTitle($ListName)
    $ListItems = $List.GetItems([Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery())
    $ClientContext.Load($List)
    $ClientContext.Load($ListItems)
    $ClientContext.ExecuteQuery()
     
    # Retrieve WorkflowService related objects
    $WorkflowServicesManager = New-Object Microsoft.SharePoint.Client.WorkflowServices.WorkflowServicesManager($ClientContext, $ClientContext.Web)
    $WorkflowSubscriptionService = $WorkflowServicesManager.GetWorkflowSubscriptionService()
    $WorkflowInstanceService = $WorkflowServicesManager.GetWorkflowInstanceService()
    $ClientContext.Load($WorkflowServicesManager)
    $ClientContext.Load($WorkflowSubscriptionService)
    $ClientContext.Load($WorkflowInstanceService)
    $ClientContext.ExecuteQuery()
    # Get WorkflowAssociations with List
    $WorkflowAssociations = $WorkflowSubscriptionService.EnumerateSubscriptionsByList($List.Id)
    $ClientContext.Load($WorkflowAssociations)
    $ClientContext.ExecuteQuery()
     
    # Prepare Start Workflow Payload
    $Dict = New-Object 'System.Collections.Generic.Dictionary[System.String,System.Object]'
     
    # Loop List Items to Start Workflow
    For ($j=0; $j -lt $ListItems.Count; $j++){
        $msg = [string]::Format("Starting workflow {0}, on ListItemId {1}", $WorkflowAssociations[0].Name, $ListItems[$j].Id)
        Write-Host $msg
        #Start Workflow on List Item

    ******* IS THERE A WAY TO PASS THE GUID or NAME of the WORKFLOW AS AN ARGUMENT TO THIS NEXT METHOD? HOW? ****   

    $Action= $WorkflowInstanceService.StartWorkflowOnListItem($WorkflowAssociations[0], $ListItems[$j].Id, $Dict)

        $ClientContext.ExecuteQuery()
    }

    Friday, March 17, 2017 10:00 PM

Answers

  • Hi,

    I modify your script a bit to start only one workflow on the list items in a list, all you need to do is provide the workflow name you want to start:

    # Add Wave16 references to SharePoint client assemblies and authenticate to Office 365 site - required for CSOM
    Add-Type -Path (Resolve-Path "$env:CommonProgramFiles\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.dll")
    Add-Type -Path (Resolve-Path "$env:CommonProgramFiles\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.Runtime.dll")
    Add-Type -Path (Resolve-Path "$env:CommonProgramFiles\Microsoft Shared\Web Server Extensions\16\ISAPI\Microsoft.SharePoint.Client.WorkflowServices.dll")
     
    # Specify tenant admin and site URL
    $SiteUrl = "yoursiteurl"
    $ListName = "yourlistname"
    $Username = "youraccount" 
    $Password = "yourpassword" 
    
    $SecurePassword = ConvertTo-SecureString $Password -AsPlainText -Force 
    
    
    
    ##########################################################################
    #specify the workflow template name which you want to start an instance on
    $WorkflowName = "wf2_ls0320"
    ##########################################################################
    
    
    
    
    # Connect to site
    $ClientContext = New-Object Microsoft.SharePoint.Client.ClientContext($SiteUrl)
    $credentials = New-Object Microsoft.SharePoint.Client.SharePointOnlineCredentials($UserName, $SecurePassword)
    $ClientContext.Credentials = $credentials
    $ClientContext.ExecuteQuery()
     
    # Get List and List Items
    $List = $ClientContext.Web.Lists.GetByTitle($ListName)
    $ListItems = $List.GetItems([Microsoft.SharePoint.Client.CamlQuery]::CreateAllItemsQuery())
    $ClientContext.Load($List)
    $ClientContext.Load($ListItems)
    $ClientContext.ExecuteQuery()
     
    # Retrieve WorkflowService related objects
    $WorkflowServicesManager = New-Object Microsoft.SharePoint.Client.WorkflowServices.WorkflowServicesManager($ClientContext, $ClientContext.Web)
    $WorkflowSubscriptionService = $WorkflowServicesManager.GetWorkflowSubscriptionService()
    $WorkflowInstanceService = $WorkflowServicesManager.GetWorkflowInstanceService()
    $ClientContext.Load($WorkflowServicesManager)
    $ClientContext.Load($WorkflowSubscriptionService)
    $ClientContext.Load($WorkflowInstanceService)
    $ClientContext.ExecuteQuery()
    # Get WorkflowAssociations with List
    $WorkflowAssociations = $WorkflowSubscriptionService.EnumerateSubscriptionsByList($List.Id)
    $ClientContext.Load($WorkflowAssociations)
    $ClientContext.ExecuteQuery()
     
    
    For ($i=0; $i -lt $WorkflowAssociations.Count; $i++)
    {
    	Write-Host $WorkflowAssociations[$i].Name "----" $WorkflowAssociations[$i].Id
    
    	if($WorkflowName -eq $WorkflowAssociations[$i].Name)
    	{
    		# Prepare Start Workflow Payload
    		$Dict = New-Object 'System.Collections.Generic.Dictionary[System.String,System.Object]'
    		 
    		# Loop List Items to Start Workflow
    		For ($j=0; $j -lt $ListItems.Count; $j++){
    		    $msg = [string]::Format("Starting workflow {0}, on ListItemId {1}", $WorkflowAssociations[$i].Name, $ListItems[$j].Id)
    		    Write-Host $msg
    		    #Start Workflow on List Item
    		    $Action = $WorkflowInstanceService.StartWorkflowOnListItem($WorkflowAssociations[$i], $ListItems[$j].Id, $Dict)
    		    $ClientContext.ExecuteQuery()
    		}
    		
    	}
    }
    
    
    
    
    
    
    

    The output would be like this(two workflow associations in my list):

    You can view the workflow names in the Workflow Settings page:

    Best regards,

    Patrick

    Please remember to mark the replies as answers if they help.
    If you have feedback for TechNet Subscriber Support, contact tnmff@microsoft.com

    • Marked as answer by GwenMHP Wednesday, March 22, 2017 8:41 PM
    Monday, March 20, 2017 8:31 AM
    Moderator