Geeks With Blogs

News
Steve Clements .Net and then some....

What you need / What you've got?

  1. Pretty obvious, when a user edits/changes a page, you need someone to check its all good before it goes live! Aka Publishing Approval
  2. You can use the "Publishing site with workflow" template or enable it manually or set it up in your custom site definition.
  3. BUT...you've got an entire site collection full of web sites and you need to do it "en-mass" … step up Powershell.
    1. A common scenario could be you were working in Stage or Pre-go live and having Approval workflow just isn't practical or required. Now its live...you need and want it.

What you need to do to SharePoint...

  1. Enable Moderation on the library (that is Content Approval in UI)
  2. Enable Minor Versions (that’s is 1.1, 1.2 etc)
  3. Create the Workflow History list and enable the Workflow History feature (hiding this list is optional, but I think its best, showing the list offers nothing to the user, you can access the same history looking at the workflow status screen, which is far more usefully presented)
  4. Create the Workflow Tasks list
  5. Associate the "Publishing Approval" workflow to the library
  6. Set the properties on the WorkFlow association
    1. This is your choice, but I have set AllowManual to true, AutoStartCreate and Change to false
  7. Add the association
  8. You would be forgiven in thinking that’s it, job done...but you will find that the even though the workflow is there, it doesn't the "major check-in" property enabled so the experience for the user is different i.e they have to choose the non-default option to fire the workflow.
  9. You need to set the property DefaultContentApprovalWorkflowId to the id of the Workflow association object, what tricked me up...even though in the UI the property is in the workflow with the other workflow properties, but this property is on the library.
  10. Still not done...now, the workflow is firing great, but every status is "Rejected". Why? Because you need to Update the workflow association data.
  11. For this I cheated and setup 1 workflow on the pages library, with the correct actions and Approvers group, then went into SharePoint Manager and grabbed the xml from there.
  12. Also I set the Enabled property to true and call WorkflowAssociations.Update(myAssociation) to set both new properties…
  13. Yes, that’s it...you are actually done now!!!

The Magic

This script is 99% influenced by this post http://bit.ly/AcOa2s, I’ve butchered it and added the extra stuff required… FYI: http://get-spscripts.com is a great resource for SharePoint PowerShell scripts...the scripts published are always of high quality, well commented and explained - bookmark it if you don't like thrashing.

The crazy colours and rather OTT output is my fault!

I’ve also put the params at the top – not overly user friendly, but this is perfect for my requirements…you can easily change that!

 

PowerShell script
  1.  
  2. $url = "<site collection URL>"
  3. $list = "Pages"
  4. $workFlowName = "Publishing Approval"
  5. $wfassname = "Page Approval"
  6.  
  7.  
  8.  
  9. function AddWorkflowToLibraries ($SiteCollection, $ListName, $WfName, $WfAssociationName)
  10. {
  11.    #Get site object and create blank guid to store workflow template ID
  12.     $site = Get-SPSite $SiteCollection
  13.    [Guid]$wfTemplateId = New-Object Guid
  14.     
  15.     # Get every sub web
  16.     Get-SPWeb -Site $site | ForEach-Object {
  17.           Write-Host -ForegroundColor White -BackgroundColor DarkMagenta "WEB: "$_.Title$_.Url
  18.         
  19.         #Do the following if a list exists with the name specified by the user - e.g., Pages
  20.         if ($_.Lists[$ListName]) {
  21.             Write-Host "PROCESS:"$listName "list"
  22.             
  23.             #
  24.             # Get list and set version properties
  25.             #
  26.             $list = $_.Lists[$ListName]
  27.             $list.EnableModeration = $true
  28.             $list.EnableMinorVersions = $true
  29.             $list.Update()
  30.             
  31.            #Go through each workflow installed in the site to find the correct ID            
  32.             foreach ($wfTemplate in $_.WorkflowTemplates) {
  33.                 if ($wfTemplate.Name -eq $WfName) {
  34.                    $wfTemplateId = $wfTemplate.Id
  35.                }
  36.            }
  37.             
  38.             #
  39.             #SETUP WORKFLOW HISTORY LIST
  40.             #
  41.             $wfTemplate = $_.WorkflowTemplates[$wfTemplateId]
  42.             if($wfTemplate -eq $null) {
  43.                 Write-Host "ERROR: Workflow '"$WfName "' with ID '"$wfTemplateId "' NOT found" -BackgroundColor Red -ForegroundColor White
  44.             }
  45.             else {
  46.                 #Check if the site already has a workflow history list - if not, create it
  47.                 if(!$_.Lists["Workflow History"])
  48.                 {
  49.                     Write-Host "CREATE: Workflow History list" -ForegroundColor Blue
  50.                     
  51.                     $_.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.",
  52.                     "WorkflowHistory", "00BFEA71-4EA5-48D4-A4AD-305CF7030140", 140, "100")
  53.                     
  54.                     if (!$_.Features["00BFEA71-4EA5-48D4-A4AD-305CF7030140"]) {
  55.                         Enable-SPFeature -Identity WorkflowHistoryList -Url $_.Url
  56.                     }
  57.                     $wfHistory = $_.Lists["Workflow History"]
  58.                     $wfHistory.Hidden = $true
  59.                     $wfHistory.Update()
  60.                 }
  61.                 else
  62.                 {
  63.                     Write-Host "FOUND: Workflow History list" -ForegroundColor green
  64.                     $wfHistory = $_.Lists["Workflow History"]
  65.                 }
  66.                 
  67.                 #
  68.                 #Check if the site already has a workflow tasks list - if not, create it
  69.                 #
  70.                 if(!$_.Lists["Workflow Tasks"]) {
  71.                     $_.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")
  72.                     Write-Host "CREATE: Workflow Tasks list" -ForegroundColor Blue
  73.                 }
  74.                 else {
  75.                     Write-Host "FOUND: Workflow Tasks list" -ForegroundColor green
  76.                 }
  77.                 $wfTasks = $_.Lists["Workflow Tasks"]
  78.                 
  79.                 #
  80.                 #new up workflow association (extra associated data can be added if you have it)
  81.                 #
  82.                 $wfAssociation = [Microsoft.SharePoint.Workflow.SPWorkflowAssociation]::CreateListAssociation($wfTemplate, $WfAssociationName, $wfTasks, $wfhistory)
  83.                 $wfAssociation.AllowManual = $true
  84.                 #$wfAssociation.AllowAsyncManualStart = $true
  85.                 $wfAssociation.AutoStartChange = $false
  86.                 $wfAssociation.AutoStartCreate = $false
  87.                 
  88.                 #
  89.                 #Check to see if the association has already been added to the list
  90.                 #
  91.                 [guid]$wfId = New-Object Guid
  92.                 [bool]$wfFound = $false
  93.                 
  94.                 foreach ($wf in $list.WorkflowAssociations) {
  95.                     if ($wf.Name -eq $wfAssociation.Name) {
  96.                         $wfId = $wf.Id
  97.                         write-host "FOUND: Workflow"$wf.Name"already exists on"$list.Title"list in site"$_.Title -ForegroundColor green
  98.                         $wfFound = $true
  99.                     }
  100.                 }
  101.                 #If association is already there, ignore the add (and optionally delete it)
  102.                 if ($wfFound -eq $true) {
  103.                     #Command to remove existing workflow from list before adding new one, if required
  104.                     #$list.WorkflowAssociations.Remove($wfId)
  105.                     write-host "REMOVE: Workflow"$wfAssociation.Name"from"$list.Title"in site"$_.Title -ForegroundColor Magenta
  106.                 }
  107.                 #else, add it to the workflow association to the list
  108.                 else
  109.                 {
  110.                     #Create the association
  111.                     $list.WorkflowAssociations.Add($wfAssociation) | Out-Null
  112.                     
  113.                     #Set the association data (for approvers and approval steps
  114.                     $wfAssociation.AssociationData = Get-AssociationData
  115.                     #enable is not available until its associated.
  116.                     $wfAssociation.Enabled = $true
  117.                     
  118.                     $list.WorkflowAssociations.Update($wfAssociation)
  119.                     
  120.                     $list.DefaultContentApprovalWorkflowId = $wfAssociation.Id
  121.                     $list.Update()
  122.                     write-host "CREATE: Workflow"$wfAssociation.Name"to"$list.Title"in site"$_.Title -BackgroundColor Cyan -ForegroundColor Red
  123.                 }
  124.             }
  125.         }
  126.         else {
  127.             Write-Host -BackgroundColor DarkRed -ForegroundColor White "No"$listName" list found"
  128.         }
  129.     }
  130.     
  131.    #Dispose of Site object
  132.     $site.Dispose()
  133. }
  134. function Get-AssociationData() {
  135.     return "<dfs:myFields xmlns:xsd=`"http://www.w3.org/2001/XMLSchema`" xmlns:dms=`"http://schemas.microsoft.com/office/2009/documentManagement/types`" xmlns:dfs=`"http://schemas.microsoft.com/office/infopath/2003/dataFormSolution`" xmlns:q=`"http://schemas.microsoft.com/office/infopath/2009/WSSList/queryFields`" xmlns:d=`"http://schemas.microsoft.com/office/infopath/2009/WSSList/dataFields`" xmlns:ma=`"http://schemas.microsoft.com/office/2009/metadata/properties/metaAttributes`" xmlns:pc=`"http://schemas.microsoft.com/office/infopath/2007/PartnerControls`" xmlns:xsi=`"http://www.w3.org/2001/XMLSchema-instance`"><dfs:queryFields /><dfs:dataFields><d:SharePointListItem_RW><d:Approvers><d:Assignment><d:Assignee><pc:Person><pc:DisplayName>Approvers</pc:DisplayName><pc:AccountId>Approvers</pc:AccountId><pc:AccountType>SharePointGroup</pc:AccountType></pc:Person></d:Assignee><d:Stage xsi:nil=`"true`" /><d:AssignmentType>Serial</d:AssignmentType></d:Assignment></d:Approvers><d:ExpandGroups>false</d:ExpandGroups><d:NotificationMessage /><d:DueDateforAllTasks xsi:nil=`"true`" /><d:DurationforSerialTasks xsi:nil=`"true`" /><d:DurationUnits>Day</d:DurationUnits><d:CC /><d:CancelonRejection>true</d:CancelonRejection><d:CancelonChange>true</d:CancelonChange><d:EnableContentApproval>true</d:EnableContentApproval></d:SharePointListItem_RW></dfs:dataFields></dfs:myFields>"
  136. }
  137.  
  138. AddWorkflowToLibraries $url $list $workFlowName $wfassname
Posted on Tuesday, March 6, 2012 6:19 PM Sharepoint | Back to top


Comments on this post: Enable Publishing Approval workflow on all SP Web(s) in an Site collection with Powershell

No comments posted yet.
Your comment:
 (will show your gravatar)


Copyright © Steve Clements | Powered by: GeeksWithBlogs.net