My first Powershell command

The other day I finally decided it was time to stop using STSADM and start learning PowerShell. I decided a good way to do this was to rewrite existing STSADM commands in PowerShell.

The first thing I decided to do was to have a quick look at the basics so after a Google I found a video by Todd Klindt called Windows PowerShell for SharePoint Server 2010 Administrators. I found this very useful as a starting point assuming no knowledge and it allowed me to get quickly up and running by searching for commands and getting examples on how to use certain commands.

After watching this I then decided to have a look on TechNet to review some of the commands I would need to know in order to deploy/update a solution package. I managed to find a list of exactly what I was looking for a full list of all PowerShell commands for features and solutions.

Using the commands for features and solutions linked above I started to plan what steps I need to take to as part of my PowerShell script. The feature and solution I was updating contained a Module which loads the a custom JS file to the web.

I think it is always good practice to manually write down the steps you want to accomplish before actually getting started writing any script/code as this allows you to plan out what you are trying to achieve and gives you something to refer to at a later date. With this in mind I worked out the deployment steps should be as follows:

  1. Deactivate feature on each web
  2. Uninstall solution
  3. Remove solution
  4. Add solution
  5. Deploy solution
  6. Activate feature on each web

 

Before starting my PowerShell script I first done some research to see if there was a way to detect if a certain command had finished running. The reason I investigated this was I have had experience before when writing STSADM commands which would not run a timer job was currently in progress and another command was initiated. After some looking around I found the ‘Wait For Command To Complete’ script, see below, on the MSDN site. This meant I was able to kick off a command such as uninstall then call my wait function so the next section of the script had to wait until the previous command completed.

Wait For Command To Complete
  1. # Wait for the SharePoint timer job name that contains "solution-deployment".
  2. function Wait4Timer
  3. {    
  4.     Write-Host -NoNewLine "`nFinding timer job"
  5.     
  6.     # The language-dependent display name of the timer job contains "Solution Retraction".
  7.     # while (($jd = Get-SPTimerJob | ?{ $_.DisplayName -like "*Solution Retraction*"+$fileName+"*" }) -eq $null)
  8.     while (($jd = Get-SPTimerJob | ?{ $_.Name -like "*solution-deployment*" + $fileName + "*" }) -eq $null)
  9.     {
  10.         Write-Host -NoNewLine .
  11.         Start-Sleep -Seconds 1
  12.     }
  13.     $jdName = $jd.Name
  14.     Write-Host "`njob: $jdName"
  15.     Write-Host -NoNewLine Waiting to finish
  16.     
  17.     while ((Get-SPTimerJob $jdName) -ne $null)
  18.     {
  19.        Write-Host -NoNewLine .
  20.        Start-Sleep -Seconds 1
  21.     }
  22.     
  23.     Write-Host
  24.     $jd.HistoryEntries | %{ Write-Host job history: $_.Status }
  25.     Write-Host
  26. } # End of function Wait4Timer.

 

With the wait in place I was then able to go about writing the rest of the script. Referring back to my 6 steps documented above I then proceed to flesh these out and add in the actual PowerShell script. After a few iterations I ended up with the script below. With me still being a novice in this area if there are any issues with this please let me know but I have tested this and it all seems to work ok.

PLEASE NOTE: If you take a copy of this script please run it on a development environment first as while this should be generic and should run on any farm it is always best practice to never run these scripts directly on live without first being tested elsewhere.

  1. # Wait for the SharePoint timer job name that contains "solution-deployment".
  2. function Wait4Timer
  3. {    
  4.     Write-Host -NoNewLine "`nFinding timer job"
  5.     
  6.     # The language-dependent display name of the timer job contains "Solution Retraction".
  7.     # while (($jd = Get-SPTimerJob | ?{ $_.DisplayName -like "*Solution Retraction*"+$fileName+"*" }) -eq $null)
  8.     while (($jd = Get-SPTimerJob | ?{ $_.Name -like "*solution-deployment*" + $fileName + "*" }) -eq $null)
  9.     {
  10.         Write-Host -NoNewLine .
  11.         Start-Sleep -Seconds 1
  12.     }
  13.     $jdName = $jd.Name
  14.     Write-Host "`njob: $jdName"
  15.     Write-Host -NoNewLine Waiting to finish
  16.     
  17.     while ((Get-SPTimerJob $jdName) -ne $null)
  18.     {
  19.        Write-Host -NoNewLine .
  20.        Start-Sleep -Seconds 1
  21.     }
  22.     
  23.     Write-Host
  24.     $jd.HistoryEntries | %{ Write-Host job history: $_.Status }
  25.     Write-Host
  26. } # End of function Wait4Timer.
  27.  
  28. Add-PSSnapin Microsoft.SharePoint.PowerShell
  29.  
  30. #get the current directory
  31. $scriptpath = $MyInvocation.MyCommand.Path
  32. $dir = Split-Path $scriptpath
  33.  
  34. #set the solution name
  35. $solutionName="SolutionName.wsp"
  36. #build up the full path to the file
  37. $solutionPath = $dir + "\" + $solutionName
  38.  
  39. #set the feature ID
  40. $featureID = "6208eb36-05cb-4109-a9d2-b620d3b1b34d"
  41. Write-Host 'Start to disable feature in each site'
  42. #please change the SharePoint site URL as appropriate
  43. $site = Get-SPsite http://sharepoint
  44. foreach($web in $site.AllWebs) {
  45. Write-Host "Deactivate feature for Web " $web.Url
  46. disable-spfeature -identity $featureID -confirm:$false -url $web.Url
  47. }
  48.  
  49. Write-Host 'Start to uninstall solution'
  50. Uninstall-SPSolution -identity $solutionName -confirm:$true
  51.  
  52. Write-Host 'Waiting for unistall job to finish'
  53. Wait4Timer
  54.  
  55. Write-Host 'Start to remove solution'
  56. Remove-SPSolution ?Identity $solutionName -confirm:$true
  57. Write-Host 'Start to add solution'
  58. Add-SPSolution -LiteralPath $solutionPath -confirm:$true
  59.  
  60. Write-Host 'Start to install solution to all web applications'
  61. Install-SPSolution ?Identity $solutionName -GACDeployment -confirm:$true
  62.  
  63. Write-Host 'Waiting for install job to finish'
  64. Wait4Timer
  65.  
  66. Write-Host 'start to enable Feature'
  67. foreach($web in $site.AllWebs) {
  68. Write-Host "Activate featur for Web " $web.Url
  69. Enable-spfeature -identity $featureID -confirm:$false -url $web.Url
  70. }
  71.  
  72. Remove-PSSnapin Microsoft.SharePoint.PowerShell

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

w

Connecting to %s

%d bloggers like this: