just like c# when you open a new spweb or spsite object you need to dispose of it once complete! powershell doesnt have a using statment but some has done it for you ;)
function Using {
param (
[System.IDisposable] $inputObject = $(throw "The parameter -inputObject is required."),
[ScriptBlock] $scriptBlock = $(throw "The parameter -scriptBlock is required.")
)
Try {
&$scriptBlock
} -Finally {
if ($inputObject -ne $null) {
if ($inputObject.psbase -eq $null) {
$inputObject.Dispose()
} else {
$inputObject.psbase.Dispose()
}
}
}
}
# Short example ...
Using ($user = $sr.GetDirectoryEntry()) {
$user.displayName = $displayName
$user.SetInfo()
}
http://weblogs.asp.net/adweigert/archive/2008/08/27/powershell-adding-the-using-statement.aspx
there is no way that i know of to know within the pipeline to which spweb object is currently open that your not using or did use and will be using later! Best to open the object, do your stuff and then finally dispose! try catch finally! or use the above to encapsulate your code within that example using statment!
as for the error, your trying to close the spweb object but somthing else is currently using it and so it throws the error! so having it in either a finally statment or the code above would do it when the code fully completes within the pipeline!
You need todo an iisreset and it should get rid of the spweb that is causing the issue and then you can try again! ;)
another example:
https://stackoverflow.com/questions/15903411/proper-disposal-of-powershell-pipeline-objects