Files
elysium/Elysium.ps1
T
tomas.kracmar 5691463bd3 fix(Elysium): catch sub-script errors instead of crashing the menu
The menu loop had try/finally with no catch. Update-KHDB.ps1,
Test-WeakADPasswords.ps1, and Extract-NTHashes.ps1 all run under
$ErrorActionPreference = 'Stop' and re-throw on failure, so any
runtime error (bad credentials, unreachable DC, network failure)
propagated uncaught through the parent and killed the whole
orchestrator instead of returning to the menu. Wrapped the switch in
try/catch so a failed option reports the error and redisplays the
menu.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-29 11:52:13 +02:00

161 lines
6.0 KiB
PowerShell

##################################################
## ____ ___ ____ _____ _ _ _____ _____ ##
## / ___/ _ \| _ \| ____| | \ | | ____|_ _| ##
## | | | | | | |_) | _| | \| | _| | | ##
## | |__| |_| | _ <| |___ _| |\ | |___ | | ##
## \____\__\_\_| \_\_____(_)_| \_|_____| |_| ##
##################################################
## Project: Elysium ##
## File: Elysium.ps1 ##
## Version: 2.4.5 ##
## Support: support@cqre.net ##
##################################################
<#
.SYNOPSIS
This is the main script for the Elysium tool for testing weak AD passwords.
.DESCRIPTION
Elysium.ps1 offers a menu to perform various actions:
1. Download/Update Known-Hashes Database (KHDB)
2. Test Weak AD Passwords
3. Extract and Send Current Hashes for KHDB Update
4. Uninstall the tool
5. Update Lithnet Password Protection store
6. Exit
#>
# Safer defaults
$ErrorActionPreference = 'Stop'
Set-StrictMode -Version Latest
# Define the path to the settings file
$settingsFilePath = Join-Path -Path $PSScriptRoot -ChildPath "ElysiumSettings.txt"
# Check if the settings file exists
if (-Not (Test-Path $settingsFilePath)) {
Write-Host "ElysiumSettings.txt does not exist. Please ensure your settings file is in the correct location."
exit
} else {
Write-Host "ElysiumSettings.txt found."
}
# The passphrase is persisted DPAPI-protected (current user + machine) via ConvertFrom-SecureString,
# never in plaintext, so it's only prompted for once per user/machine and never echoed to the console.
$storedPassphrase = [System.Environment]::GetEnvironmentVariable("ELYSIUM_PASSPHRASE", [System.EnvironmentVariableTarget]::User)
$havePassphrase = $false
if (-not [string]::IsNullOrEmpty($storedPassphrase)) {
try {
[void](ConvertTo-SecureString -String $storedPassphrase -ErrorAction Stop)
$havePassphrase = $true
Write-Host "Passphrase found in environment variables."
} catch {
Write-Warning "Stored passphrase is not in the expected protected format (leftover from an older Elysium version?). Re-enter it."
}
}
if (-not $havePassphrase) {
Write-Host "No passphrase found in environment variables."
$securePassphrase = Read-Host "Please enter your passphrase" -AsSecureString
[System.Environment]::SetEnvironmentVariable("ELYSIUM_PASSPHRASE", (ConvertFrom-SecureString -SecureString $securePassphrase), [System.EnvironmentVariableTarget]::User)
Write-Host "Passphrase stored (DPAPI-protected) as environment variable 'ELYSIUM_PASSPHRASE'."
}
function Start-OrchestratorTranscript {
param([string]$BasePath)
try {
$logsDir = Join-Path -Path $BasePath -ChildPath 'Reports/logs'
if (-not (Test-Path $logsDir)) { New-Item -Path $logsDir -ItemType Directory -Force | Out-Null }
$ts = Get-Date -Format 'yyyyMMdd-HHmmss'
$logPath = Join-Path -Path $logsDir -ChildPath "orchestrator-$ts.log"
Start-Transcript -Path $logPath -Force | Out-Null
} catch {
Write-Warning "Could not start transcript: $($_.Exception.Message)"
}
}
function Stop-OrchestratorTranscript { try { Stop-Transcript | Out-Null } catch {} }
function Invoke-WindowsPowerShellScript {
param([string]$ScriptPath)
$powershellCmd = Get-Command -Name 'powershell.exe' -ErrorAction SilentlyContinue
if (-not $powershellCmd) {
throw "Windows PowerShell (powershell.exe) was not found. Install it or run the script from a Desktop edition session."
}
$args = @('-NoLogo', '-NoProfile', '-ExecutionPolicy', 'Bypass', '-File', $ScriptPath)
& $powershellCmd.Path @args
$exitCode = $LASTEXITCODE
if ($exitCode -ne 0) {
throw ("Windows PowerShell script '{0}' exited with code {1}." -f $ScriptPath, $exitCode)
}
}
function Show-Menu {
param (
[string]$Title = 'Elysium Tool Main Menu'
)
Clear-Host
Write-Host "================ $Title ================"
Write-Host "1: Download/Update Known-Hashes Database (KHDB)"
Write-Host "2: Test Weak AD Passwords"
Write-Host "3: Extract and Send Current Hashes for KHDB Update"
Write-Host "4: Update Lithnet Password Protection Store"
Write-Host "5: Uninstall"
Write-Host "6: Exit"
}
Start-OrchestratorTranscript -BasePath $PSScriptRoot
try {
do {
Show-Menu
$userSelection = Read-Host "Please make a selection"
try {
switch ($userSelection) {
'1' {
Write-Host "Downloading KHDB..."
& (Join-Path -Path $PSScriptRoot -ChildPath 'Update-KHDB.ps1')
}
'2' {
Write-Host "Testing Weak AD Passwords..."
$testScript = Join-Path -Path $PSScriptRoot -ChildPath 'Test-WeakADPasswords.ps1'
if ($PSVersionTable.PSEdition -eq 'Desktop') {
& $testScript
} else {
Invoke-WindowsPowerShellScript -ScriptPath $testScript
}
}
'3' {
Write-Host "Extracting and Sending Current Hashes..."
$extractScript = Join-Path -Path $PSScriptRoot -ChildPath 'Extract-NTHashes.ps1'
if ($PSVersionTable.PSEdition -eq 'Desktop') {
& $extractScript
} else {
Invoke-WindowsPowerShellScript -ScriptPath $extractScript
}
}
'4' {
Write-Host "Updating Lithnet Password Protection store..."
& (Join-Path -Path $PSScriptRoot -ChildPath 'Update-LithnetStore.ps1')
}
'5' {
Write-Host "Uninstalling..."
& (Join-Path -Path $PSScriptRoot -ChildPath 'Uninstall.ps1')
}
'6' {
Write-Host "Exiting..."
# end loop; transcript will be stopped after the loop
$userSelection = '6'
}
default {
Write-Host "Invalid selection, please try again."
}
}
} catch {
Write-Error ("An error occurred while running the selected option: {0}" -f $_.Exception.Message)
}
pause
} while ($userSelection -ne '6')
} finally {
Stop-OrchestratorTranscript
}