Skip to content

Instantly share code, notes, and snippets.

@ritalin
Last active March 10, 2016 08:11
Show Gist options
  • Save ritalin/2d9366022c7f2b71db60 to your computer and use it in GitHub Desktop.
Save ritalin/2d9366022c7f2b71db60 to your computer and use it in GitHub Desktop.
Extended Start-Process Cmdlet
New-Process (Resolve-Path .\usr\bin\influxd.exe) "-config $(Resolve-Path .\etc\influxdb\influxdb.conf)" |
Enable-TextLog -RedirectStandardError access_log -Verbose |
Launch-Process
New-Process (Resolve-Path .\usr\bin\influxd.exe) "-config $(Resolve-Path .\etc\influxdb\influxdb.conf)" |
Enable-EventLog -RedirectStandardError Access -Verbose |
Launch-Process
function New-Process {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true, Position=1)]
[string]$FilePath,
[Parameter(Mandatory=$false, Position=2)]
[string[]]$ArgumentList,
# [PSCredential]$Credential = [PSCredential]::Empty,
[switch]$LoadUserProfile,
[switch]$NoNewWindow,
# [string]$RedirectStandardInput,
# [switch]$UseNewEnvironment,
[Diagnostics.ProcessWindowStyle]$WindowStyle = [Diagnostics.ProcessWindowStyle]::Normal,
[string]$WorkingDirectory = (pwd)
)
$proc = New-Object "System.Diagnostics.Process"
$proc.StartInfo.FileName = $FilePath
$proc.StartInfo.Arguments = $ArgumentList -join ' '
$proc.StartInfo.UseShellExecute = $false
$proc.StartInfo.CreateNoWindow = $NoNewWindow
$proc.StartInfo.LoadUserProfile = $LoadUserProfile
$proc.StartInfo.WindowStyle = $WindowStyle
$proc.StartInfo.WorkingDirectory = $WorkingDirectory
$proc
}
function EnableLogInternal([Diagnostics.Process]$proc, [scriptBlock]$stderrBlock, [scriptBlock]$stdoutBlock) {
$errJob =
if ($proc.StartInfo.RedirectStandardError) {
Register-ObjectEvent -InputObject $proc -EventName ErrorDataReceived -MessageData $stderrBlock -action {
if(-not [string]::IsNullOrEmpty($EventArgs.data)) {
& $event.MessageData $EventArgs.data
}
}
}
$outputjob =
if ($proc.StartInfo.RedirectStandardOutput) {
Register-ObjectEvent -InputObject $proc -EventName OutputDataReceived -MessageData $stdoutBlock -action {
if(-not [string]::IsNullOrEmpty($EventArgs.data)) {
& $event.MessageData $EventArgs.data
}
}
}
$jobs = $errJob,$outputjob | ?{ $_ -ne $null } | %{ [PSCustomObject]@{ Id = $_.Id; Name = $_.Name } }
$exitJob =
Register-ObjectEvent -InputObject $proc -EventName Exited -MessageData $jobs -action {
$jobs1 = @(
$event.MessageData
[PSCustomObject]@{ Id = $eventSubscriber.SubscriptionId; Name = $eventSubscriber.SourceIdentifier }
)
foreach ($j in $jobs1) {
Remove-Event -SourceIdentifier $j.Name
Unregister-Event -SourceIdentifier $j.Name
Stop-Job $j.Id
Remove-Job $j.Id
}
}
$proc
}
function Enable-TextLog {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true, ValueFromPipeline=$true)]
[Diagnostics.Process[]]$processes,
[string]$RedirectStandardError,
[string]$RedirectStandardOutput,
[string]$DirPath = (pwd)
)
begin {
if (-not (Test-Path $DirPath)) { mkdir $DirPath > $null }
}
process {
foreach ($proc in $processes) {
$proc.StartInfo.RedirectStandardError = $RedirectStandardError -ne ""
$proc.StartInfo.RedirectStandardOutput = $RedirectStandardOutput -ne ""
$stdErrBlock = {
param ([string]$message)
Write-Verbose "[$($RedirectStandardError)] $($message)"
$message >> "$DirPath/$($RedirectStandardError).txt"
}
$stdoutBlock = {
param ([string]$message)
Write-Verbose "[$($RedirectStandardOutput)] $($message)"
$message >> "$DirPath/$($RedirectStandardOutput).txt"
}
EnableLogInternal $proc $stdErrBlock.GetNewClosure() $stdoutBlock.GetNewClosure()
}
}
}
function Enable-EventLog {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true, ValueFromPipeline=$true)]
[Diagnostics.Process[]]$processes,
[string]$RedirectStandardError,
[string]$RedirectStandardOutput
)
begin {
}
process {
foreach ($proc in $processes) {
$proc.StartInfo.RedirectStandardError = $RedirectStandardError -ne ""
$proc.StartInfo.RedirectStandardOutput = $RedirectStandardOutput -ne ""
$name = [IO.Path]::GetFileNameWithoutExtension($proc.StartInfo.FileName)
$logName = [Globalization.CultureInfo]::CurrentCulture.TextInfo.ToTitleCase($name)
if ((Get-EventLog -List -AsString) -notcontains $logName) {
New-EventLog -LogName $logName -Source "$LogName.$RedirectStandardError"
New-EventLog -LogName $logName -Source "$LogName.$RedirectStandardOutput"
}
$stdErrBlock = {
param ([string]$message)
Write-Verbose "[$($RedirectStandardError)] $($message)"
Write-EventLog -LogName $LogName -Source "$LogName.$RedirectStandardError" -EntryType Info -EventId 1 -Message $message
}
$stdoutBlock = {
param ([string]$message)
Write-Verbose "[$($RedirectStandardOutput)] $($message)"
Write-EventLog -LogName $LogName -Source "$LogName.$RedirectStandardOutput" -EntryType Info -EventId 2 -Message $message
}
EnableLogInternal $proc $stdErrBlock.GetNewClosure() $stdoutBlock.GetNewClosure()
}
}
}
function Launch-Process {
[CmdletBinding()]
param (
[Parameter(Mandatory=$true, ValueFromPipeline=$true)]
[Diagnostics.Process[]]$processes,
[switch]$Wait,
[switch]$PassThru
)
process {
foreach ($proc in $processes) {
$proc.Start() > $null
if ($proc.StartInfo.RedirectStandardOutput) { $proc.BeginOutputReadLine() }
if ($proc.StartInfo.RedirectStandardError) { $proc.BeginErrorReadLine() }
if ($Wait) {
trap { break }
while (-not $proc.WaitForExit(50)) { }
}
elseif ($PassThru) {
$proc
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment