Detecting Windows Terminal with PowerShell
In the evolving landscape of software development and system administration, understanding your
environment is essential for ensuring that scripts and commands run as expected. One useful
PowerShell function that helps identify whether a script is running within Windows Terminal is my
Test-IsWindowsTerminal
function. This function is valuable for developers and system
administrators who must tailor their scripts based on the terminal environment.
Overview
Test-IsWindowsTerminal
is a PowerShell function designed to determine if the current session is
running inside Windows Terminal. Windows Terminal is a modern, feature-rich terminal application for
users of command-line tools and shells like PowerShell, WSL, and the Command Prompt. The function
employs a hierarchical parent process test to determine if Windows Terminal is part of the process
tree.
Details
The code for the Test-IsWindowsTerminal
function is shown in the following example.
1function Test-IsWindowsTerminal {
2 [CmdletBinding()]
3 param ()
4
5 # Check if PowerShell version is 5.1 or below, or if running on Windows
6 if ($PSVersionTable.PSVersion.Major -le 5 -or $IsWindows -eq $true) {
7 $currentPid = $PID
8
9 # Loop through parent processes to check if Windows Terminal is in the hierarchy
10 while ($currentPid) {
11 try {
12 $process = Get-CimInstance Win32_Process -Filter "ProcessId = $currentPid" -ErrorAction Stop -Verbose:$false
13 } catch {
14 # Return false if unable to get process information
15 return $false
16 }
17
18 Write-Verbose -Message "ProcessName: $($process.Name), Id: $($process.ProcessId), ParentId: $($process.ParentProcessId)"
19
20 # Check if the current process is Windows Terminal
21 if ($process.Name -eq 'WindowsTerminal.exe') {
22 return $true
23 } else {
24 # Move to the parent process
25 $currentPid = $process.ParentProcessId
26 }
27 }
28
29 # Return false if Windows Terminal is not found in the hierarchy
30 return $false
31 } else {
32 Write-Verbose -Message 'Exiting due to non-Windows environment'
33 return $false
34 }
35}
Components
-
CmdletBinding attribute: This attribute allows the function to use cmdlet features like parameter validation and verbose output.
-
Parameters: The function takes no parameters except the common parameters provided by
CmdletBinding
. Theparam()
declaration must be present to use theCmdletBinding
attribute. -
Version and environment:
1if ($PSVersionTable.PSVersion.Major -le 5 -or $IsWindows -eq $true) {
This condition checks if you're running Windows PowerShell or PowerShell on a Windows system. The
$IsWindows
automatic variable is only available on PowerShell version 6 and higher by default. The function returns$false
for non-Windows environments since Windows Terminal is Windows only. -
Process hierarchy loop:
1while ($currentPid) {
The function uses the current process ID and iterates through its parent processes to determine if any are
WindowsTerminal.exe
. The loop checks every process in the hierarchy unless it findsWindowsTerminal.exe
because Windows Terminal may not be the immediate parent. -
Process retrieval:
1$process = Get-CimInstance Win32_Process -Filter "ProcessId = $currentPid" -ErrorAction Stop -Verbose:$false
This command retrieves the process information based on the process ID.
Get-CimInstance
is used becauseGet-Process
in Windows PowerShell doesn't include information about the parent process. Using-ErrorAction Stop
ensures that any error fetching the process information stops the function.-Verbose:$false
suppresses verbose output for this command to prevent extra noise from being added to the output when verbose logging is enabled. -
Verbose logging:
1Write-Verbose -Message "ProcessName: $($process.Name), Id: $($process.ProcessId), ParentId: $($process.ParentProcessId)"
Verbose logging provides detailed output for debugging purposes, showing the name, ID, and parent ID of each process.
-
Terminal detection:
1if ($process.Name -eq 'WindowsTerminal.exe') { 2 return $true 3}
If a process named
WindowsTerminal.exe
is found, the function returns$true
, indicating that PowerShell is running within Windows Terminal. -
Parent process traversal:
1$currentPid = $process.ParentProcessId
If the current process isn't Windows Terminal, the function moves to the parent process and continues the test.
-
Default return:
1return $false
If the loop completes without finding Windows Terminal, the function returns
$false
.
Usage
To use the Test-IsWindowsTerminal
function, define it in your PowerShell session and call it when
needed.
This function is helpful for scenarios where specific behaviors or configurations are needed when running inside Windows Terminal. It allows for a more tailored and efficient command-line experience.
Summary
The Test-IsWindowsTerminal
function is a concise and efficient way to determine if the current
PowerShell host is Windows Terminal. By leveraging parent process checks and robust error handling,
this function provides a reliable method to tailor scripts based on the terminal environment.
Similar techniques can detect other terminal environments, making it easy to adapt your scripts to different command-line interfaces.
References
Acknowledgments
Thanks to Sean Wheeler for the following tip and for helping resolve a bug in my code.
Other methods of checking the terminal environment, such as testing for the presence of WT_SESSION
or WT_PROFILE_ID
environment variables, aren't used because they provide false positives due to
being inherited if you open another host such as VS Code from Windows Terminal.