Search code examples
powershellusing-directives

What is the scope of using namespace in PowerShell?


When specifying using namespace within PowerShell module or script file, is there a scope associated with the directive into which namespace symbols are being introduced?

Or are namespace symbols introduced into global session state avoiding the PS scope modifiers?

using namespace System.Management.Automation.Runspaces

For example if we specify using namespace inside module it would be great if this applies to module scope only.

Likewise if we specify using namespace inside script file it would be great if this applies to that script only unless dot sourced.

I didn't test any of this and was not able to find documentation regarding this question.


Solution

  • A using namespace statement follows PowerShell's usual dynamic scoping rules[1]:

    • It takes effect in the scope in which it is placed and all descendant scopes.

      • If a script file (*.ps1) is dot-sourced (e.g. . ./file.ps1), the statement takes effect in the caller's scope.
    • Since modules have their own scope domains ("session states") that are connected only to the global scope, a using namespace statement in a module doesn't affect any module-external callers.

      • Caveat: As of PowerShell 7.1, you cannot use name-only type literals that rely on using namespace statements (e.g., [Command] for [System.Management.Automation.Runspaces.Command]) in [OutputType([...])] attributes of exported functions (they work fine in parameter declarations and function bodies), as detailed in the GitHub issue you've discovered, GitHub issue #13768.

    [1] As of this writing, the conceptual about_Scopes help topic doesn't explicitly discuss the dynamic nature of PowerShell's scoping as such (as distinct from the lexical scoping you would find in languages such as C#). In simple terms, PowerShell's dynamic scoping means that, inside a given scope domain (non-module code vs. a given module's code), code called from a given caller is affected by the runtime state of that caller, such as by using statements, Set-StrictMode settings, and the visibility of the caller's variables.