You can tell the status of a deployment by observing the combined values of the Deployed and JobExists properties of the SPSolution object.
SPSolution.Deployed
True - Solution is deployed
False - Solution is not deployed
SPSolution.JobExists
True - A retract/deploy job exists for this solution.
False - No job
It's important to check both of these properties because depending on their state, the solution might not be "seen" as deployed by follow-up actions:
Deployed | JobExists | Is it really deployed?
---------------------------------------------
False | False | No.
False | True | No. But it's being deployed!
True | False | Yes.
True | True | No. The job hasn't yet cleaned up and can block other actions
(I don't like using the SPSolution.JobStatus property because it can be $null even though SPRunningJobStatus should have a value.)
Tying this all together, I use an algorithm similar to this to check on the status of a deployment:
$solution = "example.wsp"
Install-SPSolution -Identity $solution
$deployed = $False
while ($deployed -eq $False) {
sleep -s 5
$s = Get-SPSolution -Identity $solution
if ($s.Deployed -eq $True -And $s.JobExists -eq $False) {
$deployed = $True
}
}
For retracting a solution the logic changes a bit:
Deployed | JobExists | Is it really retracted?
---------------------------------------------
False | False | Yes.
False | True | No. The job hasn't yet cleaned up and can block other actions!
True | False | No.
True | True | No. But it's being retracted!
And in code:
$solution = "example.wsp"
Uninstall-SPSolution -Identity $solution
$deployed = $True
while ($deployed -eq $True) {
sleep -s 5
$s = Get-SPSolution -Identity $solution
if ($s.Deployed -eq $False -And $s.JobExists -eq $False) {
$deployed = $False
}
}