I wonder if it's possible to subscribe to the current Powershell session event stream so that every time some information/warning/error etc is added to the stream I can read it as an object. I was able to subscribe to DataAdded
events of the 3 streams mentioned above, but for some reason I can intercept events only from error stream
$InformationPreference = 'Continue'
$ps = [PowerShell]::Create("CurrentRunspace")
$ps.Streams.Information.Add_DataAdded({
# THE EVENT IS NEVER TRIGGERED
$ps.Streams.Information.ReadAll().ForEach{
Write-Host ($_ | Out-String)
}
})
$ps.Streams.Warning.Add_DataAdded({
# THE EVENT IS NEVER TRIGGERED
$ps.Streams.Warning.ReadAll().ForEach{
Write-Host ($_ | Out-String)
}
})
$ps.Streams.Error.Add_DataAdded({
#WORKS FINE
$ps.Streams.Error.ReadAll().ForEach{
Write-Host ($_ | Out-String)
}
})
$ps.AddScript({
Write-Information 'Some Information'
Write-Warning 'Some Warning'
Write-Error 'Some Error'
}).Invoke()
Any ideas why Warning and Information streams don't trigger events?
CodePudding user response:
Here is an example to redirect all streams of a script block to the success stream, keeping the original formatting intact and still be able to differentiate the kind of stream.
& {
[PSCustomObject]@{ Foo = 42; Bar = 23 } | Format-Table # Output
$DebugPreference = 'Continue'
Write-Debug 'Some Debug'
Write-Information 'Some Information'
Write-Warning 'Some Warning'
Write-Error 'Some Error'
} *>&1 | ForEach-Object -PV record { $_ } | Out-String -Stream | ForEach-Object {
# Process a single line of formatted output
$prefix = switch( $record ) {
{ $_ -is [Management.Automation.DebugRecord] } { 'DBG'; break }
{ $_ -is [Management.Automation.InformationRecord] } { 'INF'; break }
{ $_ -is [Management.Automation.WarningRecord] } { 'WRN'; break }
{ $_ -is [Management.Automation.ErrorRecord] } { 'ERR'; break }
default { 'OUT' }
}
# Prepend prefix and output current line
"[$prefix] $_"
}
Output:
[OUT]
[OUT] Foo Bar
[OUT] --- ---
[OUT] 42 23
[OUT]
[OUT]
[DBG] Some Debug
[INF] Some Information
[WRN] Some Warning
[ERR]
[ERR] [PSCustomObject]@{ Foo = 42; Bar = 23 } | Format-Table # Output
[ERR] Write-Debug 'Some Debug'
[ERR] Write-Information 'Some Information'
[ERR] Write-Warning 'Some Warning'
[ERR] Write-Error 'Some Error'
[ERR]
[ERR] : Some Error
[ERR] In ***\RedirectAllStreams.ps1:1 Char:1
[ERR] & {
[ERR] ~~~
[ERR] CategoryInfo : NotSpecified: (:) [Write-Error], WriteErrorException
[ERR] FullyQualifiedErrorId : Microsoft.PowerShell.Commands.WriteErrorException
[ERR]
Remarks: