What type of object is $: (such as `$code:`) in Powershell?

What you’re seeing is namespace variable notation, which is a variable-based way to access the content of items in PowerShell drives whose underlying provider implements content-based access (i.e., implements the IContentCmdletProvider interface).

The general syntax is:

${<drive>:<path>}       # same as: Get-Content <drive>:<path>

${<drive>:<path>} = ... # same as: Set-Content <drive>:<path> -Value ...

The enclosing {...} aren’t necessary if both the <drive> name and the <path> can syntactically serve as a variable name; e.g.:

$env:HOME  # no {...} needed

${env:ProgramFiles(x86)} # {...} needed due to "(" and ")"

In practice, as of Windows PowerShell v5.1, the following in-box drive providers support namespace variable notation:

  • Environment (drive Env:)
  • Function (drive Function:)
  • Alias (drive Alias:)
  • FileSystem (drives C:, …)
  • Variable (drive Variable:) – though virtually pointless, given that omitting the drive part accesses variables by default (e.g., $variable:HOME is the same as just $HOME).

Of these, the Env: drive is by far the most frequently used with namespace variable notation, even though most users aren’t aware of what underlies an environment-variable references such as $env:HOME.

On occasion you see it used with a filesystem drive – e.g., ${c:\foo\file.txt} – but the fact that you can only use literal paths and that you cannot control the character encoding limits its usefulness.

It allows interesting uses, however; e.g.:

PS> $alias:foreach  # Get the definition of alias 'foreach'
ForEach-Object

PS> $function:prompt # Get the body of the 'prompt' function
"PS $($executionContext.SessionState.Path.CurrentLocation)$('>' * ($nestedPromptLevel + 1)) ";
# .Link
# https://go.microsoft.com/fwlink/?LinkID=225750
# .ExternalHelp System.Management.Automation.dll-help.xml

# Define a function foo that echoes 'hi' and invoke it.
PS> $function:foo = { 'hi' }; foo
hi

Note:

  • Because ${<drive>:<path>} and ${<drive>:<path>} = <value> are equivalent to
    Get-Content -Path <drive>:<path> and Set-Content -Path <drive>:<path> <value>, paths are interpreted as wildcard expressions (because that’s what -Path does, as opposed to -LiteralPath), which can cause problems with paths that look like wildcards – see this answer for an example and a workaround.

  • As of this writing, namespace variable notation isn’t officially documented yet, but this GitHub issue suggests doing so.

Leave a Comment