One really neat SysInternals tool is Desktops. It allows for managing several virtual workspaces, know as desktops on Windows machines. Unlike Linux that offers a builtin way to transfer between desktops, Windows does not natively expose a way to do so. The cmdlets added to PoshInternals now allow you to manage these virtual desktops right from the command line!
Desktops are little sandboxes of windows. Processes can be associated with a desktop and all windows drawn by that process will show up in that desktop. This allows you to declutter you main desktop into many desktops. Desktops are named entities and you can switch between them pretty easily once they are created. Simply creating a desktop doesn’t associate any processes with it. If you were to switch to a desktop without starting a process in it, you will see a blank screen. If you find yourself in this circumstance, you can access task manager and start processes that way.
Creates new desktops that are tied to the current Window Station. In most circumstances, this will be WinSta0 or the default Window Station. Window Stations contain one or more desktops and manage things such as the clipboard. For more information on Window Stations, check out MSDN. Desktops are limited by the desktop heap which, by default, is 48MB. By default, this cmdlet will start the explorer.exe process in the newly created desktop.
Returns the desktops that are associated with the current WinStation. The returned desktops are named and have a handle that is used to create processes in the desktop or show the desktop.
Activates the specified desktop as an interactive desktop. Again, it’s worth noting that if nothing was started in this desktop before showing it, you’ll have to use task manager to launch a process to work with in the desktop.
Start-Process Proxy Function
This proxy function adds the Desktop parameter to Start-Process. As expected, specifying the name of the target desktop will start the process in that desktop. One caveat with this method is that since PowerShell is a console application, if you just run PowerShell it will associate with the other desktop but input will still be taken on the current PowerShell window. This is due to how shared consoles work in Windows. To get around this and make a new PowerShell window, you can use the following command line.
Start-Process PowerShell -ArgumentList “& `”Start PowerShell`”" -Desktop Desktop2
Desktops is currently available in the dev branch of PoshInternals on GitHub. Check it out!
Here’s a video of it in action.
Interesting Side Note About Windows 8 and CreateDesktop
While creating the New-Desktop cmdlet I ran into an issue with Windows 8. Apparently, there currently exists a bug that will cause a BSOD from user mode code using CreateDesktop. I reproduced this on several Windows 8 machines with 100% consistency. The 5th parameter to CreateDesktop is the access mask used to specify security and access writes for the newly created desktop. I had a bug in my P\Invoke C# code that effectively was causing me to pass a $null as the access mask. This caused a BSOD everytime! It’s a little scary because it this function doesn’t require the process to be elevated. If anyone from Microsoft is curious at looking at the crash dump, here’s the analyze -v from WinDbg. I’ve also posted a simple example on PoshCode.