{"id":2167,"date":"2012-01-03T09:19:43","date_gmt":"2012-01-03T09:19:43","guid":{"rendered":"https:\/\/poiseddevelopers.com\/reality-tech\/?p=2167"},"modified":"2024-04-26T12:09:42","modified_gmt":"2024-04-26T12:09:42","slug":"memory-management-in-powershell","status":"publish","type":"post","link":"https:\/\/poiseddevelopers.com\/reality-tech\/memory-management-in-powershell\/","title":{"rendered":"Memory Management in PowerShell"},"content":{"rendered":"<p>For limited work in SharePoint PowerShell, memory is freed when the PowerShell session is closed. If your script ignores memory management, everything usually just works fine. But what happens when you alter metadata for hundreds of thousands of documents within thousands of document libraries in one\u00a0<a href=\"https:\/\/reality-tech.com\/services\/powershell-scripting-automation\/\" target=\"_blank\" rel=\"noopener\" aria-label=\"PowerShell script - open in a new tab\" data-uw-rm-ext-link=\"\">PowerShell script<\/a>?<\/p>\n<p data-uw-rm-sr=\"\">Doing a simple $web.update() is not enough. In fact the implications are more significant than just memory. The SharePoint Object Model doesn\u2019t just hold onto the memory. It also keeps the Content DB transaction open on SQL Server. The result is a growing Transaction log, until the transaction is completed. The transaction log is not flushed until the memory is explicitly released. I know, because my script started consuming tens of GBs, until I ran out of Transaction Log space.<\/p>\n<div style=\"background-color: white; box-shadow: 0 0 10px whitesmoke; padding: 20px; width: 800px;\">\n<h4 style=\"color: black;\">Additional Read<\/h4>\n<p><a href=\"https:\/\/poiseddevelopers.com\/reality-tech\/send-email-from-powershell\/\" style=\"color:#1f6799\" target=\"_blank\" rel=\"noopener\">Send email from PowerShell<\/a><\/p>\n<\/div>\n<p>&nbsp;<\/p>\n<p>In addition to the normal $var.update() and $var.dispose(), you want to use Start-Assignment\/Stop-Assignment both locally through a named Assignment Object, and also Globally at the start\/end of the script. If you monitor SQL Transaction Logs, as well as memory utilization, the results are remarkable. Note that you will not be able to access any of the script objects (of course) after the script run, so consider adding these as the final touch after debugging.<\/p>\n<p>Here\u2019s what to add to your scripts to keep both memory management and SQL transaction management lean and mean:<\/p>\n<p>&nbsp;<\/p>\n<pre lang=\"php\"> # avoid problems, try to add in SharePoint snap-in, but don't complain if it's already loaded \r\nAdd-PSSnapin \"Microsoft.SharePoint.PowerShell\"-ErrorAction SilentlyContinue\r\n # this frees up all assignments if you end it at end of script \r\nStart-SPAssignment \u2013Global\r\n#sample function, that cleans up after itself\r\nfunction Reset-SPstuff ($WebUrl)\r\n{\r\n $FuncAssign =Start-SPAssignment #start of a named assignment object\r\n  #Here's how to allocate an object using an assignment:\r\n$web=$FuncAssign | Get-SPWeb$WebUrl\r\n #your function... \r\n$web.Dispose()\r\n$FuncAssign | Stop-SPAssignment    #release the named assignment object\r\n }\r\n\r\n # here's the main part of script, \r\n$site =... \r\n #for any variable you do use without a named assignment, try to dispose of it after use:\r\ntry {$site.Dispose();} catch {Write-Host\"can't dispose Site $($site.title) object\"}\r\n # very important to end the assignment of anything from within this script between Start\/Stop assignment: \r\nStop-SPAssignment \u2013Global<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>For limited work in SharePoint PowerShell, memory is freed when the PowerShell session is closed. If your script ignores memory management, everything usually just works fine. But what happens when you alter metadata for hundreds of thousands of documents within thousands of document libraries in one\u00a0PowerShell script? Doing a simple $web.update() is not enough. In [&hellip;]<\/p>\n","protected":false},"author":8,"featured_media":2174,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[26],"tags":[],"class_list":["post-2167","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-powershell"],"acf":[],"_links":{"self":[{"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/posts\/2167","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/users\/8"}],"replies":[{"embeddable":true,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/comments?post=2167"}],"version-history":[{"count":3,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/posts\/2167\/revisions"}],"predecessor-version":[{"id":3022,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/posts\/2167\/revisions\/3022"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/media\/2174"}],"wp:attachment":[{"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/media?parent=2167"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/categories?post=2167"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/poiseddevelopers.com\/reality-tech\/wp-json\/wp\/v2\/tags?post=2167"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}