<# .SYNOPSIS Returns the width of the console window in characters, with a sensible fallback when there isn't a real console to measure. .DESCRIPTION Tries the PowerShell host first ($Host.UI.RawUI.WindowSize), then .NET ([Console]::WindowWidth), then the COLUMNS environment variable, and finally a default. Scheduled tasks, remoting sessions, CI runners and redirected output often have no window at all, and the first two can return 0, $null or throw. This never throws; it just tells you where the number came from. .PARAMETER Default Width to use when nothing can be measured. Default: 120. .PARAMETER Detailed Return an object with the width, where it came from, and whether output is redirected, instead of just the number. .EXAMPLE .\Get-ConsoleWidth.ps1 .EXAMPLE '-' * ((.\Get-ConsoleWidth.ps1) - 1) .EXAMPLE .\Get-ConsoleWidth.ps1 -Detailed #> [CmdletBinding()] [OutputType([int])] param( [ValidateRange(20, 1000)] [int]$Default = 120, [switch]$Detailed ) $width = 0 $source = $null # 1. The PowerShell host. Right for the real console, Windows Terminal, VS Code and ISE. try { $w = $Host.UI.RawUI.WindowSize.Width if ($w -gt 0) { $width = $w; $source = 'Host.UI.RawUI' } } catch { Write-Verbose "RawUI unavailable in host '$($Host.Name)': $($_.Exception.Message)" } # 2. .NET's view of the console. Throws when there's no console handle. if (-not $width) { try { $w = [Console]::WindowWidth if ($w -gt 0) { $width = $w; $source = 'Console' } } catch { Write-Verbose "[Console]::WindowWidth unavailable: $($_.Exception.Message)" } } # 3. Many terminals and CI systems export COLUMNS. if (-not $width -and $env:COLUMNS -match '^\d+$' -and [int]$env:COLUMNS -gt 0) { $width = [int]$env:COLUMNS $source = 'COLUMNS' } # 4. Give up gracefully. if (-not $width) { $width = $Default $source = 'Default' } if ($Detailed) { $redirected = try { [Console]::IsOutputRedirected } catch { $null } [pscustomobject]@{ Width = $width Source = $source HostName = $Host.Name OutputRedirected = $redirected } } else { $width }