PowerShell 3.0 [ordered] and MongoDB

Recently, Shay Levy published a blog post about new features related to the Add-Member cmdlet in PowerShell 3.0. In it, one of the examples involved the use of [ordered]. The example, shown below is:

PS> $pso = New-Object -TypeName PSObject
PS> $pso | Add-Member ([ordered]@{One=1; Two=2; Three=3}) -PassThru

One Two Three
--- --- -----
  1   2     3

The take home of this example was simple; using the @{} operator by itself created a System.Hashtable object, and the order of those keys are not guaranteed. Therefore not guaranteeing the order of the properties of the PSObject. However we could use [ordered] to make it an “ordered hashtable” (Shay’s words).

So I spent some time looking for the MSDN documentation for OrderedHashtable. I never found it so I decided to fire up my Windows 8 VM and see what its type is.

PS C:\Users\zippy> [ordered]
Unable to find type [ordered]: make sure that the assembly containing this type is loaded.
At line:1 char:1
+ [ordered]
+ ~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (ordered:TypeName) [], RuntimeException
    + FullyQualifiedErrorId : TypeNotFound

Eventually, I figured out the problem is that [ordered] is not a type alias. I’m actually not exactly sure what it is, but I’m pretty sure its not a type alias. I did figure it it creates OrderedDictionaries.

    PS C:\Users\zippy> ([ordered]@{}).GetType()

    IsPublic IsSerial Name                                     BaseType
    -------- -------- ----                                     --------
    True     True     OrderedDictionary                        System.Object

So I said to myself, “ok that’s cool, but can I cast from an OrderedDoctionary to a MongoDB.Bson.BsonDocument with the MongoDB .NET driver?” I say this because a while back I submitted some patches to improve the driver’s user experience in PowerShell. My main goal was to be able to use the HashTable notation to define a BsonDocument like so:

[MongoDB.Bson.BsonDocument] $doc = @{
    "_id"= [MongoDB.Bson.ObjectId]::GenerateNewId();
    "FirstName"= "Justin";
    "LastName"= "Dearing";
    "PhoneNumbers"= [MongoDB.Bson.BsonDocument] @{
        'Home'= '718-555-1212';
        'Mobile'= '646-555-1212';
    };
};

The only problem with this notation is you cannot define the order of the keys. Luckily, I found that [Ordered] works flawlessly!

[MongoDB.Bson.BsonDocument] $doc = [ordered]@{
    "_id"= [MongoDB.Bson.ObjectId]::GenerateNewId();
    "FirstName"= "Justin";
    "LastName"= "Dearing";
    "PhoneNumbers"= [MongoDB.Bson.BsonDocument] [ordered]@{
        'Home'= '718-555-1212';
        'Mobile'= '646-555-1212';
    };
};

I’ve updated the gist repo for my post on using MongoDB with PowerShell.