When working with the vCAC MgmtContext from within PowerShell or whatever other .NET language you will probably have noticed two properies on the context called ‘Entities’ and ‘Links’. Whenever you make a call like ‘$vm = m.VirtualMachines |? VirtualMachineName -eq “server1″‘ the DataContext is tracking the queries objects and thus adding them to the two aforementioned properties (that are actually collections). Furthermore when you call methods like ‘LoadProperty’, ‘AttachIfNeeded’, ‘Detach’ and ‘DetachLink’ and so forth you are again implicitly adding to and removing entries from these lists.
I order not to have too many resources consumed and the context tracking to many objects you might consider to clean up these from time to time – especially when you write a Cmdlet someone else is going to use. This can be easily acomplished by noting down the references objects before making your calls (‘Backup.VcacDataContext’) and later on restoring it (calling ‘Restore-VcacDataContext’) like in the following examples.
Saving the current context of tracked entities and links:
function Backup-VcacDataContext { [OutputType([hashtable])] Param ( [Parameter(Mandatory = $false, Position = 0)] [alias("mgmtContext")] [DynamicOps.ManagementModel.ManagementModelEntities] $m = $biz_dfch_PS_vCAC_Utilities.mgmtContext ) # Param $fReturn = $false; $OutputParameter = $null; if($m -is [DynamicOps.ManagementModel.ManagementModelEntities]) { $e = ''; $aE = New-Object System.Collections.ArrayList; foreach($e in $m.Entities) { $null = $aE.Add($e.Entity); }; $l = ''; $aL = New-Object System.Collections.ArrayList; foreach($l in $m.Links) { $null = $aL.Add($l); }; $ht = @{}; $ht.Links = $aL; $ht.Entities = $aE; $OutputParameter = $ht; Remove-Variable aE; Remove-Variable e; Remove-Variable aL; Remove-Variable l; } # if return $OutputParameter; } # function
And here how to restore the previous state:
function Restore-VcacDataContext { [OutputType([Boolean])] Param ( [Parameter(Mandatory = $true, Position = 0)] [hashtable] $Context , [Parameter(Mandatory = $false)] [alias("mgmtContext")] [DynamicOps.ManagementModel.ManagementModelEntities] $m = $biz_dfch_PS_vCAC_Utilities.mgmtContext ) # Param $fReturn = $false; $OutputParameter = $null; $fLinks = $false; $fEntities = $false; if($m -is [DynamicOps.ManagementModel.ManagementModelEntities]) { if($Context.ContainsKey('Entities')) { $e = ''; $aE = $Context.Entities; foreach($e in $m.Entities) { if(!$aE.Contains($e.Entity)) { $null = $m.Detach($e.Entity); } ; }; $aE.Clear(); Remove-Variable aE; Remove-Variable e; $fEntities = $true; } # if if($Context.ContainsKey('Links')) { $l = ''; $aL = $Context.Links; foreach($l in $m.Links) { if(!$aL.Contains($l)) { $null = $m.DetachLink($l.Source, $l.SourceProperty, $l.Target); } ; }; $aL.Clear(); Remove-Variable aL; Remove-Variable l; $fLinks = $true; } # if } # if if($fLinks -Or $fEntities) { $fReturn = $true; } return $fReturn; } # function
And if you later on want to attach an object to the context without reloading it you can do so like this:
PS > $m.Entities.Count; 0 PS > $m.AttachIfNeeded($m.GetEntitySetFromType($vm.GetType()), $vm); PS > $m.Entities.Count; 1 PS > $m.Entities.Identity; https://vcac52.sharedop.org/Repository/Data/ManagementModelEntities.svc/VirtualMachines(guid'a73aeb89-715b-4362-a0a3-ffae09bee0b1')
As you can see, ‘AttachIfNeeded’ actually check if the given object is already in the list ob tracked entities and adds it by constructing the appropriate link. If, for example, you pass in ‘tralala’ instead of ‘VirtualMachines’ you will end up getting ‘Identitly links with ‘tralala’ instead of the real segment/table.