46

This is a working example in C#:

using (var conn = new SqlConnection(connString))
{
    Console.WriteLine("InUsing");
}

I need the same in PowerShell (not working):

Using-Object ($conn = New-Object System.Data.SqlClient.SqlConnection($connString)) {
    Write-Warning -Message 'In Using';          
}

The term 'Using-Object' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify that the path is correct and try again.

It is working without a using block:

$conn = New-Object System.Data.SqlClient.SqlConnection($connString)

But then, I must remember to close the connection explicitly, even when exceptions are thrown.

5
  • you want to remove 'System.Data.SqlClient.'? Commented Feb 8, 2017 at 8:17
  • using statement make sures all the resource are released by calling Dispose of SqlConnection object.....So you can just call Dispose() folowed by Close() in powershell instead of Using Commented Feb 8, 2017 at 8:25
  • @Viru:I know that I can do Dispose()/Close() but I would like to using if possible. Not working means break Commented Feb 8, 2017 at 8:35
  • Related stackoverflow.com/q/24576990/993547 Commented Feb 8, 2017 at 8:37
  • Related issue in powershell repo PS implementation of the C# Using statement #9886 Commented Apr 19, 2024 at 15:52

1 Answer 1

68

Here is a solution from Using-Object: PowerShell version of C#’s “using” statement which works by calling .Dispose() in a finally block:

function Using-Object
{
    [CmdletBinding()]
    param (
        [Parameter(Mandatory = $true)]
        [AllowEmptyString()]
        [AllowEmptyCollection()]
        [AllowNull()]
        [Object]
        $InputObject,

        [Parameter(Mandatory = $true)]
        [scriptblock]
        $ScriptBlock
    )

    try
    {
        . $ScriptBlock
    }
    finally
    {
        if ($null -ne $InputObject -and $InputObject -is [System.IDisposable])
        {
            $InputObject.Dispose()
        }
    }
}

And here's how to use it:

Using-Object ($streamWriter = New-Object System.IO.StreamWriter("$pwd\newfile.txt")) {
    $streamWriter.WriteLine('Line written inside Using block.')
}
Sign up to request clarification or add additional context in comments.

5 Comments

Thank you. Could you explain me what you mean by $ErrorActionPreference ?
by default the $ErrorActionPreference is set to Continue, then in a try catch you will only trap crittical error's. (you actualy only trap errors that stop the current flow) you can override the error action with commandlets if you you use -erroraction. but I made a mistake here, you don't use the catch block so you don't need to adjust the error action preference. I 'll edit the answer!
I'd add a switch parameter to throw an exception if IDisposable isn't implemented (if not null). Otherwise, the program continues with the object not being released. I'd also add an output variable. As far as I can see, you won't be able to return anything.
You can simplify this a bit, the -is operator works just like in .NET. If you ask of a null value if it is of any type it will always return false. In other words, the -is operator does the null check as well.
Note that this technique will fail to cleanup in some circumstances if it is used in a scriptblock that accepts pipeline input.. As far as I understand that is a problem that cannot currently be overcome in PowerShell.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.