Skip to content

Instantly share code, notes, and snippets.

@SCP002
Last active October 12, 2024 02:07
Show Gist options
  • Save SCP002/bf443b8ac06219ac869d7de1ca442c3f to your computer and use it in GitHub Desktop.
Save SCP002/bf443b8ac06219ac869d7de1ca442c3f to your computer and use it in GitHub Desktop.
PowerShell: Start-Process cmdlet, but with support of -CaptureOutput and -RedirectToStdout flags.
#Requires -Version 7.4
#Requires -PSEdition Core
$ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest
<#
.SYNOPSIS
The same as Start-Process but with support of -CaptureOutput and -RedirectToStdout parameters.
.OUTPUTS
Output of the process if -CaptureOutput was specified or process object if -PassThru and -Wait was specified.
#>
function Start-ProcessExt {
[CmdletBinding()]
[OutputType([string[]])]
param (
# File path of the executable.
[Parameter(Mandatory = $true)]
[string]
$FilePath,
# Argument list.
[Parameter()]
[string[]]
$ArgumentList,
# Location where the new process should start in.
[Parameter()]
[string]
$WorkingDirectory,
# Capture output?
[Parameter()]
[switch]
$CaptureOutput,
# Redirect all output to stdout?
[Parameter()]
[switch]
$RedirectToStdout,
# Wait for the program to finish execution?
[Parameter()]
[switch]
$Wait,
# Execute process in the same console window?
[Parameter()]
[switch]
$NoNewWindow,
# Return process object?
[Parameter()]
[switch]
$PassThru,
# Verb to use.
[Parameter()]
[string]
$Verb
)
# Expand FilePath to full form.
$FilePath = Resolve-Path -Path $FilePath
# Verify parameters.
if ($CaptureOutput -and -not $Wait) {
throw 'Unable to use -CaptureOutput without -Wait parameter'
}
if ($CaptureOutput -and -not $NoNewWindow) {
throw 'Unable to use -CaptureOutput without -NoNewWindow parameter'
}
if ($CaptureOutput -and $PassThru) {
throw 'Unable to use -CaptureOutput with -PassThru parameter, refer to $LastExitCode instead'
}
if ($CaptureOutput -and $Verb) {
throw 'Unable to use -CaptureOutput with -Verb parameter'
}
if ($RedirectToStdout -and -not $CaptureOutput) {
throw 'Unable to use -RedirectToStdout without -CaptureOutput parameter'
}
if ($Verb -and $NoNewWindow) {
throw 'Unable to use -Verb with -NoNewWindow parameter'
}
if ($CaptureOutput) {
# Change directory.
if ($WorkingDirectory) {
Push-Location -Path $WorkingDirectory
}
# Start process, capture output, wait to finish.
if ($RedirectToStdout) {
& $FilePath $ArgumentList *>&1
} else {
& $FilePath $ArgumentList
}
# Change directory to previous.
if ($WorkingDirectory) {
Pop-Location
}
} else {
# Build Start-Process commandlet conditional arguments.
$startProcessCondArgs = @{}
if ($Wait) {
$startProcessCondArgs.Add('Wait', $true)
}
if ($NoNewWindow) {
$startProcessCondArgs.Add('NoNewWindow', $true)
}
if ($WorkingDirectory) {
$startProcessCondArgs.Add('WorkingDirectory', $WorkingDirectory)
}
if ($PassThru) {
$startProcessCondArgs.Add('PassThru', $true)
}
if ($Verb) {
$startProcessCondArgs.Add('Verb', $Verb)
}
# Start process, skip output.
Start-Process -FilePath $FilePath -ArgumentList $ArgumentList @startProcessCondArgs
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment