The output-formatting system doesn't deserialize CLIXML output produced by calling the CLI with -OutputFormat xml when printing to the console
See original GitHub issueWhen you call the PowerShell CLI with -OutputFormat xml
/ -of xml
explicitly, the formatting system renders the raw CLIXML output instead of deserializing the CLIXML first and then applying the output formatting to the deserialized objects.
(Note that -OutputFormat xml
is used implicitly when you pass a script block to the -Command
/ -c
parameter, but the problem doesn’t surface then, possibly due to taking a different code path behind the scenes, given that the script block is translated into a Base64-encoded -EncodedCommand
argument.)
Note that only the output formatting system is affected and only when printing to the console; if you capture or redirect the output, deserialization happens normally. Therefore, the simplest workaround is to enclose the CLI call in (...)
.
Steps to reproduce
# Note: To work around the bug, enclose the call in (...)
pwsh -OutputFormat xml -noprofile -c 'Get-Item $PROFILE'
Expected behavior
The usual, formatted output, e.g.:
Directory: /Users/jdoe/.config/powershell
UnixMode User Group LastWriteTime Size Name
-------- ---- ----- ------------- ---- ----
-rw-r--r-- jdoe staff 3/19/2021 09:20 909 Microsoft.PowerShell_profile.ps1
Actual behavior
The raw CLIXML output prints.
#< CLIXML
<Objs Version="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04"><Obj S="Output" RefId="0"><TN RefId="0"><T>System.IO.FileInfo</T><T>System.IO.FileSystemInfo</T><T>System.MarshalByRefObject</T><T>System.Object</T></TN><ToString>/Users/mklement/.config/powershell/Microsoft.PowerShell_profile.ps1</ToString><Props><I64 N="Length">909</I64><S N="DirectoryName">/Users/mklement/.config/powershell</S><Obj N="Directory" RefId="1"><TN RefId="1"><T>System.IO.DirectoryInfo</T><T>System.IO.FileSystemInfo</T><T>System.MarshalByRefObject</T><T>System.Object</T></TN><ToString>/Users/mklement/.config/powershell</ToString><Props><S N="Parent">/Users/mklement/.config</S><S N="Root">/</S><S N="FullName">/Users/mklement/.config/powershell</S><S N="Extension"></S><S N="Name">powershell</S><B N="Exists">true</B><DT N="CreationTime">2017-02-22T18:23:24-05:00</DT><DT N="CreationTimeUtc">2017-02-22T23:23:24Z</DT><DT N="LastAccessTime">2021-04-18T14:44:45.9275675-04:00</DT><DT N="LastAccessTimeUtc">2021-04-18T18:44:45.9275675Z</DT><DT N="LastWriteTime">2021-03-29T15:28:09.1334955-04:00</DT><DT N="LastWriteTimeUtc">2021-03-29T19:28:09.1334955Z</DT><S N="Attributes">Directory</S></Props><MS><Obj N="UnixMode" RefId="2"><S></S></Obj><Ref N="User" RefId="2" /><Ref N="Group" RefId="2" /><Nil N="Size" /><S N="Mode">d----</S><S N="ModeWithoutHardLink">d----</S><S N="BaseName">powershell</S><Nil N="LinkType" /><S N="NameString">powershell</S><S N="LengthString"></S><S N="LastWriteTimeString"> 3/29/2021 3:28 PM</S></MS></Obj><B N="IsReadOnly">false</B><S N="FullName">/Users/mklement/.config/powershell/Microsoft.PowerShell_profile.ps1</S><S N="Extension">.ps1</S><S N="Name">Microsoft.PowerShell_profile.ps1</S><B N="Exists">true</B><DT N="CreationTime">2019-04-16T15:50:42.3817263-04:00</DT><DT N="CreationTimeUtc">2019-04-16T19:50:42.3817263Z</DT><DT N="LastAccessTime">2021-03-19T09:20:51.3007395-04:00</DT><DT N="LastAccessTimeUtc">2021-03-19T13:20:51.3007395Z</DT><DT N="LastWriteTime">2021-03-19T09:20:02.3063572-04:00</DT><DT N="LastWriteTimeUtc">2021-03-19T13:20:02.3063572Z</DT><Obj N="Attributes" RefId="3"><TN RefId="2"><T>System.IO.FileAttributes</T><T>System.Enum</T><T>System.ValueType</T><T>System.Object</T></TN><ToString>Normal</ToString><I32>128</I32></Obj></Props><MS><S N="PSPath">Microsoft.PowerShell.Core\FileSystem::/Users/mklement/.config/powershell/Microsoft.PowerShell_profile.ps1</S><S N="PSParentPath">Microsoft.PowerShell.Core\FileSystem::/Users/mklement/.config/powershell</S><S N="PSChildName">Microsoft.PowerShell_profile.ps1</S><Obj N="UnixStat" RefId="4"><TN RefId="3"><T>System.Management.Automation.Platform+Unix+CommonStat</T><T>System.Object</T></TN><ToString>System.Management.Automation.Platform+Unix+CommonStat</ToString><Props><I64 N="Inode">12902233604</I64><I32 N="Mode">33188</I32><I32 N="UserId">501</I32><I32 N="GroupId">20</I32><I32 N="HardlinkCount">1</I32><I64 N="Size">909</I64><DT N="AccessTime">2021-03-19T09:20:51-04:00</DT><DT N="ModifiedTime">2021-03-19T09:20:02-04:00</DT><DT N="StatusChangeTime">2021-03-19T09:20:02-04:00</DT><I64 N="BlockSize">4096</I64><I32 N="DeviceId">16777223</I32><I32 N="NumberOfBlocks">8</I32><Obj N="ItemType" RefId="5"><TN RefId="4"><T>System.Management.Automation.Platform+Unix+ItemType</T><T>System.Enum</T><T>System.ValueType</T><T>System.Object</T></TN><ToString>File</ToString><I32>1</I32></Obj><B N="IsSetUid">false</B><B N="IsSetGid">false</B><B N="IsSticky">false</B></Props></Obj><Obj N="PSDrive" RefId="6"><TN RefId="5"><T>System.Management.Automation.PSDriveInfo</T><T>System.Object</T></TN><ToString>/</ToString><Props><S N="CurrentLocation">Users/mklement/Projects/OSS/Native</S><S N="Name">/</S><Obj N="Provider" RefId="7"><TN RefId="6"><T>System.Management.Automation.ProviderInfo</T><T>System.Object</T></TN><ToString>Microsoft.PowerShell.Core\FileSystem</ToString><Props><S N="ImplementingType">Microsoft.PowerShell.Commands.FileSystemProvider</S><S N="HelpFile">System.Management.Automation.dll-Help.xml</S><S N="Name">FileSystem</S><S N="PSSnapIn">Microsoft.PowerShell.Core</S><S N="ModuleName">Microsoft.PowerShell.Core</S><Nil N="Module" /><S N="Description"></S><S N="Capabilities">Filter, ShouldProcess, Credentials</S><S N="Home">/Users/mklement</S><Obj N="Drives" RefId="8"><TN RefId="7"><T>System.Collections.ObjectModel.Collection`1[[System.Management.Automation.PSDriveInfo, System.Management.Automation, Version=7.2.0.5, Culture=neutral, PublicKeyToken=31bf3856ad364e35]]</T><T>System.Object</T></TN><LST><Ref RefId="6" /><S>Temp</S></LST></Obj><B N="VolumeSeparatedByColon">false</B><C N="ItemSeparator">47</C><C N="AltItemSeparator">92</C></Props></Obj><S N="Root">/</S><S N="Description">/</S><Nil N="MaximumSize" /><Obj N="Credential" RefId="9"><TN RefId="8"><T>System.Management.Automation.PSCredential</T><T>System.Object</T></TN><ToString>System.Management.Automation.PSCredential</ToString><Props><Nil N="UserName" /><Nil N="Password" /></Props></Obj><Nil N="DisplayRoot" /><B N="VolumeSeparatedByColon">false</B></Props><MS><I64 N="Used">913685630976</I64><I64 N="Free">207432568832</I64></MS></Obj><Ref N="PSProvider" RefId="7" /><B N="PSIsContainer">false</B><S N="UnixMode">-rw-r--r--</S><S N="User">mklement</S><S N="Group">staff</S><I64 N="Size">909</I64><S N="Mode">-----</S><S N="ModeWithoutHardLink">-----</S><Obj N="VersionInfo" RefId="10"><TN RefId="9"><T>System.Diagnostics.FileVersionInfo</T><T>System.Object</T></TN><ToString>File: /Users/mklement/.config/powershell/Microsoft.PowerShell_profile.ps1_x000A_InternalName: _x000A_OriginalFilename: _x000A_FileVersion: _x000A_FileDescription: _x000A_Product: _x000A_ProductVersion: _x000A_Debug: False_x000A_Patched: False_x000A_PreRelease: False_x000A_PrivateBuild: False_x000A_SpecialBuild: False_x000A_Language: _x000A_</ToString><Props><Nil N="Comments" /><Nil N="CompanyName" /><I32 N="FileBuildPart">0</I32><Nil N="FileDescription" /><I32 N="FileMajorPart">0</I32><I32 N="FileMinorPart">0</I32><S N="FileName">/Users/mklement/.config/powershell/Microsoft.PowerShell_profile.ps1</S><I32 N="FilePrivatePart">0</I32><Nil N="FileVersion" /><Nil N="InternalName" /><B N="IsDebug">false</B><B N="IsPatched">false</B><B N="IsPrivateBuild">false</B><B N="IsPreRelease">false</B><B N="IsSpecialBuild">false</B><Nil N="Language" /><Nil N="LegalCopyright" /><Nil N="LegalTrademarks" /><Nil N="OriginalFilename" /><Nil N="PrivateBuild" /><I32 N="ProductBuildPart">0</I32><I32 N="ProductMajorPart">0</I32><I32 N="ProductMinorPart">0</I32><Nil N="ProductName" /><I32 N="ProductPrivatePart">0</I32><Nil N="ProductVersion" /><Nil N="SpecialBuild" /></Props><MS><Version N="FileVersionRaw">0.0.0.0</Version><Version N="ProductVersionRaw">0.0.0.0</Version></MS></Obj><S N="BaseName">Microsoft.PowerShell_profile</S><Nil N="LinkType" /><S N="NameString">Microsoft.PowerShell_profile.ps1</S><S N="LengthString">909</S><S N="LastWriteTimeString"> 3/19/2021 9:20 AM</S></MS></Obj></Objs>
Environment data
PowerShell Core 7.2.0-preview.5
Issue Analytics
- State:
- Created 2 years ago
- Comments:6 (3 by maintainers)
Thanks for the clarification, @jborean93.
It seems that the problem boils down to this:
With a script-block-based invocation that implies CLIXML output, PowerShell already knows that direct-to-host output of the raw CLIXML isn’t appropriate, and that the raw output needs to be deserialized first and then sent to the formatting system:
If a script block isn’t involved and CLIXML output is explicitly requested via
-OutputFormat xml
, PowerShell does not apply the necessary logic:Also note that redundantly adding
-OutputFormat xml
to the script-block invocation scenario also results in broken output:@237dmitry issue is that if you don’t capture any output when calling a native command then the output goes directly to the console without it being touched at all by PowerShell.
If PowerShell isn’t capturing the output then the CLIXML is written directly to the console.