Question

First and foremost I've done A LOT of googling and even went past the first page or 2 :) so feel free to direct me to the proper post if necessary.

I am trying to loop through a bunch of webs and subwebs and their document libraries. After doing each web, I want to dispose of it which I did but it is not working. I have tried the "Using" qualifier but for some reason it is giving the following error message:

"The 'using' keyword is not supported in this version of the language."

I have the code below as well as a output.

In this example i first entered a fake url, than entered a real one, than a fake again. As you can see, despite my attempts to call site.dispose the site variable persists. I do not trust setting the variable to null because I think it may just store it in memory without a pointer.

I am testing this in Poweshell ISE on a test box and I am afraid that when I finish this code (which will be WAYYYY heavier) it will have memory leaks and wasted resources all over the place! Please Help!!

Code:

[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")| out-null

do {
"before init $site"
$site = $null
"after null init $site"
$url = Read-Host 'Site Url is? '
Write-Host "User entered: $url"
try{
    $site = New-Object Microsoft.SharePoint.SPSite($url) 
        Write-Host "Name is: $site"
        $web=$site.openweb()
        Write-Host "web is: $web"

        foreach($lib in $web.Lists){

            if($lib.BaseType -eq [Microsoft.SharePoint.SPBaseType]::DocumentLibrary -and $lib.BaseTemplate -eq [Microsoft.SharePoint.SPListTemplateType]::DocumentLibrary){
                write-host $lib

                foreach($itm in $lib.Items){
                    write-host $itm.Url
                }
            }
        }

}
catch [system.exception]{
    "error with url"
}
finally {    
        if($site -ne $null){
            "not disposed: $site"
            $site.Dispose()
            "after dispose $site"
        }


        if($site -ne $null){
            "not disposed2: $site"
            try{
                $web.Dispose()
                "web disposed"
            }
            catch{
                "web null"
            }
            $site.Dispose()
            "after dispose2 $site"
        }
}
$again = Read-Host 'Again? (y or n) '
Write-Host "User entered: $again"
}
until ($again -eq "n")

Output:

before init 
after null init 
User entered: fakeurl
error with url
User entered: y
before init 
after null init 
User entered: http://test-site
Name is: SPSite Url=http://test-site
web is: Test Site For Dev
DocumentLogging
DocumentLogging/log.txt
Documents
Documents/test/Testfile.txt
not disposed: SPSite Url=http://test-site
after dispose SPSite Url=http://test-site
not disposed2: SPSite Url=http://test-site
web disposed
after dispose2 SPSite Url=http://test-site
User entered: y
before init SPSite Url=http://test-site
after null init 
User entered: fakeuri
error with url
User entered: n
Was it helpful?

Solution

I have recently had a similar requirement, and I came across some useful blog posts:

Powershell Using Statement, Multi-purpose Using Statement

One thing to note, is that you should call the function something other than 'Using' as the word using will throw an exception similar to that which you've already seen.

OTHER TIPS

Try a USING statement rather than trying to manually dispose. USING statements automatically dispose of the object that you instantiated the USING statement with. For example:

using ($web = $site.openweb())
{
    Write-Host "web is: $web"

    foreach($lib in $web.Lists){

        if($lib.BaseType -eq [Microsoft.SharePoint.SPBaseType]::DocumentLibrary -and $lib.BaseTemplate -eq [Microsoft.SharePoint.SPListTemplateType]::DocumentLibrary){
            write-host $lib

            foreach($itm in $lib.Items){
                write-host $itm.Url
            }
        }
    }
}

And basically put every disposable object in a USING statement like this.

Licensed under: CC-BY-SA with attribution
Not affiliated with sharepoint.stackexchange
scroll top