How to automate Windows Security prompt input

Here's another post about automation. This time let's automate Windows Security input prompts text input. Disclaimer, use your best judgment to figure when you should or shouldn't use this scripts. Keep in mind that for the next set of examples passwords are kept in plain text. If you plan to actually use this files, at least use SecureStrings (check reference here). Please be careful, I won't be responsible for any misuse of the scripts presented in this post.

Moving on from the security disclaimers, some might ask why automate password prompts? Well, most Software development companies have Local domain Virtual Machine farms that are for internal development proposes only. Assuming all VMs are created the same Administrator account credentials, it would be neat if we could automate password prompts every time a developer wants Remote Desktop or explore the VM's file system. In my opinion, this is the only acceptable scenario where password prompts can be automated. Anyway let's take a look at the scripts.

Automating Remote Desktop access

<#
.SYNOPSIS
  Start Remote Desktop with 'local\administrator' credentials
.NOTES
  Useful to rapidly connect to a Go Lab VM
#> 

Param(
  [string]$hostname = "dev.vm-001.local"
)

Process 
{
  # helper function to locate a open program using by a given Window name
  Function FindWindow([string]$windowName, [int]$retries = 5, [int]$sleepInterval = 1000) {
    
    [int]$currentTry = 0;
    [bool]$windowFound = $false;
    
    Do {
      $currentTry++;
      
      Start-Sleep -Milliseconds $sleepInterval
      Try {
        [Microsoft.VisualBasic.Interaction]::AppActivate($windowName)
        $windowFound = $true;  
      } Catch {
        Write-Host "   [$currentTry out of $retries] failed to find Window with title '$windowName'" -ForegroundColor Yellow
        $windowFound = $false;
      }
    } While ($currentTry -lt $retries -and $windowFound -eq $false)
    

    return $windowFound;
  }

  # import required assemblies
  Add-Type -AssemblyName Microsoft.VisualBasic
  Add-Type -AssemblyName System.Windows.Forms


  # test if the provided hostname is valid
  $testedHostname = Test-Connection $hostname -Count 1 -ErrorAction SilentlyContinue

  if($testedHostname -eq $null) {
    Write-Error "the provided hostname could not be resolved '$hostname'" -ErrorAction Stop
  }
  
  $vmIp = $testedHostname.IPV4Address.IPAddressToString

  # open Remote Desktop with 'local\administrator'
  Write-Host "starting connection to '$testedHostname' using 'local\administrator' credentials!"
  cmdkey /generic:TERMSRV/$vmIp /user:local\administrator
  mstsc /v:$vmIp
  
  # first prompt to enter the password
  if(FindWindow("Windows Security")) {
    Start-Sleep -Milliseconds 500
    [System.Windows.Forms.SendKeys]::SendWait('Password1{ENTER}')  
  }
  
  # second prompt to accept the certificate
  if(FindWindow("Remote Desktop Connection")) {
    Start-Sleep -Milliseconds 250
    [System.Windows.Forms.SendKeys]::SendWait('Y')
  }


  Write-Host "done!"
} 

automated Remote Desktop interaction

Automate opening Windows Explorer on remote machine file system

<#
.SYNOPSIS
  Open Windows Explorer in the  'local\administrator' credentials
.NOTES
  Quickly open a new Windows Explorer Windows using 'local\adminstrator' credentials
#> 

param(
  [string]$hostname = "dev.vm-001.local"
)

Process 
{
  # helper function to locate a open program using by a given Window name 
  Function FindWindow([string]$windowName, [int]$retries = 5, [int]$sleepInterval = 1000) {
    
    [int]$currentTry = 0;
    [bool]$windowFound = $false;
    
    Do {
      $currentTry++;
      
      Start-Sleep -Milliseconds $sleepInterval
      Try {
        [Microsoft.VisualBasic.Interaction]::AppActivate($windowName)
        $windowFound = $true;  
      } Catch {
        Write-Host "   [$currentTry out of $retries] failed to find Window with title '$windowName'" -ForegroundColor Yellow
        $windowFound = $false;
      }
    } While ($currentTry -lt $retries -and $windowFound -eq $false)
    

    return $windowFound;
  }
  
  # import required assemblies
  Add-Type -AssemblyName Microsoft.VisualBasic
  Add-Type -AssemblyName System.Windows.Forms


  # test if the provided hostname is valid
  $testedHostname = Test-Connection $hostname -Count 1 -ErrorAction SilentlyContinue

  if($testedHostname -eq $null) {
    Write-Error "the provided hostname could not be resolved '$hostname'" -ErrorAction Stop
  }

  $vmRootLocation = Join-Path "\\$($testedHostname.Address)" "\C$\"
  
  Write-Host "opening Windows Explorer at '$vmRootLocation' using 'local\administrator' credentials!"
  explorer /root,$vmRootLocation
  
  # handle the security prompt to enter username and password
  if(FindWindow("Windows Security")) {
    Start-Sleep -Milliseconds 250
    [System.Windows.Forms.SendKeys]::SendWait('local\administrator{TAB}')
    [System.Windows.Forms.SendKeys]::SendWait('Password1{ENTER}')
  }
  
  
  Write-Host "done!"
} 

open Windows Explorer on a remote location

Open SQL Server Management Studio or Profiler, using different user credentials. Useful if you want to login using Windows Authentication.

<#
.SYNOPSIS
  Opens a local instance of the selected SQL tools, using a 'local\administrator' credentials
.NOTES
  Useful for profiling Go Lab environments since 'local\administrator' is the default local administrator of those machines
#> 

Param([Switch] $SqlProfiler)

Process 
{
  # a new Command Prompt Window should be opened with this title
  $newCmdlineWindowTitle = "C:\Windows\System32\cmd.exe"
  
  # import required assemblies
  Add-Type -AssemblyName Microsoft.VisualBasic
  Add-Type -AssemblyName System.Windows.Forms


  Start-Process "cmd.exe"

  Start-Sleep -Milliseconds 1000
  [Microsoft.VisualBasic.Interaction]::AppActivate($newCmdlineWindowTitle)
  
  if($SqlProfiler) {
    # open SQL Server Profiler
    Write-Output "about to open SQL Server Profiler"
    [System.Windows.Forms.SendKeys]::SendWait('runas /netonly /user:local\administrator "C:\Program Files {(}x86{)}\Microsoft SQL Server\110\Tools\Binn\PROFILER.EXE"{ENTER}')
  } 
  else {  
    # open SQL Server Management Studio
    Write-Output "about to open SQL Server Management Studio"
    [System.Windows.Forms.SendKeys]::SendWait('runas /netonly /user:local\administrator "C:\Program Files {(}x86{)}\Microsoft SQL Server\110\Tools\Binn\ManagementStudio\Ssms.exe"{ENTER}')
  }

  Start-Sleep -Milliseconds 500
  [System.Windows.Forms.SendKeys]::SendWait('Password1{ENTER}')

  # close command prompt window
  Start-Sleep -Milliseconds 500
  [Microsoft.VisualBasic.Interaction]::AppActivate($newCmdlineWindowTitle)
  [System.Windows.Forms.SendKeys]::SendWait('exit{ENTER}')

  
  Write-Host "done!"   
} 

open SQL Server using a different user account

You can also checkout this script in Github by following this link. I hope this scripts are useful to you, just be careful and don't leave any personal passwords in plain text!