Just a learner
Just a learner

Reputation: 28552

How to determine if my PowerShell script is being executed by Windows Terminal?

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

Answers (2)

codewario
codewario

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.

Windows PowerShell (5.1)

We have to use Win32_Process to get a parent process as Get-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'
}

If using PowerShell Core

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

Mr.Key7
Mr.Key7

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

Related Questions