Skip to content

Commit

Permalink
Added Invoke-Process
Browse files Browse the repository at this point in the history
guitarrapc committed Dec 13, 2014
1 parent 0663bbe commit e305ab6
Showing 1 changed file with 129 additions and 0 deletions.
129 changes: 129 additions & 0 deletions Invoke-Process/Invoke-Process.ps1
Original file line number Diff line number Diff line change
@@ -0,0 +1,129 @@
function Invoke-Process
{
[OutputType([PSCustomObject])]
[CmdletBinding()]
param
(
[Parameter(Mandatory = 0, Position = 0)]
[string]$FileName = "PowerShell.exe",

[Parameter(Mandatory = 0, Position = 1)]
[string]$Arguments = "",

[Parameter(Mandatory = 0, Position = 2)]
[string]$WorkingDirectory = ".",

[Parameter(Mandatory = 0, Position = 3)]
[int]$TimeoutMS = 120000
)

end
{
try
{
# new Process
$process = NewProcess -FileName $FileName -Arguments $Arguments -WorkingDirectory $WorkingDirectory

# Event Handler for Output
$stdEvent = Register-ObjectEvent -InputObject $process -EventName OutputDataReceived -Action $scripBlock -MessageData $stdSb
$errorEvent = Register-ObjectEvent -InputObject $process -EventName ErrorDataReceived -Action $scripBlock -MessageData $errorSb

# execution
$process.Start() > $null
$process.BeginOutputReadLine()
$process.BeginErrorReadLine()

# wait for complete
WaitProcessComplete -Process $process -TimeoutMS $TimeoutMS

# verbose Event Result
$stdEvent, $errorEvent | VerboseOutput

# output
return GetCommandResult -Process $process -StandardStringBuilder $stdSb -ErrorStringBuilder $errorSb
}
finally
{
if ($null -ne $process){ $process.Dispose() }
if ($null -ne $stdEvent){ Unregister-Event -SourceIdentifier $stdEvent.Name }
if ($null -ne $errorEvent){ Unregister-Event -SourceIdentifier $errorEvent.Name }
if ($null -ne $stdEvent){ $stdEvent.Dispose() }
if ($null -ne $errorEvent){ $errorEvent.Dispose() }
}
}

begin
{
# Prerequisites
$stdSb = New-Object -TypeName System.Text.StringBuilder
$errorSb = New-Object -TypeName System.Text.StringBuilder
$scripBlock =
{
if (-not [String]::IsNullOrEmpty($EventArgs.Data))
{

$Event.MessageData.AppendLine($Event.SourceEventArgs.Data)
}
}

function NewProcess ([string]$FileName, [string]$Arguments, [string]$WorkingDirectory)
{
"Execute command : '{0} {1}', WorkingSpace '{2}'" -f $FileName, $Arguments, $WorkingDirectory | VerboseOutput
# ProcessStartInfo
$psi = New-object System.Diagnostics.ProcessStartInfo
$psi.CreateNoWindow = $true
$psi.LoadUserProfile = $true
$psi.UseShellExecute = $false
$psi.RedirectStandardOutput = $true
$psi.RedirectStandardError = $true
$psi.FileName = $FileName
$psi.Arguments+= $Arguments
$psi.WorkingDirectory = $WorkingDirectory

# Set Process
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $psi
return $process
}

function WaitProcessComplete ([System.Diagnostics.Process]$Process, [int]$TimeoutMS)
{
"Waiting for command complete. It will Timeout in {0}ms" -f $TimeoutMS | VerboseOutput
$isComplete = $Process.WaitForExit($TimeoutMS)
if (-not $isComplete)
{
"Timeout detected for {0}ms. Kill process immediately" -f $timeoutMS | VerboseOutput
$Process.Kill()
$Process.CancelOutputRead()
$Process.CancelErrorRead()
}
}

function GetCommandResult ([System.Diagnostics.Process]$Process, [System.Text.StringBuilder]$StandardStringBuilder, [System.Text.StringBuilder]$ErrorStringBuilder)
{
'Get command result string.' | VerboseOutput
$standardString = $StandardStringBuilder.ToString()
$errorString = $ErrorStringBuilder.ToString()
if(($process.ExitCode -eq 0) -and ($standardString -eq "") -and ($errorString -ne ""))
{
$standardOutput = $errorString
$errorOutput = ""
}
else
{
$standardOutput = $standardString
$errorOutput = $errorString
}
return [PSCustomObject]@{
StandardOutput = $standardOutput
ErrorOutput = $errorOutput
ExitCode = $process.ExitCode
}
}

filter VerboseOutput
{
$_ | Out-String -Stream | Write-Verbose
}
}
}

0 comments on commit e305ab6

Please sign in to comment.