N2C.GuacAdmin.psm1
|
#Requires -Version 5.1 <# .SYNOPSIS N2C.GuacAdmin - administrative PowerShell module for Apache Guacamole 1.6.x. .DESCRIPTION This module administers a deployed Apache Guacamole instance through the Guacamole REST API and (in later phases) the Guacamole protocol over WebSocket tunnels. Design notes: - Authentication state is carried by [N2C_GuacAdmin_GuacSession] objects (created by New-GuacSession), never by module-scope globals. A single module-scope session-state dictionary provides a "default session" for cmdlets (the -CmsSession pattern), so multiple instances can be worked with in one process. - All REST traffic goes through the private Invoke-GuacRest transport, which parses Guacamole APIError bodies and converts every failure into a terminating N2C_GuacAdmin_GuacRestException. No cmdlet returns $false on API failure. - Compatible with Windows PowerShell 5.1 and PowerShell 7.x on Windows/Linux/macOS. No PowerShell 6+ only APIs are used. Reference implementation facts are traced to the Apache Guacamole 1.6.0 source (see ANALYSIS/guacamole-client-1.6.0/ in the repository root). #> # NOTE: Set-StrictMode is intentionally not used. API responses are untrusted # JSON parsed with ConvertFrom-Json; strict property access on those objects # would turn missing fields into confusing runtime errors. API response fields # are accessed defensively instead (see ConvertFrom-GuacErrorBody). # Force TLS 1.2 on Windows PowerShell 5.1 (the .NET Framework default is TLS 1.0, # which modern Guacamole deployments may reject). if ($PSVersionTable.PSVersion.Major -lt 6) { [System.Net.ServicePointManager]::SecurityProtocol = [System.Net.ServicePointManager]::SecurityProtocol -bor [System.Net.SecurityProtocolType]::Tls12 } # Type definitions ([N2C_GuacAdmin_GuacSession], [N2C_GuacAdmin_GuacRestException]) # live in Types.ps1, which the module manifest lists in ScriptsToProcess. Those # scripts run in a caller-visible scope, so the classes resolve to the same # type in both the module and the caller (verified empirically on PowerShell # 5.1/7.x: a class defined in the .psm1 instead is module-scope only and cannot # be cast across the module boundary). # The class types are captured as module-scope variables exactly once, at load # time. Runtime name resolution of the class identifiers inside module # functions is unreliable in some host scopes (empirically observed under # Pester 5.7.1: `New-Object N2C_GuacAdmin_GuacRestException` fails with # TypeNotFound inside the module even though the import itself succeeded), so # every construction and every runtime type test in the module goes through # these variables instead of type literals. $script:GuacSessionType = [N2C_GuacAdmin_GuacSession] $script:GuacActiveSessionType = [N2C_GuacAdmin_GuacActiveSession] $script:GuacInstructionType = [N2C_GuacAdmin_GuacInstruction] $script:GuacRestExceptionType = [N2C_GuacAdmin_GuacRestException] # Module session state: keyed by normalized server URI. This is the ONLY module # scope state the module keeps (no token/server globals), and it exists solely # to provide the "default session" resolution for the -Session parameter. $script:GuacSessionState = [System.Collections.Generic.Dictionary[string, object]]::new() # Cached capability set of the running Invoke-WebRequest implementation, used to # plumb parameters that differ between Windows PowerShell 5.1 and PowerShell 7.x # (-UseBasicParsing, -Certificate vs -PfxCertificate, -NoProxy). $script:GuacIwrCapabilities = [System.Collections.Generic.HashSet[string]]::new() foreach ($name in (Get-Command -Name Invoke-WebRequest).Parameters.Keys) { [void]$script:GuacIwrCapabilities.Add($name) } # Load private functions, then public functions. $privatePath = Join-Path -Path $PSScriptRoot -ChildPath 'Private' Get-ChildItem -Path $privatePath -Filter '*.ps1' -File | ForEach-Object { . $_.FullName } $publicPath = Join-Path -Path $PSScriptRoot -ChildPath 'Public' Get-ChildItem -Path $publicPath -Filter '*.ps1' -File | ForEach-Object { . $_.FullName } Export-ModuleMember -Function @( 'New-GuacSession', 'Get-GuacSession', 'Remove-GuacSession', 'Test-GuacSession', 'Set-GuacDataSource', 'Get-GuacConnection', 'New-GuacConnection', 'Update-GuacConnection', 'Remove-GuacConnection', 'Get-GuacConnectionGroup', 'Get-GuacConnectionGroupTree', 'New-GuacConnectionGroup', 'Update-GuacConnectionGroup', 'Remove-GuacConnectionGroup', 'Get-GuacUser', 'New-GuacUser', 'Update-GuacUser', 'Remove-GuacUser', 'Set-GuacUserPassword', 'Get-GuacUserGroup', 'New-GuacUserGroup', 'Update-GuacUserGroup', 'Remove-GuacUserGroup', 'Get-GuacSharingProfile', 'New-GuacSharingProfile', 'Update-GuacSharingProfile', 'Remove-GuacSharingProfile', 'Add-GuacPermission', 'Remove-GuacPermission', 'Add-GuacUserGroupMember', 'Remove-GuacUserGroupMember', 'Add-GuacUserGroupChildGroup', 'Remove-GuacUserGroupChildGroup', 'Get-GuacHistoryConnections', 'Get-GuacHistoryUsers', 'Get-GuacSchema', 'Get-GuacProtocol', 'Get-GuacActiveConnection', 'Stop-GuacActiveConnection', 'Get-GuacSharingCredential', 'Get-GuacTunnel', 'Get-GuacLanguage', 'Get-GuacPatches', 'Get-GuacExtension', 'New-GuacActiveSession', 'Send-GuacInstruction', 'Receive-GuacInstruction', 'Remove-GuacActiveSession' ) |