function Test-Warning
{
[CmdletBinding()]
param ()
Write-Warning -Message "Test-Warning"
}
Test-Warning -WarningVariable SS -WarningAction "SilentlyContinue"
$SS
Expected is yellow warning with the WARNING label
WARNING: Test-Warning
Actual behavior is just the plain white text, as if we used plain Write-Host
Test-Warning
$PSVersionTable
Name Value
---- -----
PSVersion 7.0.0-rc.2
PSEdition Core
GitCommitId 7.0.0-rc.2
OS Microsoft Windows 10.0.18363
Platform Win32NT
PSCompatibleVersions {1.0, 2.0, 3.0, 4.0鈥
PSRemotingProtocolVersion 2.3
SerializationVersion 1.1.0.1
WSManStackVersion 3.0
Because if we repeat exactly the same code with Write-Error we will get the expected behavior,
which is both red and formatted text:
function Test-Error
{
[CmdletBinding()]
param ()
Write-Error -Message "cmdlet error"
}
Test-Error -ErrorVariable SS -ErrorAction "SilentlyContinue"
$SS
Write-Error: C:\Users\haxor\GitHub\whatever.ps1:84:1
Line |
84 | Test-Error -ErrorVariable SS -ErrorAction "SilentlyContinue"
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| cmdlet error
If you run Get-Member on SS variable the result is normal:
System.Management.Automation.ErrorRecord
System.Management.Automation.WarningRecord
I didn't test this with Write-Debug, Write-Verbose etc. ie. by using preference variables.
Also for example Write-Information is not affected by this since there is no INFO label and text is not colored anyway, but it would be great if informational messages get some formatting too.
Hi @metablaster
The coloring for all types of data records is done by the host (console host) so if you use the appropriate Write-* you get the appropriate coloring. You can see this by instantiating a WarningRecord
{master} PSCore (1:34) > [System.Management.Automation.WarningRecord]::new("Hello")
Hello
{master} PSCore (1:35) > Write-Warning ([System.Management.Automation.WarningRecord]::new("Hello")) ; write the warning record
WARNING: Hello
So the color & prefix does not generally depend on the _type_ of object, it depends on the _disposition_ of the object.
Except for error records that is :-) Because of the way the Console Host muxes and demuxes error and output records, things of type ErrorRecord are always printed in red even when displayed through stdout.
{master}PSCore (1:42) > $ev = [System.Management.Automation.ErrorRecord]::new([exception]::New("exception yo!"), "123", "NotImplemented", $null)
{master}PSCore (1:43) > $ev
NotImplemented: exception yo! #<-- this shows up in read.
{master}PSCore (1:44) >
Part of the reason things work the way they do is because the non-error information streams were originally simple strings, not instances of a particular type. Over the years, they turned into rich objects but the color-handling code hasn't changed (much).
So you can argue that not automagically coloring the various data record is wrong. But you can also argue that the behaviour for ErrorRecord is wrong. IMHO either behaviour is probably fine as is the current mixed behaviour.
@BrucePay Thank you for detailed explanation!
So basically we need to Write-Warning again to format the output.
I understand that the additional reason (to one you explained) why Write-Error is an exception is because if we would be required to Write-Error again just to get formatted output then the $Error automatic variable would contain duplicate data.
Since other streams do not have associated automatic variables this is not a problem.
Most helpful comment
Hi @metablaster
The coloring for all types of data records is done by the host (console host) so if you use the appropriate
Write-*you get the appropriate coloring. You can see this by instantiating a WarningRecordSo the color & prefix does not generally depend on the _type_ of object, it depends on the _disposition_ of the object.
Except for error records that is :-) Because of the way the Console Host muxes and demuxes error and output records, things of type
ErrorRecordare always printed in red even when displayed through stdout.Part of the reason things work the way they do is because the non-error information streams were originally simple strings, not instances of a particular type. Over the years, they turned into rich objects but the color-handling code hasn't changed (much).
So you can argue that not automagically coloring the various data record is wrong. But you can also argue that the behaviour for ErrorRecord is wrong. IMHO either behaviour is probably fine as is the current mixed behaviour.