Alex Rivera | Logout

Variable scoping in PowerShell

Asked 2012-02-17T09:14:01.993
71

A sad thing about PowerShell is that function and scriptblocks are dynamically scoped.

But there is another thing that surprised me is that variables behave as a copy-on-write within an inner scope.

$array=@("g")
function foo()
{
    $array += "h"
    Write-Host $array
}

& {
    $array +="s"
    Write-Host $array
}
foo

Write-Host $array

The output is:

g s
g h
g

Which makes dynamic scoping a little bit less painful. But how do I avoid the copy-on-write?

Edit
Report

1 Answer

18

Not just varibles. When this says "item" it means variables, functions, aliases, and psdrives. All of those have scope.

LONG DESCRIPTION  
    Windows PowerShell protects access to variables, aliases, functions, and
    Windows PowerShell drives (PSDrives) by limiting where they can be read and
    changed. By enforcing a few simple rules for scope, Windows PowerShell
    helps to ensure that you do not inadvertently change an item that should
    not be changed.

    The following are the basic rules of scope:

        - An item you include in a scope is visible in the scope in which it
          was created and in any child scope, unless you explicitly make it
          private. You can place variables, aliases, functions, or Windows
          PowerShell drives in one or more scopes.

        - An item that you created within a scope can be changed only in the
          scope in which it was created, unless you explicitly specify a
          different scope.

The copy on write issue you're seeing is because of the way Powershell handles arrays. Adding to that array actually destroys the original array and creates a new one. Since it was created in that scope, it is destroyed when the function or script block exits and the scope is disposed of.

You can explicitly scope varibles when you update them, or you can use [ref] objects to do your updates, or write your script so that you're updating a property of an object or a hash table key of an object or hash table in a parent scope. This does not create a new object in the local scope, it modifies the object in the parent scope.

answered 2012-02-17T12:22:44.320

Your Answer