Take the 2-minute tour ×
SharePoint Stack Exchange is a question and answer site for SharePoint enthusiasts. It's 100% free, no registration required.

When I run this little piece of powershell code:

$w = Get-SPWeb http://localhost
$l = $w.List["some list"]

I get Unexpected error message to my Sharepoint ULS log

Detected use of SPRequest for previously closed SPWeb object. .../long message here/...

I don't think this should happen. Is this a bug or do I do something wrong?


On the other hand, to make it even more weird. When I wil continue in code above and write this:

$w.Dispose()
$w.Title # or any other property

I don't get that error message. I would expect I will get it. What is wrong with disposing in powershell?

share|improve this question
add comment

2 Answers 2

up vote 10 down vote accepted

Use of objects, such as SPWeb or SPSite, in PowerShell requires a proper memory management. Get commands dispose of these objects immediately after the pipeline finishes, but by using SPAssignment, you can assign the list of objects to a variable and dispose of the objects after they are no longer needed. Here is an example of usage of SPAssignment object, you can assign SPWeb to a variable and dispose of when they are needed to free up memory. See below:

$spAssigment = Start-SPAssignment
$spWeb = Get-SPWeb http://localhost -AssignmentCollection $spAssignment
$l = $spWeb.List["some list"]     
$spWeb.Title # or any other property
Stop-SPAssignment $spAssignment
share|improve this answer
    
This is it! Now it work exactly how I would expect. In both cases. Thanks for clarification. –  jumbo Jun 21 '12 at 18:48
    
I would like to link to the article I found later, after I read this answer, and which clarifies the use of Start/Stop-Assignment cmdlet and go deep of whats going there when you use it when you didn't. codefornuts.com/2010/12/dissecting-sharepoint-powershell.html –  jumbo Jun 21 '12 at 19:00
add comment

I'm guessing that you are using a regular PowerShell session, probably with the SharePoint snapp-in loaded. And not the 'SharePoint Management Shell'.

With a regular powershell session each command is executed with-in its own thread. And disposable objects, like SPWeb, are automatically disposed on the end of a thread. Thus what could happen is that the Garbage Collector is quick and disposes your SPWeb before you execute the next statement.

Disposing does not clear or destroy an object, it just gives an object a chance to close connections, clean up things the GC won't clean up, etc. Most properties will still be available (like Title) but actions that require a database connection, like $w.list["listName"], will error out.

SharePoint Management Shell

The SP Management Shell is just a regular powershell session with this tiny bit of script executed when it loads:

$ver = $host | select version
if ($ver.Version.Major -gt 1)  {$Host.Runspace.ThreadOptions = “ReuseThread”}
Add-PsSnapin Microsoft.SharePoint.PowerShell
Set-location $home

Notice the setting on ThreadOptions. With the SP Management Shell you get a sligtly different powershell (in an ugly console). One that reuses the same thread for succesive commands, and thus a PowerShell that won't dispose objects 'behind your back'.

See this blog for more information.

Load C:\Program Files\Common Files\Microsoft Shared\Web Server Extensions\14\CONFIG\POWERSHELL\Registration\\sharepoint.ps1 , instead of just adding the SnapIn

Tip Use the PowerShell ISE, which has ThreadReuse on as default. And it is a nice tool for writing and testing scripts.

share|improve this answer
    
This looks promising! I'll give it a try. (your guess in the begining of your answer is right ;) ) –  jumbo Jun 21 '12 at 15:31
    
Unfortunately the Sharepoint Management Shell behaves exactly the same :( Did you tried it? Did it work for you in Shp Mngmt Shell? –  jumbo Jun 21 '12 at 15:44
    
As I already wrote, this is not the solution for my problem, but thanks for mentioning the config script, it is important to set ReuseThread option when I try to use Start-Assignment cmdlet. –  jumbo Jun 21 '12 at 18:55
1  
I did not try this, and I didn't know (remember?) about SPAssingment. It is stated on MSDN: "It is important to note that every site collection returned by the Get-SPWeb cmdlet is automatically disposed of at the end of the pipeline. To store the results of Get-SPWeb in a local variable, the Start-SPAssignment and Stop-SPAssignment cmdlets must be used to avoid memory leaks." on technet.microsoft.com/en-us/library/ff607807.aspx –  Dribbel Jun 22 '12 at 6:02
    
Wow, I didn't know that this is on MSDN. I should have look there first. Thanks. –  jumbo Jun 22 '12 at 6:08
show 2 more comments

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.