Nov 10, 2009

SharePoint 2010, PowerShell and Disposing

When you are already familiar with the SharePoint object model, you might know that SPSite and SPWeb allocate large amounts of memory and adequate memory management and disposing is essential. To make life easier the SharePoint team introduced two Cmdlets dealing with this in SharePoint 2010:
  • Start-SPAssignment
  • Stop-SPAssignment
By default, all Get commands dispose of these objects immediately after the pipeline finishes, but using SPAssignment, you can assign the list of objects to a variable and dispose of the objects after they are no longer needed. You can also ensure that the objects will remain as long as you need them, even throughout multiple iterations of commands
There are three levels of assignment:

No Assignment

The object is not assigned to a variable and is disposed after each iteration of the command.
Get-SPWeb http://server/sites/* |
     foreach { $_.Title | out-host } 

Simple Assignment

All objects are assigned to the global assignment store. This is done by using the Global parameter. When using this level, all objects are assigned to a global store and are disposed of when the Stop-SPAssignment command is called.

Start-SPAssignment -GlobalGlobal
$web = Get-SPWeb "http://server/sites/web"
$web.Title = "Greetings from PowerShell"
Stop-SPAssignment -Global
# $web will be disposed

Note: Use global assignment with caution! For example, if you use Start-SPAssignment – Global with and then call Get-SPSite –Limit ALL, every site collection object will be loaded, every site collection object will be loaded into memory. In a live server farm, this is likely to cause to cause serious performance issues

Advanced Assignment

Objects are assigned to named stores for disposal. You can dispose of objects by using the -Identity parameter with the Stop-SPAssignment command.

$siteScope = Start-SPAssignment
foreach($site in ($siteScope | Get-SPSite "http://server/*"))
   $webScope = Start-SPAssignment
   $web = $webScope | Get-SPWeb $site.RootWeb.Url
   $web.Title = "Greetings from PowerShell"
   Stop-SPAssignment $webScope
Stop-SPAssignment $siteScope

Regardless of the level used, all objects are disposed of when the PowerShell runspace is closed.