access module variables from outside of the module
09:14 21 Nov 2025

I'm currently writing a helper module and despite my efforts, some private variable have to be accessed read/write from outside the module.

my first attempt was using Export-ModuleMember -Variable but exported variables can not be prefixed, nor accessed using modulename\... like functions and so, there is a great risk of name collision with variable outside the module.

so I tried to put all exported variables in a hashtable and export only the hashtable, but this make variable usage within the module a bit painful as now I have to prefix each usage by the hashtable name.

$myModule = @{ value = 0 }
    
function doCheck {
    write-host $myModule.value
    $script:myModule.value += 1
}

Export-ModuleMember -Function 'doCheck' -Variable 'myModule'
[CmdletBinding()]
    param ( )
    
begin   { 

    import-module -Name '.\myModule.psm1' -Force
}

process { }

end { 

    write-host $myModule.value

    $myModule.value += 1
    myModule\doCheck

    write-host $myModule.value
}

to get around this, I then did use the variables in a simple way in the module and export a PSCustomObject shadowing them. this simplify the variable usage within the module but I now have to create a getter and a setter for each mirrored variable.

$value = 0
    
function getValue { $value }
function setValue ( $value ) { $script:value = $value }
    
$myModule = [PSCustomObject] @{ }
$myModule | Add-Member -MemberType ScriptProperty -Name value `
    -Value $function:getValue -SecondValue $function:setValue
    
function doCheck {
    write-host $value
    $script:value += 1
}

Export-ModuleMember -Function 'doCheck' -Variable 'myModule'
[CmdletBinding()]
    param ( )
    
begin   { 

    import-module -Name '.\myModule.psm1' -Force    
}
process { }

end     { 

    write-host $myModule.value

    $myModule.value += 1
    myModule\doCheck

    write-host $myModule.value
}

as a third option, I tried to use classes but now I have to prefix variable access by [myModule]:: in the module and classes are a bit harder to write (for me at least) and to debug (for everyone as using module... won't reload the class.

class myModule {
    
    static $value = 0
    
    static [void] reset () {

        [myModule]::value = 0
    }

    static [void] doCheck () {

        write-host ([myModule]::value)
        [myModule]::value += 1
    }
}
using module .\myModule.psm1

[CmdletBinding()]
    param ( )

[myModule]::reset()
    
write-host ([myModule]::value)

[myModule]::value += 1
[myModule]::doCheck()

write-host ([myModule]::value)

I'm completely happy with none of these options. are they the only options I have to choose from or did I miss something?

context

Name                           Value
----                           -----
PSVersion                      5.1.19041.6456
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.19041.6456
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
powershell