How to retrieve exit codes

Tagged: 

This topic contains 6 replies, has 4 voices, and was last updated by Profile photo of I Am Sir Ask Alot I Am Sir Ask Alot 1 year, 11 months ago.

  • Author
    Posts
  • #21753
    Profile photo of I Am Sir Ask Alot
    I Am Sir Ask Alot
    Participant

    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

  • #21754
    Profile photo of Matt McNabb
    Matt McNabb
    Participant

    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

  • #21760
    Profile photo of Simon Wåhlin
    Simon Wåhlin
    Participant

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

  • #21761
    Profile photo of I Am Sir Ask Alot
    I Am Sir Ask Alot
    Participant

    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

  • #21763
    Profile photo of tommymaynard
    tommymaynard
    Member

    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.

  • #21766
    Profile photo of I Am Sir Ask Alot
    I Am Sir Ask Alot
    Participant

    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
    }
    }

  • #21774
    Profile photo of I Am Sir Ask Alot
    I Am Sir Ask Alot
    Participant

    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.

You must be logged in to reply to this topic.