Skip to content

Instantly share code, notes, and snippets.

@tsgiannis
Last active March 13, 2025 09:42
Show Gist options
  • Save tsgiannis/05f596cf491bcff3ed2644a3f4cc9d5b to your computer and use it in GitHub Desktop.
Save tsgiannis/05f596cf491bcff3ed2644a3f4cc9d5b to your computer and use it in GitHub Desktop.
Easy Laps Password retriever
#### START ELEVATE TO ADMIN #####
param(
[Parameter(Mandatory=$false)]
[switch]$shouldAssumeToBeElevated,
[Parameter(Mandatory=$false)]
[String]$workingDirOverride
)
# If parameter is not set, we are propably in non-admin execution. We set it to the current working directory so that
# the working directory of the elevated execution of this script is the current working directory
if(-not($PSBoundParameters.ContainsKey('workingDirOverride')))
{
$workingDirOverride = (Get-Location).Path
}
function Test-Admin {
$currentUser = New-Object Security.Principal.WindowsPrincipal $([Security.Principal.WindowsIdentity]::GetCurrent())
$currentUser.IsInRole([Security.Principal.WindowsBuiltinRole]::Administrator)
}
# If we are in a non-admin execution. Execute this script as admin
if ((Test-Admin) -eq $false) {
if ($shouldAssumeToBeElevated) {
Write-Output "Elevating did not work :("
} else {
# vvvvv add `-noexit` here for better debugging vvvvv
Start-Process powershell.exe -Verb RunAs -ArgumentList ('-noprofile -file "{0}" -shouldAssumeToBeElevated -workingDirOverride "{1}"' -f ($myinvocation.MyCommand.Definition, "$workingDirOverride"))
}
exit
}
Set-Location "$workingDirOverride"
##### END ELEVATE TO ADMIN #####
# Add actual commands to be executed in elevated mode here:
Write-Output "I get executed in an admin PowerShell"
# Function to check and set execution policy with admin elevation if needed
function Ensure-ExecutionPolicy {
$currentPolicy = Get-ExecutionPolicy -Scope Process
if ($currentPolicy -ne 'Bypass') {
# Check if running as admin
if (-not ([Security.Principal.WindowsPrincipal][Security.Principal.WindowsIdentity]::GetCurrent()).IsInRole([Security.Principal.WindowsBuiltInRole] "Administrator")) {
# Request admin elevation
$scriptPath = $MyInvocation.MyCommand.Path
Start-Process powershell.exe -Verb RunAs -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$scriptPath`""
exit
} else {
# Set execution policy if running as admin
try {
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force -ErrorAction Stop
Write-Host "Execution policy set to Bypass."
} catch {
Write-Host "Failed to set execution policy: $_"
exit 1
}
}
}
}
# Check and set execution policy
Ensure-ExecutionPolicy
# Ensure we're running as PowerShell (after execution policy is set)
if ($Host.Name -ne 'ConsoleHost') {
# If running from Explorer (double-click), relaunch as PowerShell
$scriptPath = $MyInvocation.MyCommand.Path
Start-Process powershell.exe -ArgumentList "-NoProfile -ExecutionPolicy Bypass -File `"$scriptPath`"" -NoNewWindow
exit
}
# Hide the console window when running as a GUI application
Add-Type -Name Window -Namespace Console -MemberDefinition '
[DllImport("Kernel32.dll")]
public static extern IntPtr GetConsoleWindow();
[DllImport("user32.dll")]
public static extern bool ShowWindow(IntPtr hWnd, int nCmdShow);
'
$consolePtr = [Console.Window]::GetConsoleWindow()
[void][Console.Window]::ShowWindow($consolePtr, 0) # 0 = hide
# Import necessary assemblies for Windows Forms
Add-Type -AssemblyName System.Windows.Forms
Add-Type -AssemblyName System.Drawing
# Enable visual styles for modern UI
[System.Windows.Forms.Application]::EnableVisualStyles()
# Set execution policy for the current session
try {
Set-ExecutionPolicy -ExecutionPolicy Bypass -Scope Process -Force -ErrorAction SilentlyContinue
} catch {
# Continue even if this fails
}
# Create the form
$form = New-Object System.Windows.Forms.Form
$form.Text = "LAPS Password Viewer"
$form.Size = New-Object System.Drawing.Size(500, 450)
$form.StartPosition = [System.Windows.Forms.FormStartPosition]::CenterScreen
$form.BackColor = [System.Drawing.Color]::White
$form.Icon = [System.Drawing.SystemIcons]::Shield
# Create a larger font for better UI look
$font = New-Object System.Drawing.Font("Segoe UI", 12)
$largeFont = New-Object System.Drawing.Font("Segoe UI", 14, [System.Drawing.FontStyle]::Bold)
$titleFont = New-Object System.Drawing.Font("Segoe UI", 16, [System.Drawing.FontStyle]::Bold)
# Create title label
$titleLabel = New-Object System.Windows.Forms.Label
$titleLabel.Text = "LAPS Password Viewer"
$titleLabel.Location = New-Object System.Drawing.Point(125, 20)
$titleLabel.Size = New-Object System.Drawing.Size(250, 30)
$titleLabel.Font = $titleFont
$titleLabel.ForeColor = [System.Drawing.Color]::FromArgb(0, 120, 215)
$form.Controls.Add($titleLabel)
# Create a label for the computer name
$computerLabel = New-Object System.Windows.Forms.Label
$computerLabel.Text = "Enter Computer Name:"
$computerLabel.Location = New-Object System.Drawing.Point(150, 64)
$computerLabel.Size = New-Object System.Drawing.Size(200, 30)
$computerLabel.Font = $font
$form.Controls.Add($computerLabel)
# Create a text box for the computer name
$computerNameBox = New-Object System.Windows.Forms.TextBox
$computerNameBox.Location = New-Object System.Drawing.Point(150, 92)
$computerNameBox.Size = New-Object System.Drawing.Size(300, 30)
$computerNameBox.Font = $font
$computerNameBox.Text = [System.Environment]::MachineName # Pre-populate with current machine name
$computerNameBox.ReadOnly = $false # Make sure it's editable
$computerNameBox.Enabled = $true # Make sure it's enabled
$computerNameBox.TextAlign = 'Left' # Ensure text starts at the left
$form.Controls.Add($computerNameBox)
# Create a label to display the password (larger)
$passwordLabel = New-Object System.Windows.Forms.Label
$passwordLabel.Location = New-Object System.Drawing.Point(20, 130)
$passwordLabel.Size = New-Object System.Drawing.Size(450, 40)
$passwordLabel.Font = $largeFont
$passwordLabel.AutoSize = $true
$form.Controls.Add($passwordLabel)
# Create a label to display the expiration information
$expirationLabel = New-Object System.Windows.Forms.Label
$expirationLabel.Location = New-Object System.Drawing.Point(20, 180)
$expirationLabel.Size = New-Object System.Drawing.Size(450, 30)
$expirationLabel.Font = $font
$form.Controls.Add($expirationLabel)
# Create a button to get the password
$getPasswordButton = New-Object System.Windows.Forms.Button
$getPasswordButton.Text = "Get Password"
$getPasswordButton.Location = New-Object System.Drawing.Point(150, 220)
$getPasswordButton.Size = New-Object System.Drawing.Size(200, 40)
$getPasswordButton.Font = $font
$getPasswordButton.BackColor = [System.Drawing.Color]::FromArgb(120, 120, 215)
$getPasswordButton.ForeColor = [System.Drawing.Color]::White
$getPasswordButton.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
$getPasswordButton.FlatAppearance.BorderSize = 0
$getPasswordButton.Enabled = $true
$form.Controls.Add($getPasswordButton)
# Create a button to save password to file
$saveToFileButton = New-Object System.Windows.Forms.Button
$saveToFileButton.Text = "Save Password to Text File"
$saveToFileButton.Location = New-Object System.Drawing.Point(150, 270)
$saveToFileButton.Size = New-Object System.Drawing.Size(200, 40)
$saveToFileButton.Font = $font
$saveToFileButton.BackColor = [System.Drawing.Color]::FromArgb(0, 120, 215)
$saveToFileButton.ForeColor = [System.Drawing.Color]::White
$saveToFileButton.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
$saveToFileButton.FlatAppearance.BorderSize = 0
$saveToFileButton.Enabled = $false
$form.Controls.Add($saveToFileButton)
# Create a button to enter credentials (initially visible)
$credentialsButton = New-Object System.Windows.Forms.Button
$credentialsButton.Text = "Enter Credentials"
$credentialsButton.Location = New-Object System.Drawing.Point(150, 150)
$credentialsButton.Size = New-Object System.Drawing.Size(200, 40)
$credentialsButton.Font = $font
$credentialsButton.BackColor = [System.Drawing.Color]::FromArgb(0, 120, 215)
$credentialsButton.ForeColor = [System.Drawing.Color]::White
$credentialsButton.FlatStyle = [System.Windows.Forms.FlatStyle]::Flat
$credentialsButton.FlatAppearance.BorderSize = 0
$form.Controls.Add($credentialsButton)
# Create a status label
$statusLabel = New-Object System.Windows.Forms.Label
$statusLabel.Location = New-Object System.Drawing.Point(20, 320)
$statusLabel.Size = New-Object System.Drawing.Size(450, 30)
$statusLabel.Font = $font
$statusLabel.TextAlign = [System.Drawing.ContentAlignment]::MiddleCenter
$statusLabel.ForeColor = [System.Drawing.Color]::Green
$form.Controls.Add($statusLabel)
# Hide the rest of the UI elements initially
$computerLabel.Visible = $false
$computerNameBox.Visible = $false
$expirationLabel.Visible = $false
$passwordLabel.Visible = $false
$saveToFileButton.Visible = $false
$getPasswordButton.Visible = $false
# Create a global variable for the user credentials
$global:userCredentials = $null
$global:currentPassword = $null
# Function to get credentials
$credentialsButton.Add_Click({
# Ask for credentials
$userCredential = Get-Credential -Message "Enter your domain credentials to retrieve LAPS passwords"
if ($userCredential -eq $null) {
return
}
$global:userCredentials = $userCredential
# Once credentials are entered, show the rest of the UI
$credentialsButton.Visible = $false
$computerLabel.Visible = $true
$computerNameBox.Visible = $true
$computerNameBox.ReadOnly = $false
$computerNameBox.Enabled = $true
$expirationLabel.Visible = $true
$passwordLabel.Visible = $true
$saveToFileButton.Visible = $true
$getPasswordButton.Visible = $true
# Set focus to the computer name text box
$computerNameBox.Focus()
})
# Create a progress bar to indicate background work
$progressBar = New-Object System.Windows.Forms.ProgressBar
$progressBar.Location = New-Object System.Drawing.Point(20, 350)
$progressBar.Size = New-Object System.Drawing.Size(450, 20)
$progressBar.Style = [System.Windows.Forms.ProgressBarStyle]::Marquee
$progressBar.Visible = $false
$form.Controls.Add($progressBar)
# Function to get the script directory
function Get-ScriptDirectory {
$scriptPath = $MyInvocation.MyCommand.Path
if ($scriptPath) {
Split-Path $scriptPath
} else {
$PWD.Path
}
}
# Enter key in computer name box triggers Get Password
$computerNameBox.Add_KeyDown({
if ($_.KeyCode -eq [System.Windows.Forms.Keys]::Enter) {
$getPasswordButton.PerformClick()
$_.SuppressKeyPress = $true
}
})
$getPasswordButton.Add_Click({
# Check if credentials are entered
if ($global:userCredentials -eq $null) {
[System.Windows.Forms.MessageBox]::Show("Please enter credentials to run the command.", "Error")
return
}
# Retrieve the computer name from the input box
$computerName = $computerNameBox.Text
# Check if the user entered a computer name
if ([string]::IsNullOrEmpty($computerName)) {
[System.Windows.Forms.MessageBox]::Show("Please enter a valid computer name.", "Error")
return
}
# Disable button to prevent multiple clicks
$getPasswordButton.Enabled = $false
$progressBar.Visible = $true
$statusLabel.Text = "Retrieving password..."
$statusLabel.ForeColor = [System.Drawing.Color]::Blue
# Update the UI
[System.Windows.Forms.Application]::DoEvents()
# Run in the current session
try {
# Suppress the module import error by redirecting error stream
$ErrorActionPreference = 'SilentlyContinue'
$null = Import-Module AdmPwd.PS 2>$null
$ErrorActionPreference = 'Continue'
# Get the LAPS password
$lapsPasswordData = Get-LapsADPassword -Identity $computerName -AsPlainText -Credential $global:userCredentials
if ($lapsPasswordData) {
$password = $lapsPasswordData.Password
$expirationTimestamp = $lapsPasswordData.ExpirationTimestamp
# Store password in global variable
$global:currentPassword = $password
# Calculate expiration details
$expirationDate = [datetime]::Parse($expirationTimestamp)
$daysUntilExpiration = ($expirationDate - (Get-Date)).Days
$expirationText = "This password will expire in $daysUntilExpiration days on $expirationDate"
# Update UI
$expirationLabel.Text = $expirationText
$passwordLabel.Text = "Password: $password"
# Enable save to file button
$saveToFileButton.Enabled = $true
# Automatically copy password to clipboard
Set-Clipboard -Value $password
# Update status
$statusLabel.Text = "Password copied to clipboard!"
$statusLabel.ForeColor = [System.Drawing.Color]::Green
} else {
$statusLabel.Text = "Failed to retrieve password."
$statusLabel.ForeColor = [System.Drawing.Color]::Red
[System.Windows.Forms.MessageBox]::Show("Failed to retrieve the password. Ensure LAPS is configured properly.", "Error")
}
} catch {
$statusLabel.Text = "Error retrieving password."
$statusLabel.ForeColor = [System.Drawing.Color]::Red
[System.Windows.Forms.MessageBox]::Show("Error retrieving password: $_", "Error")
}
# Re-enable UI elements
$progressBar.Visible = $false
$getPasswordButton.Enabled = $true
})
# Function to save password to file
$saveToFileButton.Add_Click({
if ($global:currentPassword -ne $null) {
$computerName = $computerNameBox.Text
$scriptDir = Get-ScriptDirectory
$fileName = "$scriptDir\${computerName}_password.txt"
try {
$fileContent = "Computer: $computerName`r`nPassword: $($global:currentPassword)`r`n$($expirationLabel.Text)"
Set-Content -Path $fileName -Value $fileContent
$statusLabel.Text = "Password saved to file!"
$statusLabel.ForeColor = [System.Drawing.Color]::Green
[System.Windows.Forms.MessageBox]::Show("Password saved to file: $fileName", "Success")
} catch {
$statusLabel.Text = "Error saving password to file."
$statusLabel.ForeColor = [System.Drawing.Color]::Red
[System.Windows.Forms.MessageBox]::Show("Error saving password to file: $_", "Error")
}
} else {
[System.Windows.Forms.MessageBox]::Show("No password available to save.", "Error")
}
})
# Show the form
[void]$form.ShowDialog()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment