# encoding: ascii # api: powershell # title: Work-in-progressSPdeploy # description: 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. # version: 3.5 # type: function # license: CC0 # function: Run-MSBuild # x-poshcode-id: 1050 # x-archived: 2010-01-25T15:37:18 # # Some parts are still ugly. # [System.Reflection.Assembly]::Load('Microsoft.Build.Utilities.v3.5, Version=3.5.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a') | out-null [System.Reflection.Assembly]::Load('Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c') | out-null $msbuild = [Microsoft.Build.Utilities.ToolLocationHelper]::GetPathToDotNetFrameworkFile("msbuild.exe", "VersionLatest") $global:basepath = (resolve-path ..).path $stsadm = Join-Path ([Microsoft.SharePoint.Utilities.SPUtility]::GetGenericSetupPath("BIN")) "stsadm.exe" function Run-MSBuild($msBuildArgs) { & $msbuild $msBuildArgs } function Get-FirstDirectoryUnderneathSrc { dir (Get-FullPath "src") | where { $_.PSIsContainer -eq $true } | select -first 1 } function Get-FullPath($subdirectory) { return join-path -path $basepath -childPath $subdirectory } $wspbuilder = Get-FullPath("tools\WSPBuilder.exe") function Run-WspBuilder($rootDirectory) { pushd cd $rootDirectory & $WSPBuilder -BuildWSP true -OutputPath (Get-FullPath 'deployment') popd } function Clean-Path($dir) { #I don't like the SilentlyContinue option, but we need to ignore the case #where there is no directory to delete (in this situation, an error is thrown) del $dir -recurse -force -erroraction SilentlyContinue mkdir $dir -erroraction SilentlyContinue | out-null } function Create-DeploymentBatchFile($filename, $featureName, $solutionName, $url) { $contents = @" ECHO OFF SET STSADM="%PROGRAMFILES%\Common Files\Microsoft Shared\web server extensions\12\BIN\stsadm.exe" %STSADM% -o deactivatefeature -name $featureName -url $url %STSADM% -o retractsolution -allcontenturls -immediate -name $solutionName %STSADM% -o execadmsvcjobs %STSADM% -o deletesolution -name $solutionName -override %STSADM% -o addsolution -filename $solutionName %STSADM% -o deploysolution -allcontenturls -immediate -allowgacdeployment -name $solutionName %STSADM% -o execadmsvcjobs REM second call to execadmsvcjobs allows for a little more delay. Shouldn't be necessary, but is. %STSADM% -o execadmsvcjobs %STSADM% -o activatefeature -url $url -name $featureName "@ Out-File -inputObject $contents -filePath $filename -encoding ASCII } #Do-Deployment - regardless of current status, will install the Solution function Do-Deployment($featureName, $solutionName, $rootDirectory) { echo $featureName, $solutionName, $rootDirectory if (-not (Is-Installed $solutionName)) { Install-Solution -solutionName $solutionName -filename (join-path $rootDirectory $solutionName) } Exec-AdmSvcJobs if (-not (Is-Deployed $solutionName)) { Deploy-Solution -solutionName $solutionName -featureName $featureName -filename (join-path $rootDirectory $solutionName) } else { Upgrade-Solution -solutionName $solutionName -featureName $featureName -filename (join-path $rootDirectory $solutionName) } } function Is-Installed($solutionName) { #is Solution in the Solution store at all? return [Microsoft.SharePoint.Administration.SPFarm]::Local.Solutions[$solutionName] -ne $null } function Is-Deployed($solutionName) { #Is Solution successfully deployed everywhere? Partial/failed deployments don't count as deployed $solution = [Microsoft.SharePoint.Administration.SPFarm]::Local.Solutions[$solutionName] if ($solution -eq $null) { return false; } return $solution.Deployed } function Install-Solution($solutionName, $filename) { #Assumes solution is NOT already installed. For "unsure installation", use Do-Deployment [Microsoft.SharePoint.Administration.SPFarm]::Local.Solutions.psbase.Add($filename) | out-null } function Deploy-Solution($featureName, $solutionName, $filename) { #Assumes solution is already installed. For "unsure installation", use Do-Deployment $dateToGuaranteeInstantDeployment = [datetime]::Now.AddDays(-2) #method signature requires typed Collection, so we're unrolling #the IEnumerable into an array. $webApplications = [Microsoft.SharePoint.Administration.SPWebService]::ContentService.WebApplications | % { $_ } $webApplicationsCollection = new-object Microsoft.SharePoint.Administration.SPWebApplication[] -arg ($webApplications.Count) 0..($webApplications.Count-1) | % { $webApplicationsCollection[$_] = $webApplications[$_] } [Microsoft.SharePoint.Administration.SPFarm]::Local.Solutions[$solutionName].Deploy($dateToGuaranteeInstantDeployment, $true, $webApplicationsCollection, $false) } function Upgrade-Solution($featureName, $solutionName, $filename) { [Microsoft.SharePoint.Administration.SPFarm]::Local.Solutions[$solutionName].Upgrade($filename) } function Exec-AdmSvcJobs { & $stsadm -o execadmsvcjobs #sleep for a few more seconds to account for concurrency bugs/timing issues sleep -seconds 2 }