Voici comment je l'ai fait dans le passé, il utilise des événements de StandardOut et StandardError. Comme ceux-ci sont exécutés de manière asynchrone, vous ne contrôlez pas entièrement la sortie (en termes de moment où elle se produit), mais elle devrait être proche de ce dont vous avez besoin.
$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!"
}
}