Skip to content

Instantly share code, notes, and snippets.

@trackd
Last active December 17, 2025 14:47
Show Gist options
  • Select an option

  • Save trackd/71d27ae6a512108f0684afb195459b26 to your computer and use it in GitHub Desktop.

Select an option

Save trackd/71d27ae6a512108f0684afb195459b26 to your computer and use it in GitHub Desktop.
IsWindowsTerminal? who knows.
function IsWindowsTerminal {
<#
.SYNOPSIS
this is completely overkill and you should probably not use it.
.NOTES
the problem is:
Start-Process -FilePath powershell -ArgumentList '-nop', '-c', '[bool]$env:WT_SESSION' -RedirectStandardOutput (Join-Path $pwd.Path 'foo.log') -UseNewEnvironment
Start-Sleep 1;Get-Content .\foo.log;Remove-Item .\foo.log
$env:WT_SESSION does not work if you start a shell directly, such as running powershell:
from Start => Run => pwsh.
only if you launch wt.exe does it get created.
#>
[cmdletbinding()]
param(
[Parameter(DontShow)]
[Diagnostics.Process] $Process = (Get-Process -Id $PID),
[Parameter(DontShow)]
[Switch] $Breaker,
[Parameter()]
[Switch] $VersionInfo
)
function Out-TerminalInfo {
param($found)
if (!$VersionInfo.IsPresent) {
return $found
}
if ($Process.ProcessName -eq 'WindowsTerminal') {
$Edition = [regex]::match($Process.Path, 'Preview|Canary|Dev', 'IgnoreCase').Value
if (!$Edition) {
$Edition = 'Stable'
}
}
[PSCustomObject]@{
Success = $found
Name = $Process.ProcessName
Edition = $Edition
Version = $Process.FileVersion
}
}
if ($IsLinux -or $IsMacOS) {
return Out-TerminalInfo $false
}
if ($Process.ProcessName -eq 'WindowsTerminal') {
return Out-TerminalInfo $true
}
if ($Process.ProcessName -in 'conhost', 'Code', 'Code - Insiders') {
Write-Verbose ('Found non-windows terminal: {0}' -f $Process.ProcessName)
return Out-TerminalInfo $false
}
if ($Process.ProcessName -match 'Alacritty|Hyper|Terminus|wezterm|rio') {
Write-Verbose ('Found non-windows terminal: {0}, matching {1}' -f $Process.ProcessName, $Matches[0])
# probably need to add more here..
return Out-TerminalInfo $false
}
if ($Breaker.IsPresent) {
# dont let it recursively check forever, after explorer we're done.
return Out-TerminalInfo $false
}
if ($Process.Parent) {
Write-Verbose ('Parent found: {0}' -f $Process.Parent.ProcessName)
$PSBoundParameters['Process'] = $Process.Parent
return IsWindowsTerminal @PSBoundParameters
}
if ($Process.ProcessName -eq 'explorer') {
Write-Verbose 'Explorer but no breaker, happens if launch a shell from start => run directly, or doing weird stuff.'
try {
$oldTitle = $host.UI.RawUI.WindowTitle
$str = 'IsWindowsTerminal: {0}' -f $Process.Id
$host.UI.RawUI.WindowTitle = $str
$Process = Get-Process | Where-Object { $_.mainWindowTitle -eq $str }
$host.UI.RawUI.WindowTitle = $oldTitle
# no more recursion pls.
$PSBoundParameters['Breaker'] = $true
$PSBoundParameters['Process'] = $Process
return IsWindowsTerminal @PSBoundParameters
}
catch {
return Out-TerminalInfo $false
}
}
if (!$IsCoreCLR) {
Write-Verbose 'Windows PowerShell, using CIM to get parent process.'
$PSBoundParameters['Process'] = Get-Process -Id (Get-CimInstance Win32_Process -Filter ('ProcessId = {0}' -f $Process.ID)).ParentProcessId
return IsWindowsTerminal @PSBoundParameters
}
return Out-TerminalInfo $false
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment