Skip to content

Instantly share code, notes, and snippets.

@Jaykul
Last active August 14, 2020 21:12
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save Jaykul/f715ec958df3b6b5dfc381634d641db8 to your computer and use it in GitHub Desktop.
Save Jaykul/f715ec958df3b6b5dfc381634d641db8 to your computer and use it in GitHub Desktop.
Using WASP to remote desktop, for those ocassions when policy blocks you ...
<#
.SYNOPSIS
Connects to remote desktop using the specified credentials by automating UI input using WASP
.DESCRIPTION
Requires the WASP (Windows Automation Scripting in PowerShell) module to be installed.
This script is a workaround for environments where GPOs don't allow saving credentials,
but we only have the credentials via an API from PowerShell.
... hey, it's better than exposing the plain text in a browser and copy-pasting via the clipboard!
Connect-RemoteDesktop is (in my opinion) safer and more secure, since it stores credentials in the vault,
and you don't have to fetch them each time. It also has much greater compatibility with versions of Windows.
This script works on Windows 10, 1903 at least -- but since the Remote Desktop UI has changed, it may not work in other versions.
.EXAMPLE
Connect-WaspRemoteDesktop $RemoteComputer -Credential MyUserName
Would prompt for credentials using the normal Windows credential prompt (instead of the Remote Desktop dialog) before initiating the remote connection.
.EXAMPLE
[PSCustomObject]@{ CN = $Server; Credential = BetterCredentials\Get-Credential -Domain $Server } | Connect-WaspRemoteDesktop
Gets the password from the vault, then passes the credentials and server name to this function for automation...
.LINK
Get-QMAzConnectionInfo
.NOTES
After running this command you need to stop using the computer for a few seconds while it connects, because it's going to be automating mouse and keyboard input.
#>
[CmdletBinding()]
param(
# The computer name or IPAddress to connect to
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
[Alias("CN", "IPAddress")]
[string]$ComputerName,
# The credential to use to connect
[Parameter(Mandatory, ValueFromPipelineByPropertyName)]
[System.Management.Automation.Credential()]
[PSCredential]$Credential
)
begin {
# All the rest of this depends on WASP
if (-not (Get-Module -FullyQualified @{ ModuleName = "WASP"; ModuleVersion = "2.5.0.0" } -ListAvailable)) {
throw "WASP module not installed. Please Install-Module WASP, and try again."
} elseif (-not (Get-Module -FullyQualified @{ ModuleName = "WASP"; ModuleVersion = "2.5.0.0" })) {
Import-Module WASP -Verbose:$false
}
}
process {
Write-Warning "Automating Windows Remote Desktop: please don't click or type until you're connected"
&"$($env:SystemRoot)\system32\mstsc.exe" /v $ComputerName
$Seconds = 0
while (($Seconds++) -lt 8 -and -not (Select-UIElement "Windows Security" -ControlType Window)) {
Start-Sleep -Seconds 1
}
if (($login = Select-UIElement "Windows Security" -ControlType Window)) {
$login | Select-UIElement "More choices" -ControlType Hyperlink -Recurse |
Invoke-Invoke.Invoke # click
$login | Select-UIElement "Switch to Local or domain account password" -recurse |
Invoke-SelectionItem.Select
$login | Select-UIElement "Email address" -ControlType Edit -recurse |
Invoke-Value.SetValue $Credential.UserName
$login | Select-UIElement "Password" -ControlType Edit -recurse |
Invoke-Value.SetValue $Credential.GetNetworkCredential().Password
$login | Select-UIElement "OK" -ControlType Button |
Invoke-Invoke.Invoke # click
} else {
Write-Warning "Unable to locate the Remote Deskop window titled 'Windows Security' after a couple of seconds. Giving up."
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment