Private/Test/Test-PowerShellEnvironment.ps1
|
function Test-PowerShellEnvironment { <# .SYNOPSIS Validates the PowerShell environment and returns diagnostic results. .DESCRIPTION Performs comprehensive validation of the PowerShell environment including: - Operating System (Windows only) - OS version (Windows 10 1607+/Server 2016+) - PowerShell version (5.1 or 7.4+) - PowerShell edition (Desktop vs Core) - Terminal environment (Windows Terminal recommended) - Output encoding (UTF-8 recommended) - Required and optional module availability Exits on critical failures (OS, OS version, or PowerShell version). Warns on non-critical issues (terminal, encoding, missing modules). Returns a hashtable containing all test results for diagnostic purposes. .INPUTS None. This function does not accept pipeline input. .OUTPUTS System.Collections.Hashtable Returns a hashtable with the following keys: - IsWindows: Boolean - Running on Windows OS - IsSupportedOS: Boolean - Running on supported Windows version - IsSupportedPS: Boolean - Running supported PowerShell version - IsPowerShellCore: Boolean - Running PowerShell Core/7+ (Core edition) - IsWindowsTerminal: Boolean - Running in Windows Terminal - IsUtf8: Boolean - Console output encoding is UTF-8 - AllModulesLoaded: Boolean - All required modules are loaded in session - MissingModules: Array - List of module names that are not loaded .EXAMPLE Test-PowerShellEnvironment Validates the environment and returns diagnostic hashtable. .EXAMPLE $env = Test-PowerShellEnvironment -Verbose if ($env.AllModulesLoaded) { # All required modules are loaded } else { Write-Host "Missing modules: $($env.MissingModules -join ', ')" } Stores diagnostic results and checks module load status. .EXAMPLE Test-PowerShellEnvironment | ConvertTo-Json Validates environment and outputs results as JSON for logging. .NOTES Critical failures (OS, OS version, PowerShell version) will cause the function to exit. Non-critical issues generate warnings but allow execution to continue. Module availability is checked but not automatically installed by this function. #> [CmdletBinding()] [OutputType([hashtable])] param ( ) #requires -Version 5.1 Write-Verbose "Starting PowerShell environment validation..." try { # Check Windows OS Write-Verbose "Checking if running on Windows..." $testIsWindows = Test-IsWindows if (-not $testIsWindows) { $errorRecord = [System.Management.Automation.ErrorRecord]::new( [System.Exception]::new('Locksmith 2 is only supported on Windows.'), 'UnsupportedOS', [System.Management.Automation.ErrorCategory]::InvalidOperation, $PSVersionTable.OS ) $PSCmdlet.ThrowTerminatingError($errorRecord) } $testIsSupportedOS = Test-IsSupportedOS if (-not $testIsSupportedOS) { $errorRecord = [System.Management.Automation.ErrorRecord]::new( [System.Exception]::new('Locksmith 2 is only supported on Windows 10 1607+/Server 2016+.'), 'UnsupportedOSVersion', [System.Management.Automation.ErrorCategory]::InvalidOperation, $PSVersionTable.OS ) $PSCmdlet.ThrowTerminatingError($errorRecord) } $testIsSupportedPS = Test-IsSupportedPS if (-not $testIsSupportedPS) { $errorRecord = [System.Management.Automation.ErrorRecord]::new( [System.Exception]::new('Locksmith 2 is only supported on Windows PowerShell 5.1 and PowerShell 7.4+.'), 'UnsupportedPSVersion', [System.Management.Automation.ErrorCategory]::InvalidOperation, $PSVersionTable.PSVersion ) $PSCmdlet.ThrowTerminatingError($errorRecord) } $testIsPowerShellCore = Test-IsPowerShellCore if (-not $testIsPowerShellCore) { Write-Warning 'Windows PowerShell detected. Locksmith 2 will run in headless mode. Interactive mode requires PowerShell 7.4+.' } $neededModules = @( 'PSCertutil', 'PwshSpectreConsole', 'PSWriteHTML' ) Write-Verbose "Modules to check: $($neededModules -join ', ')" $testIsWindowsTerminal = Test-IsWindowsTerminal if (-not $testIsWindowsTerminal) { Write-Warning 'Locksmith 2 is designed to work on Windows Terminal. Visual output may be degraded.' } $testIsUtf8 = Test-IsUtf8 if (-not $testIsUtf8) { Write-Warning "Console Output Encoding is not set to UTF-8 (CodePage 65001). Visual output may be degraded." } $missingModules = @() foreach ($module in $neededModules) { $isLoaded = Test-IsModuleLoaded -Name $module Write-Verbose "$module is loaded: $isLoaded" if (-not $isLoaded) { Write-Warning "Needed module '$module' is not loaded. Locksmith 2 will guide you through installation and importation." $missingModules += $module } } if ($missingModules) { $allModulesLoaded = $false } else { $allModulesLoaded = $true } $returnObject = [ordered]@{ IsWindows = $testIsWindows IsSupportedOS = $testIsSupportedOS IsSupportedPS = $testIsSupportedPS IsPowerShellCore = $testIsPowerShellCore IsWindowsTerminal = $testIsWindowsTerminal IsUtf8 = $testIsUtf8 AllModulesLoaded = $allModulesLoaded MissingModules = $missingModules } Write-Verbose "PowerShell environment validation complete." Write-Verbose "Returning diagnostic object with $($returnObject.Count) properties." $returnObject } catch { $errorRecord = [System.Management.Automation.ErrorRecord]::new( $_.Exception, 'EnvironmentValidationFailed', [System.Management.Automation.ErrorCategory]::NotSpecified, $null ) $PSCmdlet.ThrowTerminatingError($errorRecord) } } |