Behind the PowerShell Pipeline logo

Behind the PowerShell Pipeline

Subscribe
Archives
May 14, 2024

Using Module Scope

One of the most perplexing topics in PowerShell, especially for beginner scripters is scope. Referencing items like variables and functions that may or may not be available can feel spinning a roulette wheel. You probably know about things like the global and script scopes. But there's another scope that you may not think about often: the *module* scope. There's a reason we use a manifest or the `Export-ModuleMember` cmdlet. It's all about scope. Let's take a look at how module scope works and how you can use it to your advantage. A PowerShell module typically consists of a set of functions and perhaps variables. When you import a module, PowerShell sets up a module scope. All commands from the module run in that scope. Where it gets tricky is that you'll see commands from the global scope. Here's a test module.

$fooVar = 100

Function Get-Secret {

    Param([string]$string)

    $n = $string.ToCharArray()

    for ($i = 0; $i -lt $fooVar; $i++) {

        $n = $n | Get-Random -Count $n.count

    }

    $n -join ''

}

Function Get-PSFoo {

    [cmdletBinding()]

    [alias('psf')]

    Param(

        [string]$Text

    )

    $space = ';',':','<','?','-','_' | Get-Random -count 1

    #replace all whitespace with a random character

    $Text = $Text -replace '\s',$space

    Write-Verbose "Running PSFoo on $Text using a value of $fooVar"

    Get-Secret -string $Text

}
I'll import this module.
Import-Module c:\demo\PSFoo-A.psm1
PowerShell loads all the modules into the global scope.
PS C:\> Get-Command -module PSFoo-A

CommandType     Name                                      Version    Source

-----------     ----                                      -------    ------

Function        Get-PSFoo                                     0.0     SFoo-A

Function        Get-Secret                                    0.0     PSFoo-A
But I don't see the variable `$fooVar` or the `psf` alias.
PS C:\>  Get-Alias psf

Get-Alias: This command cannot find a matching alias because an alias with the name 'psf' does not exist.

PS C:\> Get-Variable foovar

Get-Variable: Cannot find a variable with the name 'foovar'.
But the variable, which has a default value of 100 **is** available to the function.
PS C:\> Get-PSFoo "I am the walrus" -Verbose

VERBOSE: Running PSFoo on I:am:the:walrus using a value of 100

rl:s:hw:amaeIut
PowerShell found the variable in the module scope.
Get a premium subscription for full article and archive access

One of the most perplexing topics in PowerShell, especially for beginner scripters is scope. Referencing items like variables and functions that may or may not be available can feel spinning a roulette wheel. You probably know about things like the global and script scopes. But there's another scope that you may not think about often: the module scope. There's a reason we use a manifest or the Export-ModuleMember cmdlet. It's all about scope. Let's take a look at how module scope works and how you can use it to your advantage.

A PowerShell module typically consists of a set of functions and perhaps variables. When you import a module, PowerShell sets up a module scope. All commands from the module run in that scope. Where it gets tricky is that you'll see commands from the global scope. Here's a test module.

$fooVar = 100
Function Get-Secret {
    Param([string]$string)

    $n = $string.ToCharArray()
    for ($i = 0; $i -lt $fooVar; $i++) {
        $n = $n | Get-Random -Count $n.count
    }

    $n -join ''
}

Function Get-PSFoo {
    [cmdletBinding()]
    [alias('psf')]
    Param(
        [string]$Text
    )

    $space = ';',':','<','?','-','_' | Get-Random -count 1
    #replace all whitespace with a random character
    $Text = $Text -replace '\s',$space
    Write-Verbose "Running PSFoo on $Text using a value of $fooVar"
    Get-Secret -string $Text

}
Want to read the full issue?
GitHub Bluesky LinkedIn About Jeff
Powered by Buttondown, the easiest way to start and grow your newsletter.