PowerShell Scripting Automatic Variables
> A quick reminder that if you need to manage your subscription, use the links in the footer of this email.
Last time, we looked at a variety of automatic variables in PowerShell. These are variables that PowerShell defines whenever you start a PowerShell session. Many of these are intended to make it easier to work with PowerShell in the console. However, there are some variables that only have values during code execution. These are automatic variables that you can use in your scripts and functions.
PSScriptRoot
One of the most useful automatic variables is $PSScriptRoot
. This variable contains the path to the directory where the script or function is located. This is useful for referencing files that are in the same directory as the script.
Function Get-PSFoo {
[cmdletbinding()]
Param()
Write-Host "This command is running from $PSScriptRoot"
$src = Join-Path $PSScriptRoot -ChildPath locationlist.json
Write-host "Opening $src"
Get-Content -Path $src | ConvertFrom-Json | Select-Object Index,Path
}
In order for this work to work, you need to dot-source the script file. If you copy and paste the code into your session, $PSScriptRoot
will be empty.
PS C:\> . c:\temp\Get-PSFoo.ps1
PS C:\> Get-PSFoo
This command is running from C:\temp
Opening C:\temp\locationlist.json
Index Path
----- ----
1 Behind:\
2 S:\
3 S:\PSBluesky
4 Behind:\2025
5 D:\OneDrive\PSBehind
6 C:\Users\Jeff\Documents\MuseScore4\Scores\impromptu-24
The value will always be a file system path. Even if you dot source from a PSDrive, the value of $PSScriptRoot
will be a file system path.
If you need to get to a relative path, you can use code like this:
Function Get-PSBar {
[cmdletbinding()]
Param()
Write-Host "This command is running from $PSScriptRoot"
$src = Join-Path $PSScriptRoot\..\..\scripts -ChildPath PSIntro
Write-host "Opening $src"
Get-ChildItem -path $src -file
}
I put this file in C:\temp\demo.
PS C:\> . C:\temp\demo\Get-PSBar.ps1
PS C:\> Get-PSBar
This command is running from C:\temp\demo
Opening C:\temp\demo\..\..\scripts\PSIntro
Directory: C:\scripts\PSIntro
Mode LastWriteTime Length Name
---- ------------- ------ ----
la--- 8/20/2020 4:03 PM 108 .markdownlint.json
la--- 5/12/2025 9:16 AM 343 CHANGELOG.md
la--- 5/12/2025 8:51 AM 1452 PSIntro.psd1
la--- 5/12/2025 8:51 AM 1034 PSIntro.psm1
la--- 5/12/2025 9:23 AM 692 psproject.json
la--- 5/12/2025 9:22 AM 1945 README.md
la--- 5/9/2025 4:42 PM 1726 scratch.ps1
PS C:\>
Be careful when moving files around as it might affect the relative path. Yes, you can always hard code paths in your code, but that is not a good practice.
PSCommandPath
A related variable is $PSCommandPath
. This variable contains the full path to the script or function that is currently executing. This is useful for logging and debugging purposes, as you can see exactly where the code is being executed from.
Function Get-FooFoo {
[CmdletBinding()]
param (
[Parameter(Mandatory)]
[string]$Name,
[alias('cn')]
[string]$Computername,
[PSCredential]$Credential
)
Write-Verbose "I am running with a `PSCommandPath of $PSCommandPath"
Write-Host "Hello, $Name!"
}