Public/New-GuacActiveSession.ps1
|
function New-GuacActiveSession { <# .SYNOPSIS Opens a new Guacamole active session (interactive connection). .DESCRIPTION Opens a WebSocket tunnel to the specified Guacamole connection or connection group and performs the full protocol handshake (select, args, size, audio, video, image, timezone, connect) to establish an active session. Returns a [N2C_GuacAdmin_GuacActiveSession] object containing the session ID and the live WebSocket connection for the instruction pump. Use Send-GuacInstruction and Receive-GuacInstruction to exchange instructions with the session. Use Remove-GuacActiveSession to gracefully disconnect. Reference (Apache Guacamole 1.6.0): - guacamole/src/main/java/org/apache/guacamole/tunnel/TunnelRequest.java (tunnel URL parameters) - guacamole/src/main/java/org/apache/guacamole/tunnel/websocket/WebSocketTunnel.java - guacamole-common/src/main/java/org/apache/guacamole/protocol/ConfiguredGuacamoleSocket.java (handshake sequence) .EXAMPLE $session = New-GuacSession -Server https://guac.example.com/guacamole -Credential $cred $active = New-GuacActiveSession -Session $session -ConnectionId 'abc-123' # Use the session... Remove-GuacActiveSession -Session $active #> [CmdletBinding()] [OutputType([N2C_GuacAdmin_GuacActiveSession])] param ( [Parameter(Mandatory = $false)] [AllowNull()] [N2C_GuacAdmin_GuacSession] $Session, [Parameter(Mandatory = $false)] [AllowEmptyString()] [string] $Server = [string]::Empty, [Parameter(Mandatory = $false)] [AllowEmptyString()] [string] $DataSource = [string]::Empty, [Parameter(Mandatory = $false)] [AllowEmptyString()] [string] $ConnectionId = [string]::Empty, [Parameter(Mandatory = $false)] [AllowEmptyString()] [string] $GroupId = [string]::Empty, [Parameter(Mandatory = $false)] [ValidateRange(64, 7680)] [int] $Width = 1024, [Parameter(Mandatory = $false)] [ValidateRange(64, 7680)] [int] $Height = 768, [Parameter(Mandatory = $false)] [ValidateRange(75, 300)] [int] $Dpi = 96, [Parameter(Mandatory = $false)] [AllowEmptyString()] [string] $Timezone = [string]::Empty, [Parameter(Mandatory = $false)] [AllowEmptyString()] [string[]] $AudioMimeTypes = @(), [Parameter(Mandatory = $false)] [AllowEmptyString()] [string[]] $VideoMimeTypes = @(), [Parameter(Mandatory = $false)] [AllowEmptyString()] [string[]] $ImageMimeTypes = @(), [Parameter(Mandatory = $false)] [AllowEmptyString()] [hashtable] $Arguments = @{}, [Parameter(Mandatory = $false)] [ValidateRange(5, 300)] [int] $HandshakeTimeoutSec = 30 ) # Resolve session $resolved = Resolve-GuacSessionContext -Session $Session -Server $Server -DataSource $DataSource -CmdletName 'New-GuacActiveSession' $sessionObj = $resolved.Session # Build the tunnel URL $tunnelUrl = New-GuacTunnelUrl -Server $sessionObj.Server ` -Token $sessionObj.Token ` -ConnectionId $ConnectionId ` -GroupId $GroupId ` -DataSource $sessionObj.DataSource ` -Width $Width -Height $Height -Dpi $Dpi ` -Timezone $Timezone ` -AudioMimeTypes $AudioMimeTypes ` -VideoMimeTypes $VideoMimeTypes ` -ImageMimeTypes $ImageMimeTypes Write-Verbose ("N2C.GuacAdmin: opening WebSocket tunnel to {0}" -f $tunnelUrl) # Open WebSocket connection with subprotocol "guacamole" $ws = New-Object System.Net.WebSockets.ClientWebSocket try { $ws.ConnectAsync([Uri]$tunnelUrl, [System.Threading.CancellationToken]::None).GetAwaiter().GetResult() Write-Verbose ("N2C.GuacAdmin: WebSocket connected, performing handshake") # Perform the protocol handshake $activeSession = Invoke-GuacProtocolHandshake -WebSocket $ws ` -Session $sessionObj ` -ConnectionId $ConnectionId ` -GroupId $GroupId ` -Width $Width -Height $Height -Dpi $Dpi ` -Timezone $Timezone ` -AudioMimeTypes $AudioMimeTypes ` -VideoMimeTypes $VideoMimeTypes ` -ImageMimeTypes $ImageMimeTypes ` -Arguments $Arguments ` -HandshakeTimeoutSec $HandshakeTimeoutSec return $activeSession } catch { # Close the WebSocket on failure if ($ws.State -eq [System.Net.WebSockets.WebSocketState]::Open) { try { [void]$ws.CloseAsync([System.Net.WebSockets.WebSocketCloseStatus]::NormalClosure, 'Handshake failed', [System.Threading.CancellationToken]::None).GetAwaiter().GetResult() } catch { # Ignore close errors } } throw } } |