| Mobile | RSS

Workaround to Catch Exceptions from Import-CliXml

February 14th, 2010 | No Comments | Posted in microsoft

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="1.1.0.1" xmlns="http://schemas.microsoft.com/powershell/2004/04">  <Obj RefId="0">    <TN RefId="0">      <T>Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData</T>      <T>Microsoft.PowerShell.Commands.Internal.Format.PacketInfoData</T>      <T>Microsoft.PowerShell.Commands.Internal.Format.FormatInfoData</T>      <T>System.Object</T>    </TN>    <ToString>Microsoft.PowerShell.Commands.Internal.Format.FormatEntryData</ToString>    <Props>      <S N="ClassId2e4f51ef21dd47e99d3c952918aff9cd">27c87ef9bbda4f709f6b4002fa4af63c</S>      <Obj N="formatEntryInfo" RefId="1">        <TN RefId="1">          <T>Microsoft.PowerShell.Commands.Internal.Format.RawTextFormatEntry</T>          <T>Microsoft.PowerShell.Commands.Internal.Format.FormatEntryInfo</T>          <T>Microsoft.PowerShell.Commands.Internal.Format.FormatInfoData</T>          <T>System.Object</T>        </TN>        <ToString>Microsoft.PowerShell.Commands.Internal.Format.RawTextFormatEntry</ToString>        <Props>          <S N="ClassId2e4f51ef21dd47e99d3c952918aff9cd">29ED81BA914544d4BC430F027EE053E9</S>          <S N="text">a</S>        </Props>      </Obj>      <B N="outOfBand">true</B>      <B N="writeErrorStream">false</B>    </Props>  </Obj></Objs>

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,
Microsoft.PowerShell.Commands.OutLineOutputCommand

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
   oft.PowerShell.Commands.OutLineOutputCommand

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

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

FormatObjectDeserializerDeserializeInvalidClassId,Microsoft.PowerShell.Commands.OutLineOut
putCommand

Cheers,
Francisco Gomez Gamino [MSFT]

Share and Enjoy:
  • Print
  • Digg
  • Sphinn
  • del.icio.us
  • Facebook
  • Mixx
  • Google Bookmarks
  • Blogplay
Leave a Reply 371 views, 1 so far today |
  • No Related Post

Leave a Reply


_MG_0209IMG_4187Sanjya-matsuri#7DSCF1962DSC_0628Photo-4.jpg_DSC468829-09-2011 23.31.21IMG_5807IMG_0840