Workaround to Catch Exceptions from Import-CliXml

PowerShell Team

Recently, I came across an interesting bug in PowerShell. Let’s create a repro.

First, we create a string “a” and generate an xml based representation of it using the Export-Clixml cmdlet. Since we need to have the class id, we pipe the string to format-table as shown in the example below.

PS> "a" | format-table -auto | Export-Clixml a.xml

Here is the content of the xml file.

<Objs Version="" xmlns="">
  <Obj RefId="0">
    <TN RefId="0">
      <S N="ClassId2e4f51ef21dd47e99d3c952918aff9cd">27c87ef9bbda4f709f6b4002fa4af63c</S>
      <Obj N="formatEntryInfo" RefId="1">
        <TN RefId="1">
          <S N="ClassId2e4f51ef21dd47e99d3c952918aff9cd">29ED81BA914544d4BC430F027EE053E9</S>
          <S N="text">a</S>
      <B N="outOfBand">true</B>
      <B N="writeErrorStream">false</B>

Then, we remove the class id (in blue) and save the xml file. Next, we recreate an object using the import-cliXml cmdlet and we assign it to a variable, i.e. $a. We should get an exception because the class id is missing but, we do not.

PS> $a = Import-Clixml .\a.xml

On the other hand, if we execute the same command without assigning it to a variable, the exception is thrown.

PS> Import-Clixml .\a.xml 

Unknown class Id .
    + CategoryInfo          : InvalidData: (Microsoft.Power…FormatEntryData:PS

Object) [out-lineoutput], PSArgumentException

    + FullyQualifiedErrorId : FormatObjectDeserializerDeserializeInvalidClassId,


Why is this happening?

In the first instance, the object gets assigned to the variable and it never goes to the F&O system. Thus the terminating error is never generated.

The workaround

The fix is fairly simple, Out-String will send the object to the host through the F&O system.

PS> $a = Import-Clixml .\a.xml | Out-String

out-lineoutput : Unknown class Id .
    + CategoryInfo          : InvalidData: (Microsoft.Power…FormatEntryData:PSObject

   ) [out-lineoutput], PSArgumentException

    + FullyQualifiedErrorId : FormatObjectDeserializerDeserializeInvalidClassId,Micros


To make sure our script ends nicely, we catch the terminating error.

$e = $null
    Import-Clixml .\a.xml | Out-String             
    $e = $_            
If($e –ne $null) { $e.FullyQualifiedErrorId }


Francisco Gomez Gamino [MSFT]


Discussion is closed.

Feedback usabilla icon