Fully automated RDP connection using LAPS password and PowerShell

ยท

3 min read

LAPS is a must-have tool for randomizing local administrator's password in any Active Directory.

In this article, I will show you, how to automate using of LAPS password for making RDP connection, so it will be a matter of calling one PowerShell function ๐Ÿ‘

PS: This was the first time when better security (LAPS) brought me easier management (automated RDP) ๐Ÿ˜€

rdp_laps (1).gif

According to the security, using LAPS for RDP has another benefit, that in case of compromise of such account, it can't be used on other servers (unlike the domain account).

Anyway, there can be computers, where LAPS isn't used. For such cases, my function supports even automation of computer name and username filling into the RDP application. It can also be very easily customized to support TIER model i.e. fill correct domain account for such TIER.


Requirements

  • PowerShell running under the account, that has permissions to read LAPS passwords from AD
  • AutoItX PowerShell module
  • AdmPwd.PS PowerShell module
  • My function Invoke-MSTSC

Key parts of the Invoke-MSTSC function

Gettings LAPS password

$password = (Get-AdmPwdPassword $computerHostname).password

Saving LAPS password to Windows Credential Manager using cmdkey.exe

This step is used when the function retrieved LAPS password

# I have password, so I will use cmdkey to store it in Cred. Manager
Write-Verbose "Saving credentials for $computer and $userName to CredMan"
$ProcessInfo = New-Object System.Diagnostics.ProcessStartInfo
$Process = New-Object System.Diagnostics.Process
$ProcessInfo.FileName = "$($env:SystemRoot)\system32\cmdkey.exe"
$ProcessInfo.Arguments = "/generic:TERMSRV/$computer /user:$userName /pass:`"$password`""
$ProcessInfo.WindowStyle = [System.Diagnostics.ProcessWindowStyle]::Hidden
$Process.StartInfo = $ProcessInfo
[void]$Process.Start()
$null = $Process.WaitForExit()

Using AutoIt for filling everything except the password

This step is used when the function hasn't retrieved LAPS password

Prechecks

if ([console]::CapsLock) {
    $keyBoardObject = New-Object -ComObject WScript.Shell
    $keyBoardObject.SendKeys("{CAPSLOCK}")
    Write-Warning "CAPS LOCK was turned on, disabling"
}

$titleCred = "Windows Security"
if (((Get-AU3WinHandle -Title $titleCred) -ne 0) -and $password) {
    Write-Warning "There is opened window for entering credentials. It has to be closed or auto-fill of credentials will not work."
    Write-Host 'Enter any key to continue' -NoNewline
    $null = [Console]::ReadKey('?')
}

Filling the information

# click on "Show options" in mstsc console
$title = "Remote Desktop Connection"
Start-Sleep -Milliseconds 300 # to get the handle on last started mstsc
$null = Wait-AU3Win -Title $title -Timeout 1
$winHandle = Get-AU3WinHandle -Title $title
$null = Show-AU3WinActivate -WinHandle $winHandle
$controlHandle = Get-AU3ControlHandle -WinHandle $winhandle -Control "ToolbarWindow321"
$null = Invoke-AU3ControlClick -WinHandle $winHandle -ControlHandle $controlHandle
Start-Sleep -Milliseconds 600

# fill computer and username
Write-Verbose "Connecting to: $connectTo as: $userName"
Send-AU3Key -Key "{CTRLDOWN}A{CTRLUP}{DELETE}" # delete any existing text
Send-AU3Key -Key "$connectTo{DELETE}" # delete any suffix, that could be autofilled there

Send-AU3Key -Key "{TAB}"
Start-Sleep -Milliseconds 400

Send-AU3Key -Key "{CTRLDOWN}A{CTRLUP}{DELETE}" # delete any existing text
Send-AU3Key -Key $userName
Send-AU3Key -Key "{ENTER}"

Summary

All needed files (modules included) can be found at my GitHub.

TIP: You can improve this function further by adding TAB support, so the computer names will be automatically completed. Just check my How to add parameter TAB completion post.

Did you find this article valuable?

Support Ondrej Sebela by becoming a sponsor. Any amount is appreciated!

ย