PoshCode Logo PowerShell Code Repository

Work-in-progressSPdeploy (modification of post by view diff)
embed code: <script type="text/javascript" src="http://PoshCode.org/embed/1050"></script>download | new post

Work-in-progress. This script is meant to be run from a “scripts/” subdirectory as part of a larger build structure. It won’t run by itself, but maybe you’ll find the SharePoint deployment bits useful.

Some parts are still ugly.

  1.  
  2.  
  3. [System.Reflection.Assembly]::Load('Microsoft.Build.Utilities.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') | out-null
  4. [System.Reflection.Assembly]::Load('Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c') | out-null
  5. $msbuild = [Microsoft.Build.Utilities.ToolLocationHelper]::GetPathToDotNetFrameworkFile("msbuild.exe", "VersionLatest")
  6.  
  7. $global:basepath = (resolve-path ..).path
  8. $stsadm = Join-Path ([Microsoft.SharePoint.Utilities.SPUtility]::GetGenericSetupPath("BIN")) "stsadm.exe"
  9.  
  10.  
  11. function Run-MSBuild($msBuildArgs)
  12. {
  13.         & $msbuild $msBuildArgs
  14. }
  15.  
  16. function Get-FirstDirectoryUnderneathSrc
  17. {
  18.         dir (Get-FullPath "src") | where { $_.PSIsContainer -eq $true } | select -first 1
  19. }
  20.  
  21. function Get-FullPath($subdirectory)
  22. {
  23.         return join-path -path $basepath -childPath $subdirectory
  24. }
  25.  
  26. $wspbuilder = Get-FullPath("tools\WSPBuilder.exe")
  27. function Run-WspBuilder($rootDirectory)
  28. {
  29.         pushd
  30.         cd $rootDirectory
  31.         & $WSPBuilder -BuildWSP true -OutputPath (Get-FullPath 'deployment')
  32.         popd
  33. }
  34.  
  35. function Clean-Path($dir)
  36. {
  37.         #I don't like the SilentlyContinue option, but we need to ignore the case
  38.         #where there is no directory to delete (in this situation, an error is thrown)
  39.         del $dir -recurse -force -erroraction SilentlyContinue
  40.         mkdir $dir -erroraction SilentlyContinue | out-null
  41. }
  42.  
  43. function Create-DeploymentBatchFile($filename, $featureName, $solutionName, $url)
  44. {
  45.         $contents = @"
  46.  
  47. ECHO OFF
  48. SET STSADM="%PROGRAMFILES%\Common Files\Microsoft Shared\web server extensions\12\BIN\stsadm.exe"
  49. %STSADM% -o deactivatefeature -name $featureName -url $url
  50. %STSADM% -o retractsolution -allcontenturls -immediate -name $solutionName
  51. %STSADM% -o execadmsvcjobs
  52. %STSADM% -o deletesolution -name $solutionName -override
  53. %STSADM% -o addsolution -filename $solutionName
  54. %STSADM% -o deploysolution -allcontenturls -immediate -allowgacdeployment -name $solutionName
  55. %STSADM% -o execadmsvcjobs
  56. REM second call to execadmsvcjobs allows for a little more delay. Shouldn't be necessary, but is.
  57. %STSADM% -o execadmsvcjobs
  58. %STSADM% -o activatefeature -url $url -name $featureName
  59. "@
  60.  
  61.         Out-File -inputObject $contents -filePath $filename -encoding ASCII
  62. }
  63.  
  64. #Do-Deployment - regardless of current status, will install the Solution
  65. function Do-Deployment($featureName, $solutionName, $rootDirectory)
  66. {
  67.         echo $featureName, $solutionName, $rootDirectory
  68.         if (-not (Is-Installed $solutionName)) {
  69.                 Install-Solution -solutionName $solutionName -filename (join-path $rootDirectory $solutionName)
  70.         }
  71.        
  72.         Exec-AdmSvcJobs
  73.        
  74.         if (-not (Is-Deployed $solutionName)) {
  75.                 Deploy-Solution -solutionName $solutionName -featureName $featureName -filename (join-path $rootDirectory $solutionName)
  76.         } else {
  77.                 Upgrade-Solution -solutionName $solutionName -featureName $featureName -filename (join-path $rootDirectory $solutionName)
  78.         }
  79. }
  80.  
  81. function Is-Installed($solutionName)
  82. {
  83.         #is Solution in the Solution store at all?
  84.         return [Microsoft.SharePoint.Administration.SPFarm]::Local.Solutions[$solutionName] -ne $null
  85. }
  86.  
  87. function Is-Deployed($solutionName)
  88. {
  89.         #Is Solution successfully deployed everywhere? Partial/failed deployments don't count as deployed
  90.         $solution = [Microsoft.SharePoint.Administration.SPFarm]::Local.Solutions[$solutionName]
  91.         if ($solution -eq $null) { return false; }
  92.        
  93.         return $solution.Deployed
  94. }
  95.  
  96. function Install-Solution($solutionName, $filename)
  97. {
  98.         #Assumes solution is NOT already installed. For "unsure installation", use Do-Deployment
  99.         [Microsoft.SharePoint.Administration.SPFarm]::Local.Solutions.psbase.Add($filename) | out-null
  100. }
  101.  
  102. function Deploy-Solution($featureName, $solutionName, $filename)
  103. {
  104.         #Assumes solution is already installed. For "unsure installation", use Do-Deployment
  105.         $dateToGuaranteeInstantDeployment = [datetime]::Now.AddDays(-2)
  106.         #method signature requires typed Collection, so we're unrolling
  107.         #the IEnumerable<SPWebApplication> into an array.
  108.         $webApplications = [Microsoft.SharePoint.Administration.SPWebService]::ContentService.WebApplications | % { $_ }
  109.         $webApplicationsCollection = new-object Microsoft.SharePoint.Administration.SPWebApplication[] -arg ($webApplications.Count)
  110.         0..($webApplications.Count-1) | % { $webApplicationsCollection[$_] = $webApplications[$_] }
  111.        
  112.         [Microsoft.SharePoint.Administration.SPFarm]::Local.Solutions[$solutionName].Deploy($dateToGuaranteeInstantDeployment, $true, $webApplicationsCollection, $false)
  113. }
  114.  
  115. function Upgrade-Solution($featureName, $solutionName, $filename)
  116. {
  117.         [Microsoft.SharePoint.Administration.SPFarm]::Local.Solutions[$solutionName].Upgrade($filename)
  118. }
  119.  
  120. function Exec-AdmSvcJobs
  121. {
  122.         & $stsadm -o execadmsvcjobs
  123.         #sleep for a few more seconds to account for concurrency bugs/timing issues
  124.         sleep -seconds 2
  125. }

Submit a correction or amendment below (
click here to make a fresh posting)
After submitting an amendment, you'll be able to view the differences between the old and new posts easily.

Syntax highlighting:


Remember me