2

Trying to move the current, active powershell window to the left side of the screen using a PowerShell script.

I've found this function, but it doesn't really come with any examples.

henrycarteruk
  • 12,708
  • 2
  • 36
  • 40
  • 2
    There are examples, e.g. `Get-Process powershell | Set-Window -X 2040 -Y 142 -Passthru` – Clijsters Mar 27 '17 at 10:47
  • Thanks. After I got some sleep and returned to this, I read the code and found the details in the script. I should really get more sleep. :) – Richie Bartlett Mar 28 '17 at 05:47
  • The link to the code is dead. – not2qubit Jun 03 '23 at 10:50
  • That link is from 2017! Microsoft obviously moved the page some where else. Here's another example that can help: https://www.powershellgallery.com/packages/SciProfile/0.3.0/Content/PSModuleUtils%5CFunctions%5CSet-Window.ps1 – Richie Bartlett Jun 22 '23 at 12:57

3 Answers3

6

Funny and interesting question.

If you want move window, you need to know the Window handle hWnd of it. For console you can do it by using the GetConsoleWindow function from kernel32.dll.

This script, it will move powershell console to upper-left with size (500, 500).

Add-Type -Name Window -Namespace Console -MemberDefinition '
[DllImport("Kernel32.dll")] 
public static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
public static extern bool MoveWindow(IntPtr hWnd, int X, int Y, int W, int H); '

$consoleHWND = [Console.Window]::GetConsoleWindow();
$consoleHWND
[Console.Window]::MoveWindow($consoleHWND,0,0,500,500);

If you know the hWnd of the window you can do many things with that window. You can find all functions here.

But this script work will only work with a real powershell console. If you will start it from Powershell ISE, hWnd will be Zero 0, because Powershell ISE don't have real console in it.

not2qubit
  • 14,531
  • 8
  • 95
  • 135
Mihail Kuznesov
  • 555
  • 2
  • 13
2

To give you a complete example with Set-Window which mimics the manual Window+Left-Arrow.

On my 1920*1200 screen the window dimensions after Window+Left-Arrow are:

#  Left    Top  Width Heigth
#    -7      0    974   1207

So you need to get the screen dimensions first, for the primary monitor this will do:

Add-Type -AssemblyName System.Windows.Forms
$ScreenSize = [System.Windows.Forms.SystemInformation]::PrimaryMonitorSize

$MyLeft  = -7
$MyTop   = 0
$MyWidth = $ScreenSize.Width/2+2*7
$MyHeight= $ScreenSize.Height +7

"Left:{0}  Top:{1}  Width:{2}  Height:{3}" -f $MyLeft,$MyTop,$MyWidth,$MyHeight
Get-Process powershell | Set-Window -X $MyLeft -Y $MyTop -Width $MyWidth -Height $MyHeight
2

Yet another way for moving window of the current posh process:

$MethodDefinition = @'
[DllImport("user32.dll", CharSet = CharSet.Unicode)]
public static extern bool SetWindowPos(IntPtr hWnd, int hWndInsertAfter, int X, int Y, int cx, int cy, int wFlags);
'@
$User32 = Add-Type -MemberDefinition $MethodDefinition -Name 'User32' -Namespace 'Win32' -PassThru

$CurrentProcess = Get-Process -id $PID
$User32::SetWindowPos($CurrentProcess.MainWindowHandle, 0x1, 0, 0, 0, 0, 0x0040 -bor 0x0020 -bor 0x0001)
Vanya Usalko
  • 405
  • 7
  • 10
  • 1
    Can you please describe what your code does (or how it works)? – not2qubit Jun 03 '23 at 10:51
  • No problem. power-shell script can use any windows dynamic load library (DLL). In code, we just do import of the user32 system library and use function from that library. – Vanya Usalko Jun 04 '23 at 13:44
  • I was thinking about the `0x0040 -bor 0x0020 -bor 0x0001` part. – not2qubit Jun 05 '23 at 09:56
  • 1
    Yep, it's a bitwize boolean manipulation within flags. The more details could be found in the API definitions for a [SetWindowPos](https://learn.microsoft.com/en-us/windows/win32/api/winuser/nf-winuser-setwindowpos) function. I.e. it looks like ```SWP_SHOWWINDOW | SWP_FRAMECHANGED | SWP_NOSIZE``` – Vanya Usalko Jun 11 '23 at 09:40