Public/New-GuacConnection.ps1
|
function New-GuacConnection { <# .SYNOPSIS Creates a new Guacamole connection. .DESCRIPTION Creates a connection in the per-data-source UserContext by POSTing an APIConnection body (DirectoryResource.createObject). The body follows the APIConnection shape: name, protocol, parameters (a map of parameter name to value), parentIdentifier (the containing connection group; "ROOT" for the root group), and attributes. The server assigns the identifier and returns the created object. The connection body may be supplied as a hashtable/ordered hashtable or a PSCustomObject (also from the pipeline via -InputObject). The "identifier" property, if present, is ignored: the server assigns it. Alternatively, -Name/-Protocol/-Parameters/-Parent construct the body directly. Requires the CREATE_CONNECTION system permission (or ADMINISTER) on the server. Reference (Apache Guacamole 1.6.0): - guacamole/src/main/java/org/apache/guacamole/rest/directory/DirectoryResource.java (createObject: @POST on the directory, returns the created object) - guacamole/src/main/java/org/apache/guacamole/rest/connection/APIConnection.java (name, protocol, parameters, parentIdentifier, attributes) - guacamole/src/main/java/org/apache/guacamole/rest/session/UserContextResource.java (@Path("connections")) .EXAMPLE New-GuacConnection -Name 'db-server' -Protocol 'ssh' ` -Parameters @{ hostname = 'db.example.com'; port = '22' } ` -Parent 'ROOT' .EXAMPLE New-GuacConnection -InputObject @{ name = 'print-server' protocol = 'rdp' parameters = @{ hostname = 'print.example.com'; port = '3389' } } -Parent 'ROOT' #> [CmdletBinding(SupportsShouldProcess = $true)] [OutputType([PSCustomObject])] 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, ValueFromPipelineByPropertyName = $true, ValueFromPipeline = $true)] [AllowNull()] [object] $InputObject, [Parameter(Mandatory = $false)] [AllowEmptyString()] [string] $Name = [string]::Empty, [Parameter(Mandatory = $false)] [AllowEmptyString()] [string] $Protocol = [string]::Empty, [Parameter(Mandatory = $false)] [AllowNull()] [object] $Parameters, [Parameter(Mandatory = $false)] [AllowEmptyString()] [string] $Parent = [string]::Empty, [Parameter(Mandatory = $false)] [AllowNull()] [object] $Attributes ) begin { $pendingBody = $null if (-not [string]::IsNullOrWhiteSpace($Name)) { $pendingBody = [ordered]@{} $pendingBody['name'] = $Name if (-not [string]::IsNullOrWhiteSpace($Protocol)) { $pendingBody['protocol'] = $Protocol } if ($null -ne $Parameters) { $pendingBody['parameters'] = $Parameters } } } process { if ($null -ne $InputObject) { $pendingBody = $InputObject } } end { if ($null -eq $pendingBody) { throw ($script:GuacRestExceptionType::new( 'New-GuacConnection requires a connection body: supply -Name (optionally with -Protocol/-Parameters) or -InputObject.' )) } if ([string]::IsNullOrWhiteSpace($Parent)) { $Parent = 'ROOT' } $ctx = Resolve-GuacSessionContext -Session $Session -Server $Server -DataSource $DataSource -CmdletName 'New-GuacConnection' $body = ConvertTo-GuacEntityBody -Object $pendingBody -ExcludeProperty @('identifier', 'Identifier') $body['parentIdentifier'] = $Parent # Determine the protocol for schema-based parameter completion $connectionProtocol = [string]$body['protocol'] if ([string]::IsNullOrWhiteSpace($connectionProtocol) -and -not [string]::IsNullOrWhiteSpace($Protocol)) { $connectionProtocol = $Protocol $body['protocol'] = $connectionProtocol } # If a protocol is known, fetch its schema and ensure all required # parameter fields are present (defaulting to empty string). This # matches the behavior of the Guacamole web UI and is required by # some server configurations that expect the complete parameter set. if (-not [string]::IsNullOrWhiteSpace($connectionProtocol)) { $defaultParams = $null try { # Directly fetch the protocol schema to avoid type resolution issues # when calling Get-GuacProtocol from within the same module. $schemaPath = Resolve-GuacContextUrl -DataSource $ctx['DataSource'] -Collection 'schema' -SubPath 'protocols' $protocolsMap = Invoke-GuacRest -Server $ctx['Server'] -Token $ctx['Token'] -Method GET -Path $schemaPath if ($null -ne $protocolsMap -and $protocolsMap.PSObject.Properties[$connectionProtocol]) { $protocolInfo = $protocolsMap.$connectionProtocol if ($null -ne $protocolInfo) { # Collect all field names from the protocol's connection forms $fieldNames = @() foreach ($form in @($protocolInfo.connectionForms)) { if ($null -ne $form -and $form.PSObject.Properties['fields']) { foreach ($f in @($form.fields)) { if ([string]::IsNullOrWhiteSpace([string]$f) -eq $false) { $fieldNames += [string]$f } } } } # Build default parameters with empty strings $defaultParams = @{} foreach ($fieldName in $fieldNames) { $defaultParams[$fieldName] = '' } } } } catch { Write-Warning ('Failed to fetch protocol schema for "{0}": {1}. Using provided parameters only.' -f ($connectionProtocol, $_.Exception.Message)) } # Merge: defaults first, then user-provided parameters override $userParams = $null if ($null -ne $body['parameters']) { $userParams = $body['parameters'] } elseif ($null -ne $Parameters) { $userParams = $Parameters } $mergedParams = @{} if ($null -ne $defaultParams) { foreach ($key in $defaultParams.Keys) { $mergedParams[$key] = $defaultParams[$key] } } if ($null -ne $userParams) { foreach ($key in $userParams.Keys) { $mergedParams[$key] = $userParams[$key] } } $body['parameters'] = $mergedParams } # Always include an attributes object (empty if not provided) if ($null -ne $Attributes) { $body['attributes'] = $Attributes } elseif ($null -eq $body['attributes']) { $body['attributes'] = @{} } $whatIfTarget = 'connection' if (-not [string]::IsNullOrWhiteSpace([string]$body['name'])) { $whatIfTarget = ('connection "{0}"' -f $body['name']) } if (-not ($PSCmdlet.ShouldProcess($whatIfTarget, 'Create Guacamole connection (POST connections)'))) { return } return (Invoke-GuacDirectory -Context $ctx -Collection 'connections' -Action 'Create' -Body $body) } } |