20

How to start a powershell from "RUN" with specific window size? is there any argument for that like "-size:100x100". is that possible with RUN or is there any other way to run a program window with a given size?

knobiDev
  • 462
  • 1
  • 5
  • 17
  • `PowerShell.exe -noe -c ". mode.com con: lines=25 cols=80"` – JosefZ Apr 08 '17 at 16:59
  • 1
    I suggest you play around with the properties you see with `$host.ui.rawui|gm` –  Apr 08 '17 at 17:09
  • @JosefZ: That works in principle, but the unfortunate side effect is that you lose any scroll-back buffer (the buffer height is set to the window height). – mklement0 Apr 08 '17 at 17:35

2 Answers2

38

From the Windows Run dialog:

The following command starts PowerShell in a console window with the default size and then resizes the window to 100 columns x 50 rows:

powershell -noexit -command "[console]::WindowWidth=100; [console]::WindowHeight=50; [console]::BufferWidth=[console]::WindowWidth"

Note: powershell -noexit -command "mode con cols=100 lines=50" works in principle, but has the unfortunate side effect that you lose any scroll-back buffer (the buffer height is set to the window height).

The command uses the [console] (System.Console) .NET type to set the window width and height, and additionally sets the buffer width to the same value as the window width, so as to ensure that no horizontal scroll bar appears.

From an existing console window:

If you run the above command from an existing Command Prompt or PowerShell console, the new PowerShell session starts in the current window, and therefore resizes the current window.
Here's how to open a new window:

  • from a Command Prompt (cmd.exe): use start:

    start powershell -noexit -command "[console]::windowwidth=100; [console]::windowheight=50; [console]::bufferwidth=[console]::windowwidth"
    
  • from a PowerShell console window: use Start-Process (note the single quotes around the argument list):

    start-process powershell '-noexit -command "[console]::windowwidth=100; [console]::windowheight=50; [console]::bufferwidth=[console]::windowwidth"'
    

If you don't want to resize the window after it has opened with the default size:

The commands above run after the new window has been created with the default size, which can be visually disruptive.

To prevent that, you have two options:

  • Create a shortcut file that targets powershell.exe, configure its properties to set the desired size, then run the shortcut file (*.lnk) to open the window.

    • As papo points out, you can also preset the window size for PowerShell instances you invoke via the Start Menu, via the Win-X shortcut menu, or via File Explorer's File > Open Windows Powershell command that way, by modifying the preexisting underlying shortcut file:[1]
      "$env:AppData\Microsoft\Windows\Start Menu\Programs\Windows PowerShell\Windows PowerShell.lnk"
  • Change the default window size to your liking, but note that this then applies to all PowerShell sessions started with just the executable name (or path):

    • Interactively:

      • Press Win+R and submit just powershell

      • Open the new window's system menu, select Properties and configure the window size as desired.
        Future windows launched the same way will have the same size.

    • Programmatically:

      • Console window properties are stored in the registry at HKEY_CURRENT_USER\Console, with the REG_DWORD value WindowSize containing the window size, and ScreenBufferSize containing the buffer size:

      • Key HKEY_CURRENT_USER\Console (HKCU:\Console) contains the overall defaults.

      • Subkeys, such as %SystemRoot%_System32_WindowsPowerShell_v1.0_powershell.exe, contain overrides for specific executables / window titles.

        • Important: These settings do not apply to console windows started via shortcut files (.lnk); the latter dynamically inherit the overall console defaults directly from HKEY_CURRENT_USER\Console (not from any subkeys) - except for CodePage on Windows 10 (not sure about Windows 8/8.1), and except for values later overridden via the Properties dialog, which are saved directly in the file.
      • Subkeys inherit values from their parent, which complicates setting values for subkeys - see below for an example.


Setting powershell.exe window-size defaults programmatically:

The following PSv5+ snippet sets the default window size for powershell.exe-launched console windows to 100 columns by 50 rows.

Note that the fact that screen buffer values are inherited from the overall default settings, stored directly in HKCU:\Console, adds complexity.

# Determine the target registry key path.
$keyPath = 'HKCU:\Console\%SystemRoot%_System32_WindowsPowerShell_v1.0_powershell.exe'

# Get the existing key or create it on demand.
$key = Get-Item $keyPath -ErrorAction SilentlyContinue
if (-not $key) { $key = New-Item $keyPath }

# Determine the new size values.
[uint32] $cols = 100; [uint32] $lines = 50
# Convert to a DWORD for writing to the registry.
[uint32] $dwordWinSize = ($cols + ($lines -shl 16))

# Note: Screen *buffer* values are inherited from 
#       HKCU:\Console, and if the inherited buffer width is larger
#       than the window width, the window width is apparently set to 
#       the larger size.
#       Therefore, we must also set the ScreenBufferSize value, passing through
#       its inherited height value while setting its width value to the same
#       value as the window width.
[uint32] $dwordScreenBuf = Get-ItemPropertyValue HKCU:\Console ScreenBufferSize -EA SilentlyContinue
if (-not $dwordScreenBuf) {  # No buffer size to inherit.
  # Height is 3000 lines by default. 
  # Note that if we didn't set this explicitly, the buffer height would 
  # default to the same value as the window height.
  $dwordScreenBuf = 3000 -shl 16  
}

# Set the buffer width (low word) to the same width as the window
# (so that there's no horizontal scrolling).
$dwordScreenBuf = $cols + (($dwordScreenBuf -shr 16) -shl 16)

# Write the new values to the registry.
Set-ItemProperty -Type DWord $key.PSPath WindowSize $dwordWinSize
Set-ItemProperty -Type DWord $key.PSPath ScreenBufferSize $dwordScreenBuf

[1] papo further states, "[That the] Win+X Menu actually starts this lnk (will error if missing), which is weird, as Win+X has its own shortcuts: "$env:LOCALAPPDATA\Microsoft\Windows\WinX\Group3", which are ignored. (Win10 1809). PS started from Explorer's > File will still work if this link is removed, but will use defaults from registry."

mklement0
  • 382,024
  • 64
  • 607
  • 775
  • Thanks for the very first command, I put this at the top of my profile and now I get the default Powershell Core window size. However do you know how to set the location of the console at the center of the screen? I tried to play with `[console]::WindowLeft` and `[console]::WindowTop` but it seems to change the location of the scrollbars, not the window itself... Thanks – Jérôme MEVEL Jun 02 '20 at 10:18
  • @JérômeMEVEL Indeed, these properties cannot be used to position a window. [This answer](https://stackoverflow.com/a/42334329/45375) contains a C# solution. Since a PowerShell-based solution may be of interest too, I encourage you to ask a _new_ question. – mklement0 Jun 02 '20 at 12:45
  • Is there any way to specify that after resizing, lock window size? e.g. preventing users from resizing the window after powershell has been launched? – Hatefiend Jan 13 '21 at 09:36
  • @Hatefiend: I don't if that can be done; if it can be done, it won't be trivial. I encourage you to ask a _new_ question that focuses on that. – mklement0 Jan 13 '21 at 14:23
  • Are you aware of any documentation by Microsoft outlining your "Programmatically" section? Issuing the command `start "some title"` will look for `some title` as a subkey to HKCU\Console but I just cannot find this documented anywhere. –  Sep 02 '21 at 16:06
  • @madeslurpy, I'm afraid I don't have a documentation link; my answer is based on trial and error. – mklement0 Sep 02 '21 at 16:35
  • Okay, I just find articles describing it, but no actual documentation saying how conhost picks the settings from the registry. –  Sep 03 '21 at 12:59
3

Had issues with the rest of my script running in the same resized window.

This seemed to work though:

[console]::WindowWidth=80; 
[console]::WindowHeight=50; 
[console]::BufferWidth=[console]::WindowWidth

cd myDirectory
node app

Example above is a Powershell script I run to launch my node API

Dandesaj
  • 107
  • 8
  • 3
    I'm not understanding what this adds that isn't covered in [mklement0's detailed answer](https://stackoverflow.com/a/43298114/150605). You're modifying the same properties of `[Console]` as that answer is except you're doing so in the script itself instead of the command line. This won't work if there's no script involved, and the question isn't specifically asking about a script, either. – Lance U. Matthews Sep 27 '22 at 16:37