Created
May 22, 2020 21:25
-
-
Save jborean93/be94d9255e601e6ddfeddb752fa486b5 to your computer and use it in GitHub Desktop.
Starts Windows Terminal as the current user, another user, and optionally elevated.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| # Copyright: (c) 2020, Jordan Borean (@jborean93) <[email protected]> | |
| # MIT License (see LICENSE or https://opensource.org/licenses/MIT) | |
| Function Start-WindowsTerminal { | |
| <# | |
| .SYNOPSIS | |
| Start Windows Terminal from PowerShell. | |
| .DESCRIPTION | |
| Start Windows Terminal from PowerShell. This can be done as the current user, another user, and optionally | |
| elevated through UAC. | |
| .PARAMETER Credential | |
| Custom user credential to use when starting windows terminal. Unless UAC is disabled or not applied to the target | |
| account, the process will be a limited process. Use with -Elevated to elevate the process. | |
| .PARAMETER Elevated | |
| Whether to run as an elevated user or not. This will also result in a interactive UAC prompt. Can be combined with | |
| -Credential to start Windows Terminal elevated as another user when the current user is also an admin. | |
| .NOTES | |
| To start WindowsTerminal as another user, the WindowsTerminal app must be installed on that user's profile. If it | |
| is not then this cmdlet will fail with wt.exe not found. | |
| #> | |
| [CmdletBinding()] | |
| param ( | |
| [PSCredential] | |
| $Credential, | |
| [Switch] | |
| $Elevated | |
| ) | |
| $splitUser = { | |
| param ([PSCredential]$Credential) | |
| # ProcessStartInfo requires a NETLOGON username form 'DOMAIN\user' to be split up into different values. This | |
| # extracts the domain part if that user is in that form otherwise keeps it as is. | |
| $username = $Credential.UserName | |
| $domain = [NullString]::Value | |
| if ($username.Contains('\')) { | |
| $domain, $username = $username.Split('\\', 2) | |
| } | |
| $domain, $username | |
| } | |
| if ($Credential -and $Elevated) { | |
| # This is a tricky process, we cannot elevate and run as another user at the same time so we need to do it | |
| # step by step. These steps are: | |
| # | |
| # 1. Start a process as another user | |
| # 2. Create an elevated process for that user using UAC | |
| # 3. Start wt.exe from that elevated process | |
| # | |
| # We can also only start wt.exe from that elevated process, we cannot start it as elevated from the get go. | |
| # See 'elseif ($Elevated)' for more details. | |
| $elevation = { | |
| Start-Process -FilePath powershell.exe -ArgumentList 'wt.exe' -WindowStyle Hidden -Verb Runas | |
| } | |
| $elevationCommand = [Convert]::ToBase64String([Text.Encoding]::Unicode.GetBytes($elevation.ToString())) | |
| # Start powershell as another user which will elevate itself through UAC then call wt.exe. | |
| $domain, $username = &$splitUser -Credential $Credential | |
| $psi = [System.Diagnostics.ProcessStartInfo]@{ | |
| FileName = 'powershell.exe' | |
| Arguments = "-WindowStyle Hidden -EncodedCommand $elevationCommand" | |
| LoadUserProfile = $true | |
| UserName = $username | |
| Domain = $domain | |
| Password = $Credential.Password | |
| UseShellExecute = $false | |
| WindowStyle = 'Hidden' | |
| } | |
| $null = [System.Diagnostics.Process]::Start($psi) | |
| } | |
| elseif ($Credential) { | |
| # Using 'Start-Process -Credential $Credential' will spawn the process as the other user but the window | |
| # doesn't allow any interaction. .NET has no limitations here so we use that instead. | |
| $domain, $username = &$splitUser -Credential $Credential | |
| $psi = [System.Diagnostics.ProcessStartInfo]@{ | |
| FileName = 'wt.exe' | |
| LoadUserProfile = $true | |
| UserName = $username | |
| Domain = $domain | |
| Password = $Credential.Password | |
| UseShellExecute = $false | |
| WindowStyle = 'Hidden' | |
| } | |
| $null = [System.Diagnostics.Process]::Start($psi) | |
| } | |
| elseif ($Elevated) { | |
| # Want to start it elevated through UAC. Unfortunately we cannot just call wt.exe through UAC as that won't | |
| # place the proper groups to the new token that are needed to access wt.exe. By starting a new powershell | |
| # that is elevated then wt.exe, it will inherit the elevated access token and have the proper token | |
| # capabilities applied. | |
| Start-Process -FilePath powershell.exe -ArgumentList 'wt.exe' -WindowStyle Hidden -Verb Runas | |
| } | |
| else { | |
| # Just want to start a new instance, call normally. | |
| Start-Process -FilePath wt.exe | |
| } | |
| } |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment