Wednesday, 11 August 2010

Add a workflow to a SharePoint list in all sites of a site collection using PowerShell

This script sets up a function to add a workflow association to a specifically named list or document library in all sites of a site collection. For example, adding a workflow to the “Pages” document library in all publishing sites. You use the function by first running the script and then calling it using the following command:

AddWorkflowToLibraries -SiteCollection http://portal -ListName Pages -WfName "Collect Feedback - SharePoint 2010" -WfAssociationName "Collect Feedback"

The example above adds the out-of-box SharePoint 2010 Collect Feedback workflow to the Pages library in each site of the http://portal site collection, calling it “Collect Feedback”. If a site does not have a Pages library (e.g., a Team site), the script will pass over it and continue on to the next site. The script will also continue to the next site if the workflow already exists in the list and I have added an optional delete section (commented out in the script below) which you can use to delete a workflow associated with each list – this will allow you to bulk delete workflow associations before creating new ones.

Run this script first before typing the AddWorkflowToLibraries command above:

function AddWorkflowToLibraries ($SiteCollection, $ListName, $WfName, $WfAssociationName)

    #Get site object and create blank guid to store workflow template ID
    $site = Get-SPSite $SiteCollection
    [Guid]$wfTemplateId = New-Object Guid

    #Step through each web in site collection
    $site | Get-SPWeb -limit all | ForEach-Object {

        #Do the following if a list exists with the name specified by the user - e.g., Pages
        if ($_.Lists[$ListName]) {

            write-host $_.Title"has a list called"$ListName -ForegroundColor green

            $list = $_.Lists[$ListName]
            #Go through each workflow installed in the site to find the correct ID           
            foreach ($wfTemplate in $_.WorkflowTemplates) {
                if ($wfTemplate.Name -eq $WfName) {
                $wfTemplateId = $wfTemplate.Id
            #Set up the template from the ID found
            $wfTemplate = $_.WorkflowTemplates[$wfTemplateId]
            #Check if the site already has a workflow history list - if not, create it
            if(!$_.Lists["Workflow History"])
                $_.Lists.Add("Workflow History", "A system library used to store workflow history information that is created in this site.  It is created by the Publishing feature.",
                "WorkflowHistory", "00BFEA71-4EA5-48D4-A4AD-305CF7030140", 140, "100")
                if (!$_.Features["00BFEA71-4EA5-48D4-A4AD-305CF7030140"]) {
                    Enable-SPFeature -Identity WorkflowHistoryList -Url $_.Url
                $wfHistory = $_.Lists["Workflow History"]
                $wfHistory.Hidden = $true
                $wfHistory = $_.Lists["Workflow History"]
            #Check if the site already has a workflow tasks list - if not, create it
            if(!$_.Lists["Workflow Tasks"])
                $_.Lists.Add("Workflow Tasks", "This system library was created by the Publishing feature to store workflow tasks that are created in this site.", "WorkflowTasks", "BF611337-1591-49f4-BF42-CE7BE53852D8", 107, "100")
            $wfTasks = $_.Lists["Workflow Tasks"]
            #Set up workflow association (extra associated data can be added if you have it)
            $wfAssociation = [Microsoft.SharePoint.Workflow.SPWorkflowAssociation]::CreateListAssociation($wfTemplate, $WfAssociationName, $wfTasks, $wfhistory)
            #Check to see if the association has already been added to the list
            [guid]$wfId = New-Object Guid
            [bool]$wfFound = $false
            foreach ($wf in $list.WorkflowAssociations) {
                if ($wf.Name -eq $wfAssociation.Name) {
                    $wfId = $wf.Id
                    write-host "Workflow"$wf.Name"already exists on"$list.Title"list in site"$_.Title -ForegroundColor green
                    $wfFound = $true
            #If association is already there, ignore the add (and optionally delete it)
            if ($wfFound -eq $true) {
                #Command to remove existing workflow from list before adding new one, if required
                #write-host "Removed workflow"$wfAssociation.Name"from"$list.Title"in site"$_.Title -ForegroundColor green
            #else, add it to the workflow association to the list
                write-host "Added workflow"$wfAssociation.Name"to"$list.Title"in site"$_.Title -ForegroundColor green
        #Report if the site does not have the list specified by the user
        else {
            write-host $_.Title"does not have a list called"$listName -ForegroundColor green
    #Dispose of Site object

Another thing to note here are the names of the history and task lists associated with the workflow. I have gone with “Workflow History” and “Workflow Tasks” but you can change these as required. The script will create these lists if they do not exist already on a site (e.g., when a Publishing site template is used without the approval workflow).


  1. Phil, you're my hero! I have 2 items to add:
    This will allow you to auto start workflows--
    line 52 [bool]$wfFound = $false

    new $wfAssociation.AllowManual = false;

    new $wfAssociation.AutoStartChange = true;

    new $wfAssociation.AutoStartCreate = true;

    line 53 foreach ($wf in $list.WorkflowAssociations) {

    I had to change "Workflow Tasks" to just "Tasks" between lines 43 and 47. IDK why, but once I did that everything worked out great. Thanks again for your site and your smarts!

    1. Hi,
      Can U please help me how can I set 'assign to' and 'cc' fields for collect feedback workflow using powershell.

  2. Thank you Phil.
    This script helped me a lot.
    Keep posting such a great information

  3. Phil, I am trying to figure out whether to customize the OOB Publishing Approval workflow, or copy and modify as a new WF. All I need to do is add a 2nd level of approval to the existing WF.

    If I copy and modify, how do I make my new WF the default for all the Publishing assets (pages, master pages, page layouts, etc.)? I am a bit confused as to how the association is done with the OOB Publishing Approval WF.

    I also have a current thread on with this question (

  4. Phil, this script looks very close to what I'm trying to achieve, which is to add a new workflow to each site created under a specific site. i.e. in simple terms, I have a site collection with two sites: marketing and support. I've created a new workflow call 'support approval', and I want this added to every site created under 'support'. I'll work to see if this is possible, by altering your script.. but.....

    .. I've no idea how to run this script! I can launch SharePoint PowerShell, and can type in short scripts (4 or 5 lines), but the prospect of typing this size of a script by hand is daunting to say the least. I'm pretty sure it's possible to create script and run execute them via PowerShell, but haven't been able to find any websites that explain how.

    Any ideas where I can find such instruction?

  5. Kevin - Yes, this site!

    Read this article:

    I never use the standard command prompt based version of PowerShell. Windows PowerShell ISE is built into PowerShell 2.0 by Microsoft, allows you to copy and paste into a script window, and includes debugging features.

  6. Wonderful! Thanks, Phil. I should have guessed you'd have an article on this too. Many thanks :)

  7. Christopher Smith13 January 2012 at 22:11

    I have a workflow I've made and promoted to reusable and globally reusable however I cannot get it to deploy to all of the subsites of a collection using your script. What needs to be changed in the script to apply my workflow to my collection? Here is the error I receive:

    Exception calling "CreateListAssociation" with "4" argument(s): "Value cannot be null."
    At C:\Users\csmith5\Desktop\workflow.ps1:49 char:106
    + $wfAssociation = [Microsoft.SharePoint.Workflow.SPWorkflowAssociation]::CreateListAssociation <<<< ($wfTemplate, $WfAssociationName, $wfTasks, $wfhistory)
    + CategoryInfo : NotSpecified: (:) [], MethodInvocationException
    + FullyQualifiedErrorId : DotNetMethodException

  8. Phil,

    Awesome post, thanks. Would it be possible to be able to set more options that are on the association form like "End on First Reject" or "End on Document Change"?

  9. Thank you so much for sharing, Phil
    Note: I have changed as "Anonymous Dec 15, 2010 08:05 PM" and it worked for me, thank you too, Annonymous

  10. Phil,

    I have this script that updates every item in one list. I have a problem, when I add a element into this list, this script executes and the workflow asociated too. How can I disable the automatic execution of this script asociated to list?

    Add-PSSnapin "Microsoft.Sharepoint.Powershell"
    $site = Get-SPWeb -identity "http://mywebsite"
    $list = $site.Lists["List"]
    $spitems = $list.items

    foreach($item in $spitems){
    [Microsoft.SharePoint.SPListItem]$spListItem = $item
    Remove-PSSnapin -name "Microsoft.Sharepoint.Powershell"

  11. Thanks for the great post. How do I set this workflow to start when an item is published, make it the default content publishing workflow?

  12. I am running bellow script and when running first one getting error.The term 'AddWorkflowToLibraries' is not recognized as the name of a cmdlet, fu
    nction, script file, or operable program. Check the spelling of the name, or if
    a path was included, verify that the path is correct and try again.
    At C:\FMICPageApprovalWorkflow.ps1:1 char:23
    + AddWorkflowToLibraries <<<< -SiteCollection http://mosspa/ -ListName Pages -
    WfName "Page Approval Workflow" -WfAssociationName "Page Approval Workflow"
    + CategoryInfo : ObjectNotFound: (AddWorkflowToLibraries:String)
    [], CommandNotFoundException
    + FullyQualifiedErrorId : CommandNotFoundException

  13. Hi Phil.
    Its reduced huge time because i configure the workflow more than 20 lists manually.
    This script helped me a lot.
    Thank you very much.

  14. Do you know how to add a workflow in a site? I deploy a workflow in a site collection but cannot deploy it on a site. The workflow template is simply missing in workflow settings.

  15. for beginners like me need a lot of reading and searching for information on various blogs. and articles that you share a very nice and inspires me .

    obat aborsi
    jual obat aborsi

  16. By reading this article many benefits that we can learn. thank you for sharing your insights to us all . boneka full body

  17. Hi Phil,

    You have not added the script for setting the 'assign to' and cc fields for collect feedback approval. Can you Please share that script?

  18. This is a very good article material and it is very useful for us all. thank you . cara menggugurkan kandungan