Rehash: Playing with Window Size

https://blogs.msdn.com/b/timid/archive/2011/06/23/playing-with-window-size.aspx gave the core magic for messing with the console window size.  Since then, I’ve seen functions that allow the user to set it to arbitrary values, but I found myself wanting to grow and shrink the window size by some specified delta, e.g. +10 columns, when generating the ‘test pattern’ from yesterdays’ post.  Why not?  The resulting function handles [int], +/-[int], and [float] as arguments to height and width. 

BufferSize?  Well, I just set it to 99999 and leave it there.  I guess you could play with it if you wanted.

function Set-ConsoleSize {
    
     param (
         [string]$Width = $null,
         [string]$Height = $null,
         [int]$Buffer = $Host.UI.RawUI.BufferSize.Height,
         [switch]$Verbose,
         [switch]$Force
     )

     # Check the host name and exit if the host is not the Windows PowerShell console host.
     if ($host.Name -ne 'ConsoleHost') {
         Write-Warning "$((Get-Variable -ValueOnly -Name MyInvocation).MyCommand)runs only in the console host. You cannot run this script in $($Host.Name).";
         return;
     }

     function Read-ArithmeticParameter {
         param ( [int]$Current, [String]$Value, [int]$Max, [string]$Name, [bool]$Force );

         Write-Debug "current: $current Value: $value Max: $Max Name: $name Force: $Force";
         $lcName = $Name.ToLower();

         if ($Value -match '^[+-](\d+)$') { # value is a +/- modifier
             $delta = $matches[1] -as [int];
             if ($Value[0] -eq '+') {
                 [int]$Value = $Current + $delta;
             } 
             else {
                 [int]$Value = $Current - $delta;
             }
         }
         elseif ($Value -match '^\d+$'      ) { [int]$Value = $Value; }
         elseif ($delta = $Value -as [float]) { [int]$Value = $Current * $delta; } 
         elseif ($Value -eq 'Max'           ) { $Value = $Max; }
         else { Write-Warning "Unable to process -$Name '$Value'"; return; }

         if (($Value -gt $Max) -and !$Force) {
             Write-Warning "Use -Force to set $lcName greater than max $lcName of $Max";
             Write-Verbose "-$Name $value";
             [int]$Value = $Max;
         }
        
         if ($Value -le 0) { Write-Warning "Cannot set $lcName to less than 0"; return; }
         $Value;
     }

     $currentWidth  = $Host.UI.RawUI.WindowSize.Width;
     $currentHeight = $Host.UI.RawUI.WindowSize.Height;
     $currentBuffer = $Host.UI.RawUI.BufferSize.Height;

     $maxWidth  = $Host.UI.RawUI.MaxPhysicalWindowSize.Width;
     $maxHeight = $Host.UI.RawUI.MaxPhysicalWindowSize.Height;

     if (!$Width)  { $Width  = $currentWidth;  }
     if (!$Height) { $Height = $currentHeight; }

     if (!($Width  = Read-ArithmeticParameter -Current $currentWidth  -Value $Width  -Max $maxWidth  -Name Width  -Force $Force)) { return; }
     if (!($Height = Read-ArithmeticParameter -Current $currentHeight -Value $Height -Max $maxHeight -Name Height -Force $Force)) { return; }

     if ($currentWidth -lt $Width) {
         $host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.Size($Width, $Buffer);
         $Host.UI.RawUI.WindowSize = New-Object System.Management.Automation.Host.Size($Width, $Height);
     } else {
         $Host.UI.RawUI.WindowSize = New-Object System.Management.Automation.Host.Size($Width, $Height);
         $host.UI.RawUI.BufferSize = New-Object System.Management.Automation.Host.Size($Width, $Buffer);
     } # if ($currentWidth

     if ($Verbose) { 
         $VerbosePreference = 'continue'; 
         Write-Verbose "Width: $Width";
         Write-Verbose "Height: $Height";
         Write-Verbose "Buffer: $Buffer";
         Write-Verbose "MaxWidth: $maxWidth";
         Write-Verbose "MaxHeight: $maxHeight";
     }
}