Author Posts

January 7, 2015 at 10:41 pm

I have a script that is working great, but I would like the addition of retrieving exit codes. My script uninstalls one program and installs another using the Start-Process cmdlet, but the exit code is not displaying. I read that there is a bug in the Start-Process cmdlet and that is why it is not displaying an exit code.

Basically all I am doing is the following:

$p=start-process -filepath msiexec -argumentlist 'parameter1', 'parameter2', 'parameter3' -nonewwindow -wait

if ($p.exitcode -eq 0)
{
write-output "the program was installed successfully"
}

I used the following method as well, but it is still not displaying the exit code:

$p = [System.Diagnostics.Process]::Start("program.exe", "parameter1")

$p.ExitCode

Does anyone have any good techniques for grabbing exit codes?

Thanks

January 8, 2015 at 5:02 am

This was a bug that I remember seeing a while back. Tobias Weltner posted it on Connect here:

https://connect.microsoft.com/PowerShell/feedback/details/520554/start-process-does-not-return-exitcode-property

The article states this was fixed in PS version 4.0. What version do you have?

Also, check here for workarounds:

http://stackoverflow.com/questions/10262231/obtaining-exitcode-using-start-process-and-waitforexit-instead-of-wait

January 8, 2015 at 7:26 am

You need to use the parameter -PassThru on Start-Process to get anything returned

January 8, 2015 at 7:52 am

Ahhhh -Passthru that was it, thanks.

Also, how do I get Write-Warning to display the exit code?

I am trying something like this and it isn't working:

Write-Warning -Message "Exit code: $(($InstallSCEP).ExitCode)"

I've also tried:

Write-Warning -Message "Exit code: $InstallSCEP.ExitCode"

and

Write-Warning -Message "Exit code: $($InstallSCEP.ExitCode)"

But nothing seems to work to display the exit code with Write-Warning.

Thanks for again for your help

January 8, 2015 at 10:43 am

If you have a value in $InstallSCEP.ExitCode, then the first and third options will display the value. I should note that the third option would be preferred, since the first has unnecessary parenthesis. I took the liberty of trying out Start-Process and it's parameters in PS 3.0 (on Server 2012) and PS 4.0 (on Windows 8.1).

[u][b]PowerShell 3.0[/b] (on Server 2012)[/u]
PS C:\> $PSVersionTable.PSVersion.Major
3
PS C:\> $x = Start-Process calc.exe -PassThru
PS C:\> $x.ExitCode # While calc.exe is running
PS C:\> # Nothing returned, as we'd suspect
PS C:\> $x.ExitCode # After calc.exe is closed
PS C:\> # Nothing returned –> have to use -Wait in PS 3.0
PS C:\>
PS C:\>
PS C:\> $y = Start-Process calc.exe -PassThru -Wait
PS C:\> $y.ExitCode
0
PS C:\> Write-Warning -Message "Exit Code: $($y.ExitCode)."
WARNING: Exit Code: 0.

[u][b]PowerShell 4.0[/b] (on Windows 8.1)[/u]
PS C:\> $PSVersionTable.PSVersion.Major
4
PS C:\> $x = Start-Process calc.exe -PassThru
PS C:\> $x.ExitCode # While calc.exe is running
PS C:\> # Nothing returned, as we'd suspect
PS C:\> $x.ExitCode # After calc.exe is closed
0
PS C:\> # Wait is not required in PS 4.0
PS C:\> Write-Warning -Message "Exit Code: $($x.ExitCode)."
WARNING: Exit Code: 0.

January 8, 2015 at 1:00 pm

When i run your code, I do not get an exit code value, until I used the -wait parameter, then all was good.

Thanks

However, I still cannot get my exit code to display.

Here is my script:

$ComputerName = @("$env:COMPUTERNAME")

Foreach ($Computer in $ComputerName)
{
If (Test-Connection -ComputerName $Computer -Count 1 -Quiet)
{
$NewLine

Write-Output "$Computer is online!"

$NewLine

Write-Output "Please wait ..."

#——— Check if the SCCM 2012 R2 Client is Installed ———#

$CM12R2ClientInstalled = Get-WmiObject -Class Win32_Product -ComputerName $Computer |
Where-Object -FilterScript { $_.Name -eq "Configuration Manager Client" -and $_.Version -ge "5.00.7958.1000" }

$CM12ClientService = Get-Service -Name CcmExec -ComputerName $Computer

If (($CM12R2ClientInstalled -ne $null) -and ($CM12ClientService -ne $null))
{
$NewLine

Write-Output "The $($CM12R2ClientInstalled.Name) $($CM12R2ClientInstalled.Version) is installed on $Computer"

#———- Check if the FCS Client is Installed ———-#

$FCSInstalled = Get-WmiObject -Class Win32Reg_AddRemovePrograms -ComputerName $Computer |
Where-Object -FilterScript { $_.DisplayName -match "Forefront" }

Foreach ($FCS in $FCSInstalled)
{
If ($FCS)
{
$NewLine

Write-Output "$($FCS.DisplayName) is installed!"

$NewLine

Write-Output "Preparing to uninstall $($FCS.DisplayName)"

#——– Uninstall the FCS Client ———#

$UninstallFCS = Start-Process -FilePath MsiExec -ArgumentList "/X$($FCS.ProdID)" -NoNewWindow -Wait -PassThru

If ($($UninstallFCS.ExitCode) -eq '0')
{
$NewLine

Write-Output "$($FCS.DisplayName) uninstalled successfully!"

$NewLine

#——— Check if the SCEP Client is Installed ———-#

$SCEPInstalled = Get-WmiObject -Class Win32Reg_AddRemovePrograms -ComputerName $Computer |
Where-Object -FilterScript { $_.DisplayName -eq "System Center Endpoint Protection" }

If ($SCEPInstalled -eq $null)
{
$NewLine

Write-Output "The System Center Endpoint Protection client is not installed on $Computer"

#———- Install the SCEP Client ———#

$InstallSCEP = Start-Process -FilePath "C:\Windows\ccmsetup\SCEPInstall.exe" -ArgumentList '/s', '/q', '/NoSigsUpdateAtInitialExp', '/policy "C:\Windows\CCM\EPAMPolicy.xml"' -NoNewWindow -Wait -PassThru

If ($($InstallSCEP.ExitCode) -eq '0')
{
$NewLine

Write-Output "System Center Endpoint Protection installed successfully!"

$NewLine
}

Else
{
$NewLine

Write-Warning -Message "System Center Endpoint Protection failed to install on $Computer with exit error: $($InstallSCEP.ExitCode)"

$NewLine
}
}

Else
{
$NewLine

Write-Output "The System Center Endpoint Protection client is already installed on $Computer!"

$NewLine
}
}

Else
{
$NewLine

Write-Warning -Message "$($FCS.DisplayName) failed to uninstall on $Computer with exit error: $($FCS.ExitCode)"

$NewLine
}
}

Else
{
$NewLine

Write-Output "Microsoft Forefront Client Security is not installed on $Computer!"

$NewLine
}
}
}

Else
{
$NewLine

Write-Output "The System Center Configuration Manager 2012 R2 client is not installed on $Computer!"

$NewLine
}
}

Else
{
$NewLine

Write-Warning -Message "$Computer is not reachable and may be offline!"

$NewLine
}
}

January 9, 2015 at 9:11 am

WOW!!

Okay, I see what my problem was. I should have been using $UninstallFCS.ExitCode, not $FCS.ExitCode on this line:

Write-Warning -Message "$($FCS.DisplayName) failed to uninstall on $Computer with exit error: $($FCS.ExitCode)"

My script is now working as expected.