I recently wrote about on how to use the mgmtContext from vCAC so that you can use it outside the script/file repository of vCAC. With it you can easily access VirtualMachines, GlobalProperties without the need to use the ODATA REST interface of vCAC. However, when you first grab a virtual machine you might have wondered why you do not get all the related properties of it:
PS > $Vm = $m.VirtualMachines |? VirtualMachineName -eq 'DUB100124' PS > $Vm.VirtualMachineProperties PS > $Vm.VirtualMachineProperties.GetType() IsPublic IsSerial Name BaseType -------- -------- ---- -------- True True Collection`1 System.Object PS > $Vm.VirtualMachineProperties.Count 0
In C# you would use a “LINQ Expand” or in ODATA you would use a “ODATA exapnd” expression. This is obviously not possible in this case. However the mgmtContext provides you a property that you can use to dynamically load additional objects into a context:
PS > $m.LoadProperty OverloadDefinitions ------------------- System.Data.Services.Client.QueryOperationResponse LoadProperty(System.Object entity, string propertyName) System.Data.Services.Client.QueryOperationResponse LoadProperty[T](T source, System.Linq.Expressions.Expression[System.Func[T,System.Object]] property) System.Data.Services.Client.QueryOperationResponse LoadProperty(System.Object entity, string propertyName, uri nextLinkUri) System.Data.Services.Client.QueryOperationResponse LoadProperty(System.Object entity, string propertyName, System.Data.Services.Client.DataServiceQueryContinuation continuation) System.Data.Services.Client.QueryOperationResponse[T] LoadProperty[T](System.Object entity, string propertyName, System.Data.Services.Client.DataServiceQueryContinuation[T] continuation)
Here, we are interested in the first overload. With it we can load a property by name for its base entity. So, to load the “VirtualMachineProperties” we use the following command and will see that we now have access to 72 properties:
# System.Data.Services.Client.QueryOperationResponse # LoadProperty(System.Object entity, string propertyName) $null = $m.LoadProperty($vm, 'VirtualMachineProperties') PS > $vm.VirtualMachineProperties.Count 72
In order to load all properties at a time you can simply enumerate over all properies of the base entity and issue a “LoadProperty()” for each of them:
($vm|gm -Type Property).Name |% { $null = $m.LoadProperty($vm, $_); }
To further simplify (read-only) access to the machine properties you can add them to a hash table like this:
$hp = @{}; $vm.VirtualMachineProperties | Select-Object PropertyName, PropertyValue |% { $hp.Add($_.PropertyName, $_.PropertyValue); };
To access a property you only have to code like this:
$Location = $hp.'Vrm.DataCenter.Location';
The properties you loaded in this way certainly have a link to its base entity, so when changing them you only have to call “UpdateObject()” and then “SaveChanges()”. Quite simple, isn’t it …