Last active
March 13, 2025 09:42
-
-
Save tsgiannis/05f596cf491bcff3ed2644a3f4cc9d5b to your computer and use it in GitHub Desktop.
Easy Laps Password retriever
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
#### 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