В C++ и в C# есть очень хорошая концепция - автоматическая очистка ресурсов по выходу из блока. В умолчательном powershell-е очень не хватает конструкции, которая бы делала тоже самое.
Но умные люди уже все придумали за нас. Adam Weigert придумал функцию using, которая по синтаксису и семантике очень близка к C#-ному using-у.
http://weblogs.asp.net/adweigert/archive/2008/08/27/powershell-adding-the-using-statement.aspx
Но в исходном скрипте есть неточность, он не работает, если IDisposable был реализован явно, например, для класса XmlTextWriter. В данном скрипте эта неточность устранена.
function Try
{
param
(
[ScriptBlock]$Command = $(throw "The parameter -Command is required."),
[ScriptBlock]$Catch = { throw $_ },
[ScriptBlock]$Finally = {}
)
& {
$local:ErrorActionPreference = "SilentlyContinue"
trap
{
trap
{
& {
trap { throw $_ }
&$Finally
}
throw $_
}
$_ | & { &$Catch }
}
&$Command
}
& {
trap { throw $_ }
&$Finally
}
}
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) `
{
[System.IDisposable].GetMethod("Dispose").Invoke($inputObject, $null)
}
}
}