public/Invoke-ConsoleCommand.ps1
|
function Invoke-ConsoleCommand { <# .DESCRIPTION Invokes a console command which is passed as a string array of commands, values and parameters. .OUTPUTS A PSCustomObject with the following properties: - Success: Boolean - Value: String - Message: String - Command: String - StartTime: DateTime - Duration: Int .PARAMETER Command REQUIRED. Array of String. Alias: -c. A string array representing the console command to be invoked. .PARAMETER Retries OPTIONAL. Int. Alias: -r. The number of times to retry the command if it fails. Default: 3 .PARAMETER RetryDelay OPTIONAL. Int. Alias: -r. The amount of time to wait between retries in seconds. Default: 5 .PARAMETER FailureIsNotAnError OPTIONAL. Switch. Alias: -f. Do not consider a command failure an error. .PARAMETER Silent OPTIONAL. Switch. Alias: -l. Do not display and log events. This overrides the logging preferences set at the environment level. .EXAMPLE Invoke-ConsoleCommand -Command @('c:\windows\notepad.exe','C:\file.txt') -r 3 -d 10 .EXAMPLE Invoke-ConsoleCommand -Command 'launchctl list' -r 3 -d 10 -s #> [OutputType([PSCustomObject])] [CmdletBinding()] [Alias('Invoke-Cmd')] param ( [Parameter()] [Alias('c')] [String[]] $Command, [Parameter()] [Alias('r')] [Int] $Retries = 5, [Parameter()] [Alias('d')] [Int] $RetryDelay = 15, [Parameter()] [Alias('f')] [Switch] $FailureIsNotAnError, [Parameter()] [Alias('x')] [Switch] $Silent ) process { try { $r = [Ordered]@{ command = $Command -join ' ' success = $true value = $null message = $null startTime = $null duration = $null } $commandMsg = $( 'Executing command: {0}' -f $r.Command ) do { try { $r.startTime = Get-Date $commandErrors = $( $r.value = Invoke-Expression -Command $r.command ) 2>&1 if ( $commandErrors ) { if ( $commandErrors -is [System.Management.Automation.ErrorRecord] ) { if ( $commandErrors.Exception.Message.StartsWith( 'WARNING: ' ) ) { $r.message = $commandErrors.Exception.Message if ( -not $Silent ) { Write-Msg -w -il 1 -m $commandMsg Write-Msg -w -il 2 -m $( $commandErrors.Exception.Message ) } } elseif ( $FailureIsNotAnError ) { $r.message = $commandErrors.Exception.Message if ( -not $Silent ) { Write-Msg -d -il 1 -m $commandMsg Write-Msg -d -il 2 -m $( $commandErrors.Exception.Message ) } } else { throw $commandErrors.Exception } } else { throw $commandErrors } } else { if ( -not $Silent ) { Write-Msg -d -il 1 -m $commandMsg } } $r.duration = [Math]::Round((New-TimeSpan -Start $r.startTime -End (Get-Date)).TotalSeconds,0) if ( -not $Silent ) { Write-Msg -d -il 2 -m $( 'Command completed in {0} seconds.' -f $r.duration ) } } catch { $r.success = $false $r.duration = [Math]::Round((New-TimeSpan -Start $r.startTime -End (Get-Date)).TotalSeconds,0) $r.message = $_.Exception.Message if ( -not $Silent ) { Write-Msg -w -il 1 -m $commandMsg Write-Msg -w -il 2 -m $( 'Command failed after {0} seconds.' -f $r.duration ) Write-Msg -w -il 2 -m $( $r.message ) } if ( $Retries -gt 0 ) { if ( -not $Silent ) { Write-Msg -w -il 2 -m $( 'Retrying in {0} seconds ...' -f $RetryDelay ) Start-Sleep -Seconds $RetryDelay } } } $Retries-- } until ( $r.success -or $Retries -le 0 ) if ( -not $Silent -and $FailureIsNotAnError -and -not $r.success ) { Write-Msg -w -il 2 -m 'Command failed after all retries.' } elseif ( -not $Silent -and -not $r.success ) { Write-Msg -e -il 2 -m 'Command failed after all retries.' } } catch { Write-Msg -x -o $_ $r.value = $_.Exception.Message $r.Success = $false } return $r } } |