Windows 10 introduced a great new feature with virtual desktops. This set of powershell commandlets helps out and lets you control virtual desktops from scripts.
Now with support for Windows 11 including Insider up to 24H2
Now with support for Windows Server 2022
Now with support for Powershell Core (pin application commandlets still not work)
Now with support for Windows Terminal
Compatible to supported versions of Windows Server 2016, Windows 10, Windows Server 2022 and Windows 11!
Since Technet Gallery was closed, now here.
Also on Powershell Gallery as VirtualDesktop module, see here or install with
Install-Module VirtualDesktopProject page on github is here.
- bugfix for Windows 11: fixes Windows Explorer crash
- bugfix for Windows 11: fixes missing activiation after desktop switch
- new commands Pin-ActiveWindow and Unpin-ActiveWindow
- Windows 11: parameter -NoAnimation for Switch-Desktop
- faster API call FindWindow instead of EnumWindows
- Windows 11: animated switch to new desktop
- changes for Win 11 24H2 and fixing of messages
- changes for Win 11 3085 and up
- bug fix for Win 11 Insider Canary
- Remove-AllDesktops for all versions
- bug fix for Win 11 22H2 Build 22621.2215
- integration of Win 11 22H2 Build 22621.2215 and Insider versions
- Remove-AllDesktops without function on Win 11 22H2 Build 22621.2215 and Insider versions (will soon be fixed)
- no flashing icons after switching of desktops
support for Windows 11 Insider 25276+
bug fix: desktop for pinned windows and apps are recognized
support for Powershell Core
support for Windows Server 2022
support for Windows Terminal
support for Windows 11 Insider build 22449 and up
support for Windows 10 21H2 and Windows 11
Set-DesktopName works on current virtual desktop if parameter -desktop is missing
integrating fixes from VirtualDesktop.cs
fixes for Get-DesktopIndex
compatible to Powershell Core 7.0 (but not 7.1 or up)
parameter -PassThru for Set-DesktopName (by sirAndros)
support for desktop names introduced with Win 10 2004
new functions Get-DesktopList, Get-DesktopName and Set-DesktopName
desktop name as parameter for many functions
support for verbose output
version checking)
- Load commands (assumes VirtualDesktop.ps1 is in the current path)
. .\VirtualDesktop.ps1- Create a new virtual desktop and switch to it
New-Desktop | Switch-Desktop- Create a new virtual desktop and name it (only on Win 10 2004 or up)
New-Desktop | Set-DesktopName -Name "The new one"- Get second virtual desktop (count starts with 0) and remove it
Get-Desktop 1 | Remove-Desktop -Verbose- Retrieves the count of virtual desktops
Get-DesktopCount- Show list of virtual desktops
Get-DesktopList- Move notepad window to current virtual desktop
(ps notepad)[0].MainWindowHandle | Move-Window (Get-CurrentDesktop) | Out-Null- Move powershell window to last virtual desktop and switch to it
Get-Desktop ((Get-DesktopCount)-1) | Move-Window (Get-ConsoleHandle) | Switch-Desktop- Retrieve virtual desktop on which notepad runs and switch to it
Get-DesktopFromWindow ((Get-Process "notepad")[0].MainWindowHandle) | Switch-Desktop- Pin notepad to all desktops
Pin-Window ((Get-Process "notepad")[0].MainWindowHandle)For a C# implementation look here: https://github.com/MScholtes/VirtualDesktop
The API is not or rarely documented by Microsoft. So there is a risk Microsoft changes the API with an os update and this script will then not work anymore (Microsoft did so already with anniversary update, 1803, 1809, Server 2022 and Windows 11).
For most of the functions you can hand the parameter as parameter or through the pipeline
In most commands you can use a desktop object, the desktop number or a part of the desktop name as parameter desktop, see online help for more information.
Get-DesktopCountGet count of virtual desktops
Get-DesktopListShow list of virtual desktops
New-DesktopCreate virtual desktop. Returns desktop object.
Switch-Desktop -Desktop desktop -NoAnimationSwitch to virtual desktop. Parameter is number of desktop (starting with 0 to count-1), desktop object or string (part of desktop name). Parameter -NoAnimation only on Windows 11.
Remove-Desktop -Desktop desktopRemove virtual desktop. Parameter is number of desktop (starting with 0 to count-1), desktop object or string (part of desktop name).
Windows on the desktop to be removed are moved to the virtual desktop to the left except for desktop 0 where the second desktop is used instead. If the current desktop is removed, this fallback desktop is activated too.
If no parameter is supplied, the last desktop is removed.
Remove-AllDesktopsRemove all virtual desktops but visible.
Get-CurrentDesktopGet current virtual desktop as desktop object.
Get-Desktop -Index indexGet virtual desktop with index number (0 to count-1). Returns desktop object.
Get-DesktopIndex -Desktop desktopGet index number (0 to count-1) of virtual desktop. Returns integer or -1 if not found.
Get-DesktopName -Desktop desktopGet name of virtual desktop. Returns string.
Set-DesktopName -Desktop desktop -Name name -PassThruSet name of virtual desktop to name. Works only with Windows 10 2004 or up.
Set-DesktopWallpaper -Desktop desktop -Path path -PassThruSet wallpaper of virtual desktop to path. Works only with Windows 11.
Set-AllDesktopWallpapers -Path pathSet wallpaper of all virtual desktops to path. Works only with Windows 11.
Get-DesktopFromWindow -Hwnd hwndGet virtual desktop of window (whose window handle is passed). Returns desktop object.
Test-CurrentDesktop -Desktop desktopChecks whether a desktop is the currently displayed virtual desktop. Returns boolean.
Get-LeftDesktop -Desktop desktopGet the desktop object on the "left" side. If there is no desktop on the "left" side $NULL is returned.
Returns desktop "left" to current desktop if parameter desktop is omitted.
Get-RightDesktop -Desktop desktopGet the desktop object on the "right" side.If there is no desktop on the "right" side $NULL is returned.
Returns desktop "right" to current desktop if parameter desktop is omitted.
Move-Desktop -Desktop desktopMove current desktop to other virtual desktop. Works only with Windows 11.
Move-Window -Desktop desktop -Hwnd hwndMove window whose handle is passed to virtual desktop.
The parameter values are auto detected and can change places. The desktop object is handed to the output pipeline for further use.
If parameter desktop is omitted, the current desktop is used.
Move-ActiveWindow -Desktop desktopMove active window to virtual desktop.
The desktop object is handed to the output pipeline for further use.
If parameter desktop is omitted, the current desktop is used.
Test-Window -Desktop desktop -Hwnd hwndCheck if window whose handle is passed is displayed on virtual desktop. Returns boolean.
The parameter values are auto detected and can change places. If parameter desktop is not supplied, the current desktop is used.
Pin-Window -Hwnd hwndPin window whose window handle is given to all desktops.
Pin-ActiveWindowPin active window to all desktops.
Unpin-Window -Hwnd hwndUnpin window whose window handle is given to all desktops.
Unpin-ActiveWindowUnpin active window from all desktops.
Test-WindowPinned -Hwnd hwndChecks whether a window whose window handle is given is pinned to all desktops. Returns boolean.
Pin-Application -Hwnd hwndPin application whose window handle is given to all desktops.
Unpin-Application -Hwnd hwndUnpin application whose window handle is given to all desktops.
Test-ApplicationPinned -Hwnd hwndChecks whether an application whose window handle is given is pinned to all desktops. Returns boolean.
Get-ConsoleHandleGet window handle of powershell console in a safe way (means: if powershell is started in a cmd window, the cmd window handle is returned).
Get-ActiveWindowHandleGet window handle of foreground window (the foreground window is always on the current virtual desktop).
Find-WindowHandleFind first window handle to title text or retrieve list of windows with title (when called with '*' as parameter)