Reputation: 28552
I want to do something special when my PowerShell script is being executed by Windows Terminal and not the normal PowerShell command line or ISE. How to determine that? I checked some built-in variables like $Host
and can't find related information.
Upvotes: 4
Views: 845
Reputation: 21408
Disclaimer: Windows Terminal is still in development at this time of writing and this information could change for the stable release.
Look for the $env:WT_SESSION
environment variable - this looks to be set to a GUID in a Windows Terminal session, but not when running powershell.exe
or running powershell.exe
through ConEmu, both of which I also tested.
@Mr.Key7's answer includes a partial workaround if the variable hasn't been set by the time your script reads it (I have not encountered this), but that workaround will not yield the correct results if the script has been executed with powershell.exe
while a parallel instance of Windows Terminal not associated with the session is executing.
To address this, we need to check that the parent PID of the current PowerShell session is WindowsTerminal.exe
, not just that it is running on the system.
We have to use
Win32_Process
to get a parent process asGet-Process
does not return an object with parent process information:
# Get PIDs of WindowsTerminal currently running
# @() guarantees a collection object even regardless of how many returned
$wTermPids = @( (Get-Process WindowsTerminal).Id )
# Get parent process id from Win32_Process for the current PID
$parentPid = ( Get-CimInstance Win32_Process -Filter "ProcessId = '$PID'" ).ParentProcessId
# Check that the current parent PID is one of the WindowsTerminal PIDs
if( $parentPid -in $wTermPids ) {
'This is running under WindowsTerminal'
} else {
'This is not running under WindowsTerminal'
}
I don't know which version after 5.1 added this in, but as of at least 7.4.2, Get-Process
returns process objects with a Parent
property, so this can be used instead to get the current process parent PIDs instead of Get-CimInstance Win32_Process
in the previous example:
$parentPid = (Get-Process -Id $PID).Parent
The rest of the code in the Windows PowerShell example applies here.
Note that either workaround also has a pitfall: if you launch a child script using Start-Process
the parent process will still be Windows Terminal but it won't have the WT presence/enhancements you may be expecting. This is effectively the same place that @Mr.Key7's answer may put you in, but this way you have a bit more control over detecting whether your script is being executing in a session that was started under Windows Terminal.
Once again, this is not an issue I have personally encountered, checking $env:WT_SESSION
has been reliable in my environment. But if you find there is a race condition for WT_SESSION
being set in your environment, this should help to reliably obtain the parent process and check that it is Windows Terminal.
At the end of the day, though, the environment variable should be the definitive way to check whether you are running under Windows Terminal or not. If this is not being populated in some environments, then it will need to be something ultimately addressed by the Windows Terminal development team.
Upvotes: 7
Reputation: 273
How to known if ps1 file executed in WT?
Looking for $env:WT_SESSION
only works if checked from PS/ WT CommandLine
, but always not defined yet if checked from its ps1 file (while ps1 script executed).
I have tried. The method that works both from Commandline
and PS1 file
is by looking for Get-Process
If ('WindowsTerminal' -in (Get-Process).Name) {'Running in WT'} else {'Not Running in WT'}
Pause
Using Function:
function IsWTRun {'WindowsTerminal' -in (Get-Process).Name}
The output True/ False
.
Upvotes: 0