Object Serialization Directives

Object Serialization Directives

  • Comments 4

When PowerShell serializes an object (e.g. when using Export-CLIXML) , we first look for serialization directives in the extended type system and then fall back to some default heuristics. We have not documented those serialization directives yet but Hitesh Raigandhi took the time to provide a few examples below.

A number of people have asked why we don't just use the object serialization provided by the .NET object itself. There are a couple reasons for that but the primary one is that we have a management mindset. That means that we want to serialize these objects into a form that can be used 30 years from now. Sound crazy? It isn't. We can still talk to the earliest SNMP devices because SNMP MIBs are hierarchical collections of a fixed set of simple types. Strings, Ints, Booleans, Floats, etc – those puppies haven't change in a long time and probably won't for quite a while more J. Most developers don't have this mindset when they produce their XML serialization. You can probably use the same version of the software to serialize and deserialize the objects and if you are lucky, the next version might support the previous version. That is, as long as the PMs, Devs and testers all agree that it is worth the investment to do this and are willing to cut other features to ensure that this. So the real answer is, "maybe it will and maybe it won't". That just isn't good enough for management scenarios. As such, we use essentially the same model as every other management protocol, we render into a hierarchy of a fixed set of types. That said, we allow you to control that hierarchy using the object serialization directives below.

Enjoy!

Jeffrey Snover [MSFT]
Windows Management Partner Architect
Visit the Windows PowerShell Team blog at:
http://blogs.msdn.com/PowerShell
Visit the Windows PowerShell ScriptCenter at:
http://www.microsoft.com/technet/scriptcenter/hubs/msh.mspx

#example 1: Serialize as string
@"
<Types>
    <Type>
        <Name>System.Management.Automation.Test.MyBase</Name>
        <Members>
            <MemberSet>
                <Name>PSStandardMembers</Name>
                <Members>
                    <NoteProperty>
                        <Name>SerializationMethod</Name>
                        <Value>
                            String
                        </Value>
                    </NoteProperty>
                </Members>
            </MemberSet>
        </Members>
    </Type>
</Types>
"
;


#Example 2: Serialize as string and supply to string method
@"
<Types>
    <Type>
        <Name>System.Management.Automation.Test.MyBase</Name>
        <Members>
            <MemberSet>
                <Name>PSStandardMembers</Name>
                <Members>
                    <NoteProperty>
                        <Name>SerializationMethod</Name>
                        <Value>
                            String
                        </Value>
                    </NoteProperty>
                    <ScriptProperty>
                    <!--
             In this case StringSerializationSource is ScriptProperty, but it could be another property
             like an alias or a note.
                     -->
                        <Name>StringSerializationSource</Name>
                        <GetScriptBlock>$this.p1</GetScriptBlock>
                    </ScriptProperty>
                </Members>
            </MemberSet>
        </Members>
    </Type>
</Types>
"
;

#Example 3: Supply depth of serialization

@"
<Types>
    <Type>
        <Name>System.Management.Automation.Test.MyContainer</Name>
        <Members>
            <MemberSet>
                <Name>PSStandardMembers</Name>
                <Members>
                    <NoteProperty>
                        <Name>SerializationDepth</Name>
                        <Value>
                            1
                        </Value>
                    </NoteProperty>
                </Members>
            </MemberSet>
        </Members>
    </Type>
</Types>"
;

#Example 4: Serialize specific properties:
<Types>
    <Type>
        <Name>System.Management.Automation.Test.MyBase</Name>
        <Members>
            <MemberSet>
                <Name>PSStandardMembers</Name>
                <Members>
                    <NoteProperty>
                        <Name>SerializationMethod</Name>
                        <Value>
                            SpecificProperties
                        </Value>
                    </NoteProperty>
                    <PropertySet>
                        <Name>PropertySerializationSet</Name>
                        <ReferencedProperties>
                            <Name>P1</Name>
                        </ReferencedProperties>
                    <!—
For object of type MyBase only property P1 is serialized.
                     -->

                    </PropertySet>
                </Members>
            </MemberSet>
        </Members>
    </Type>
    <Type>
        <Name>System.Management.Automation.Test.MyDerived1</Name>
        <Members>
            <MemberSet>
                <Name>PSStandardMembers</Name>
                <Members>
                    <NoteProperty>
                        <Name>SerializationMethod</Name>
                        <Value>
                            SpecificProperties
                        </Value>
                    </NoteProperty>
                    <PropertySet>
                        <Name>PropertySerializationSet</Name>
                        <ReferencedProperties>
                            <Name>P3</Name>
                        </ReferencedProperties>
                    <!—
For object of type MyDerived1 (derived from MyBase) property P1 and P3 is serialized.
                     -->
                    </PropertySet>
                </Members>
            </MemberSet>
        </Members>
    </Type>
    <Type>
        <Name>System.Management.Automation.Test.MyDerived2</Name>
        <Members>
            <MemberSet>
                <Name>PSStandardMembers</Name>
                <Members>
                    <NoteProperty>
                        <Name>SerializationMethod</Name>
                        <Value>
                            SpecificProperties
                        </Value>
                    </NoteProperty>
                    <PropertySet>
                        <Name>PropertySerializationSet</Name>
                        <ReferencedProperties>
                            <Name>P5</Name>
                        </ReferencedProperties>
                    <!—
For object of type MyDerived2 (derived from MyDerived1) property P1, P3 and P5 is serialized.
                     -->
                    </PropertySet>
                </Members>
            </MemberSet>
        </Members>
    </Type>
</Types>
"
;

#Example 5: Serialize specific properties. Block inheritance of serialization property set in derived class.
<Types>
    <Type>
        <Name>System.Management.Automation.Test.MyBase</Name>
        <Members>
            <MemberSet>
                <Name>PSStandardMembers</Name>
                <Members>
                    <NoteProperty>
                        <Name>SerializationMethod</Name>
                        <Value>
                            SpecificProperties
                        </Value>
                    </NoteProperty>
                    <PropertySet>
                        <Name>PropertySerializationSet</Name>
                        <ReferencedProperties>
                            <Name>P1</Name>
                        </ReferencedProperties>
                    <!—
For object of type MyBase P1 serialized.
                     -->
                    </PropertySet>
                </Members>
            </MemberSet>
        </Members>
    </Type>
    <Type>
        <Name>System.Management.Automation.Test.MyDerived1</Name>
        <Members>
            <MemberSet>
                <Name>PSStandardMembers</Name>
                <Members>
                    <NoteProperty>
                        <Name>SerializationMethod</Name>
                        <Value>
                            SpecificProperties
                        </Value>
                    </NoteProperty>
                    <NoteProperty>
                        <Name>InheritPropertySerializationSet</Name>
                        <Value>
                            false
                        </Value>
                    </NoteProperty>
                    <PropertySet>
                        <Name>PropertySerializationSet</Name>
                        <ReferencedProperties>
                            <Name>P3</Name>
                        </ReferencedProperties>
                    <!—
For object of type MyDerived1 (derived from MyBase) P3 is serialized. Property P1 is not serialized as inheritance is blocked.
                     -->
                    </PropertySet>
                </Members>
            </MemberSet>
        </Members>
    </Type>
    <Type>
        <Name>System.Management.Automation.Test.MyDerived2</Name>
        <Members>
            <MemberSet>
                <Name>PSStandardMembers</Name>
                <Members>
                    <NoteProperty>
                        <Name>SerializationMethod</Name>
                        <Value>
                            SpecificProperties
                        </Value>
                    </NoteProperty>
                    <PropertySet>
                        <Name>PropertySerializationSet</Name>
                        <ReferencedProperties>
                            <Name>P5</Name>
                        </ReferencedProperties>
                    <!—
For object of type MyDerived2 (derived from MyDerived1) P3 and P5 is serialized.
                     -->
                    </PropertySet>
                </Members>
            </MemberSet>
        </Members>
    </Type>
</Type

Leave a Comment
  • Please add 3 and 3 and type the answer here:
  • Post
  • A million, zillion thanks. Realizing that it's difficult to document all these complexities - especially stuff like this which won't be of immediate use to *every* administrator - these under-the-hood blog peaks are extraordinarily useful.

  • Does the String serialization directive simply call the object's native ToString method? Meaning, if the object hasn't overridden the ToString() method provided in System.Object, you just get the object's type name? I could see where this would be useful for objects that have a fairly rich built-in ToString() method that provides better-formatted data than just grabbing the property values would provide.

  • plus if you used the default dotnet serialization.. 1)it would only serialize the userlying base system, not the extended type systems info, as that is more a wrapper, as far as dotnet is concerned. and 2) it couldn't deserialize an object for which there is no currently type in memory for..

    So i understand why you do it the way you do as well (at least i think i do ;)

  • Hi,  could you perhaps point me out to some more documentation on this topic? More specifically on

    <NoteProperty>

    <Name>SerializationMethod</Name>

    <Value>String</Value>

    </NoteProperty>

    <ScriptProperty>

    <Name>StringSerializationSource</Name>

    <GetScriptBlock>$this.p1</GetScriptBlock>

    </ScriptProperty>

    I'm using this as a way to work around the non-CLS compliant type error when using SharePoint 2007's SPContentDatabase object. It serializes OK using the standard ToString():

          "SPContentDatabase Name=WSS_Content Parent=SPDatabaseServiceInstance Name=INST01"

    but does not seem to take StringSerializationSource into account, with which I'm trying to get the properties I want, e.g. $this.DisplayName.

    I've made a custom sharepoint.types.ps1xml in which I define the properties I want in my report for all objects. Using this method, I could just pipe any object to ConvertTo-Xml, and get a decent xml report, without writing any code, and very portable too.

    Thanks for any suggestions,

    Bert.

Page 1 of 1 (4 items)