Change PowerShell Console Font and Layout in Windows 10

117 views Asked by At

How can we programmatically alter the PowerShell console settings in Windows 10?

When I install a fresh copy of Windows, I would like the PowerShell console adjusted as follows:

  • Font size 18
  • Screen Buffer Size 9999
  • Window Size 140
  • Window Height 32

It sounds like this should be very simple to do, but I have not found a way yet.

Initially, this seemed like a pathway to doing it but cannot get it to work:

$fontSize = 18
$screenBufferSize = 9999
$windowSize = 140
$windowHeight = 32

function Set-ConsoleSettings {
    param (
        [int]$FontSize,
        [int]$ScreenBufferSize,
        [int]$WindowSize,
        [int]$WindowHeight
    )

    $font = New-Object System.Drawing.Font("Consolas", $FontSize)
    $host.UI.RawUI.GetType().GetProperty("FontSize").SetValue($host.UI.RawUI, $font.Size, $null)
    $host.UI.RawUI.BufferSize = New-Object Management.Automation.Host.Size($ScreenBufferSize, $WindowSize)
    $host.UI.RawUI.WindowSize = New-Object Management.Automation.Host.Size($WindowSize, $WindowHeight)
}

# Change regular (non-admin) PowerShell console
Set-ConsoleSettings -FontSize $fontSize -ScreenBufferSize $screenBufferSize -WindowSize $windowSize -WindowHeight $windowHeight

# Change elevated (admin) PowerShell console
Start-Process powershell.exe -ArgumentList "-NoProfile -Command Set-ConsoleSettings -FontSize $fontSize -ScreenBufferSize $screenBufferSize -WindowSize $windowSize -WindowHeight $windowHeight" -Verb RunAs

Alternatively, maybe creating a custom shortcut with the settings defined in it, and then pinning that to the Taskbar could be a solution:

# Define the desired settings
$fontSize = 18
$screenBufferSize = 9999
$windowSize = 140
$windowHeight = 32

# Create a PowerShell shortcut with the desired font size
$shortcutPath = "$env:USERPROFILE\Desktop\CustomPowerShell.lnk"
$shell = New-Object -ComObject WScript.Shell
$shortcut = $shell.CreateShortcut($shortcutPath)
$shortcut.TargetPath = "$env:SystemRoot\System32\WindowsPowerShell\v1.0\powershell.exe"
$shortcut.Arguments = "-NoProfile -ExecutionPolicy Bypass -Command `$host.UI.RawUI.FontSize=$fontSize; `$host.UI.RawUI.BufferSize=New-Object Management.Automation.Host.Size($screenBufferSize, $windowSize); `$host.UI.RawUI.WindowSize=New-Object Management.Automation.Host.Size($windowSize, $windowHeight)"
$shortcut.Save()

Write-Host "Custom PowerShell shortcut created on desktop."

Again, this fails.

I'm not really looking for "install Windows Terminal" as an answer as, although I love Windows Terminal, this is about configuring out of the box Windows so these settings should be something that I can do within an autounattend.xml to distribute standardised settings (and in any case, Windows Terminal is installed by default in Windows 11 I think).

1

There are 1 answers

0
Dennis On

According to Editing shortcut (.lnk) properties with Powershell there seems to be no real way to set relevant properties of a shortcut file using PowerShell.

You can however create link file and pin it to the taskbar.

I suppose the code could be modified to copy a lnk file instead of creating one.

Function Set-PinTaskbar {
    Param (
        [parameter(Mandatory=$True, HelpMessage='Target item to pin')]
        [ValidateNotNullOrEmpty()]
        [string] $Target,

        [Parameter(Mandatory=$False, HelpMessage='Target item to unpin')]
        [switch]$Unpin
    )

    if (!(Test-Path $Target)) {
        Write-Warning '$Target does not exist'
        Break
    }

    $KeyPath1  = 'HKLM:\SOFTWARE\Classes'
    $KeyPath2  = '*'
    $KeyPath3  = 'shell'
    $KeyPath4  = '{:}'
    $ValueName = 'ExplorerCommandHandler'
    $ValueData =
        (Get-ItemProperty `
            ('HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Explorer\' + `
                'CommandStore\shell\Windows.taskbarpin')
        ).ExplorerCommandHandler

    $Key2 = (Get-Item $KeyPath1).OpenSubKey($KeyPath2, $true)
    $Key3 = $Key2.CreateSubKey($KeyPath3, $true)
    $Key4 = $Key3.CreateSubKey($KeyPath4, $true)
    $Key4.SetValue($ValueName, $ValueData)

    $Shell = New-Object -ComObject 'Shell.Application'
    $Folder = $Shell.Namespace((Get-Item $Target).DirectoryName)
    $Item = $Folder.ParseName((Get-Item $Target).Name)

    # Registry key where the pinned items are located
    $RegistryKey = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Taskband'
    
    # Binary registry value where the pinned items are located
    $RegistryValue = 'FavoritesResolve'
    
    # Gets the contents into an ASCII format
    $CurrentPinsProperty = ([system.text.encoding]::ASCII.GetString((Get-ItemProperty -Path $RegistryKey -Name $RegistryValue | 
        Select-Object -ExpandProperty $RegistryValue)))
    
        # Specifies the wildcard of the current executable to be pinned, so that it won't attempt to unpin / repin
    $Executable = '*' + (Split-Path $Target -Leaf) + '*'
    
    # Filters the results for only the characters that we are looking for, so that the search will function
    [string]$CurrentPinsResults = $CurrentPinsProperty -Replace '[^\x20-\x2f^\x30-\x39\x41-\x5A\x61-\x7F]+', ''

    # Unpin if the application is pinned
    if ($Unpin.IsPresent) {
        if ($CurrentPinsResults -like $Executable) {
            $Item.InvokeVerb('{:}')
        }
    }
    else {
        # Only pin the application if it hasn't been pinned
        if (!($CurrentPinsResults -like $Executable)) {
            $Item.InvokeVerb('{:}')
        }
    }
    
    $Key3.DeleteSubKey($KeyPath4)
    if ($Key3.SubKeyCount -eq 0 -and $Key3.ValueCount -eq 0) {
        $Key2.DeleteSubKey($KeyPath3)
    }
}

$target = get-item ([environment]::getfolderpath('system') + 'WindowsPowerShell\v1.0\powershell.exe')
Set-PinTaskbar -Target $target.FullName