Monday, July 5, 2010

SharePoint Solution Package, JobExitsts and PowerShell

One of the issues we have when we are using the SharePoint Solution Package (wsp) framework for SharePoint is, we don’t know when all the files is copied out to the SharePoint system root (14-hive), because the deployment process is asynchronous. So if we call active-feature right after we deployed and the deployment process is not done yet, we can experience some error because the files is not deployed.

The solution for this is to make the deployment process synchronous or at least wait for it for finish. The easiest way is just to wait for the deployment process to finish and the obvious way to do this is through PowerShell.

On the Microsoft.SharePoint.Administration.SPSolution is there a property call JobExitsts (http://msdn.microsoft.com/en-us/library/microsoft.sharepoint.administration.spsolution.jobexists.aspx). This property tells if there is a deployment process in progress (deploying or retracing) for the solution. So all the PowerShell has to do is to get the solution from the solution store and wait for the JobExitsts property to return false. But we have to build in a fail save so we don’t end up in an endless loop.

I created a function (cmdlet) to do this:

function IsDeploying {
    [CmdletBinding()]
    param
    (
        [Parameter(
                Mandatory=$true, 
                ValueFromPipeline=$true,
                ValueFromPipelineByPropertyName=$true)]
        [ValidateNotNullOrEmpty()]
        [Microsoft.SharePoint.Administration.SPSolution] $Identity
    )
    begin
    {
        $packagename = $Identity.Name
        Write-Progress -Activity "Deployment job:" -Status "Waiting for deployment job for $packagename" -Id 0
    }
    process
    {
        $index = 0
        [DateTime] $startingTime = [DateTime]::Now
        while($Identity.JobExists)
        {
            $index++
            Write-Progress -Activity "Deployment job:" -Status "Job still running" -Id $index
            Start-Sleep -s 5
            if($startingTime -gt [DateTime]::Now.AddMinutes(2))
            {
                #Throw error
                break
            }
        }
        return $Identity
    }
    end
    {
        $index++
        Write-Progress -Activity "Deployment job:" -Status "Deployment job done for $packagename" -Id $index -Completed
    }
}

And the function can be used like this:

$solution = ls -Filter *.wsp -Recurse | % { Add-SPSolution -LiteralPath $_.FullName }´
Install-SPSolution -Identity $solution –GACDeployment
IsDeploying -Identity $solution

No comments:

Post a Comment