functions/Invoke-Executable.ps1
<# .SYNOPSIS Executes a executable file (*.exe) and handles stderr and exit codes .DESCRIPTION By default when powershell runs an executable any output to stderr is converted to an ErrorRecord. Many console applications simply write to stderr as a way of separating output from stdout - not because there was an error. .PARAMETER Command The executable command and it's arguments .PARAMETER AllowableExitCodes An array of the allowable exit codes. If the exit code after running the command is not in this list, an exception is thrown. .PARAMETER StdErrAsErrorRecords Indicates lines output to stderr by the command, should be returned as ErrorRecords. By default, this cmdlet converts lines output to stderr to strings that appear as stdout. .EXAMPLE PS C:\> Invoke-Executable "robocopy C:\src C:\dest" -AllowableExitCodes 0,1,2,3,7 Runs the executable robocopy.exe (presumably to copy C:\src to C:\dest) and will not throw an exception if the exit code is one of 0,1,2,3, or 7 .INPUTS Inputs (if any) .OUTPUTS Output (if any) #> function Invoke-Executable { [CmdletBinding(SupportsShouldProcess)] param ( [Parameter(Mandatory, Position = 0, ValueFromPipeline)] [String[]] $Command, [int[]] $AllowableExitCodes = 0, [Switch] $StdErrAsErrorRecords = $false ) Process { if ($PSCmdlet.ShouldProcess("$Command", "Invoke-Executable")) { Write-Verbose "Executing '$Command'" # If ErrorActionPreference is 'Stop', Invoke-Expression will throw if command outputs to stdout $oldErrorAction = $ErrorActionPreference $ErrorActionPreference = 'Continue' # 2>&1 captures stderr in the output but they are still error records $output = Invoke-Expression "$Command 2>&1" # Restore original $ErrorActionPreference $ErrorActionPreference = $oldErrorAction if ($StdErrAsErrorRecords) { $output } else { # Convert ErrorRecords to strings $output | ForEach-Object { Write-Output $_.ToString() } } if ($AllowableExitCodes -notcontains $LASTEXITCODE) { throw "Exit code '$LASTEXITCODE' not in allowable exit codes '$AllowableExitCodes'. Command: '$Command'" } } } } Set-Alias -Name exec -Value Invoke-Executable |