Workaround to Catch Exceptions from Import-CliXml

  • Comments 2

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]

Leave a Comment
  • Please add 3 and 8 and type the answer here:
  • Post
  • I do not get your error on XP SP2 PoSH V2.

    10:52 PS> Import-Clixml .\a.xml


    10:53 PS>

    No exception is thrown.

    XML is identical.

  • What does F&O system mean?

    Also, on a side note, the error should still be getting sent to the error stream when the output is getting assigned to the variable. The only thing that the variable is "catching" is the pipeline output from the expression on the right-hand side of the assignment operator.

    I have a feeling that something else is going on here.

Page 1 of 1 (2 items)

Workaround to Catch Exceptions from Import-CliXml