Sådan har jeg gjort det tidligere, det gør brug af hændelser fra StandardOut og StandardError. Da disse udføres asynkront, har du ikke helt kontrol over outputtet (i forhold til hvornår det sker), men det skal være tæt på det, du har brug for.
$SqlCommandArguments = @()
$SqlCommandArguments += "-S $DbHost"
$SqlCommandArguments += "-d $DbSchema"
$SqlCommandArguments += "-Q `"do some crazy db change here`""
ExecuteProcess -FileName "SqlCmd.exe" -CommandArguments $SqlCommandArguments -Verbose:$VerbosePreference
function ExecuteProcess
{
[cmdletbinding()]
param
(
[string]$FileName,
[string[]]$CommandArguments
)
Write-Verbose "$FileName $CommandArguments"
$startInfo = New-Object System.Diagnostics.ProcessStartInfo
$startInfo.FileName = $FileName
$startInfo.Arguments = $CommandArguments
$startInfo.RedirectStandardError = $true
$startInfo.RedirectStandardOutput = $true
$startInfo.UseShellExecute = $false
$startInfo.CreateNoWindow = $true
$process = New-Object System.Diagnostics.Process
$process.StartInfo = $startInfo
$eventOutputDataReceived = Register-ObjectEvent -InputObject $process -EventName OutputDataReceived -MessageData $VerbosePreference -Action {
if ($($EventArgs.data))
{
Write-Verbose $EventArgs.data -verbose:$event.MessageData
}
}
$global:standardError = New-Object System.Text.StringBuilder
$eventErrorDataReceived = Register-ObjectEvent -InputObject $process -EventName ErrorDataReceived -Action {
if ($($EventArgs.data))
{
$global:standardError.Append("$($EventArgs.data)`r`n")
Write-Warning -message $EventArgs.data
}
}
$process.Start() | Out-Null
$process.BeginOutputReadLine()
$process.BeginErrorReadLine()
$process.WaitForExit()
Unregister-Event -SourceIdentifier $eventOutputDataReceived.Name
Unregister-Event -SourceIdentifier $eventErrorDataReceived.Name
$exitCode = $process.ExitCode
if ($exitCode -ne 0)
{
Write-Error $global:standardError.ToString()
throw "$FileName Failed!"
}
}