functions/distributed-engines/Test-TssDistributedEngineCloudAccess.ps1
function Test-TssDistributedEngineCloudAccess { <# .SYNOPSIS Validate network and firewall access to Secret Server Cloud from a device .DESCRIPTION Validate network and firewall access to Secret Server Cloud (SSC) from a device. The command validates port access for SSC and the Azure Service Bus host. This function would be used from your Distributed Engine to verify the proper outputbound access is in place for a Distributed Engine to communicate with SSC. .EXAMPLE $session = New-TssSession -SecretServer https://tenant.secretservercloud.com -Credential $ssCred Test-TssDistributedEngineCloudAccess -TssSession $session -TransportType AMQP -Timeout 30 Run Hostname and IP port test for SSC URL and Service Bus with ports 5671 and 5672 for AMQP, with a timeout of 30 seconds .EXAMPLE $session = New-TssSession -SecretServer https://tenant.secretservercloud.eu -Credential $ssCred Test-TssDistributedEngineCloudAccess -TssSession $session Run Hostname and IP port test for SSC URL and Service Bus with port 443 (Web Sockets), with a default timeout of 5 seconds .LINK https://thycotic-ps.github.io/thycotic.secretserver/commands/distributed-engines/Test-TssDistributedEngineCloudAccess .LINK https://github.com/thycotic-ps/thycotic.secretserver/blob/main/src/functions/distributed-engines/Test-TssDistributedEngineCloudAccess.ps1 .NOTES Requires TssSession object returned by New-TssSession Details on IP and Hostnames used: - https://docs.thycotic.com/ss/11.0.0/secret-server-setup/upgrading/ssc-ip-change-3-21#new_ip_addresses_and_hostnames - https://docs.thycotic.com/ss-arc/1.0.0/secret-server/secret-server-cloud #> [cmdletbinding()] [OutputType('Thycotic.PowerShell.DistributedEngines.CloudAccessResult')] param( # TssSession object created by New-TssSession for authentication [Parameter(Mandatory, ValueFromPipeline, Position = 0)] [Thycotic.PowerShell.Authentication.Session] $TssSession, # Azure ServiceBus Transport Type (Admin > Distributed Engine > Configuration tab), defaults to WebSockets [ValidateSet('Web Sockets', 'AMQP')] $TransportType = 'Web Sockets', # Timeout for connection test, defaults to 5 seconds [int] $Timeout = 5 ) begin { $tssParams = $PSBoundParameters } process { Get-TssInvocation $PSCmdlet.MyInvocation if ($tssParams.ContainsKey('TssSession') -and $TssSession.IsValidSession()) { $secretServerUrl = $TssSession.SecretServer $secretServerHost = ([uri]$TssSession.SecretServer).Host $tssSscDomains = . $SscDomains $tssSscDomainIps = . $sscDomainIps $tssServiceBusHosts = . $SscAzureServiceBusHosts switch ([string]$TransportType) { 'Web Sockets' { $testPortServiceBus = 443 } 'AMQP' { $testPortServiceBus = 5671,5672 } } $regionDomain = $tssSscDomains.Where({ $secretServerUrl -match $_.Domain }) $region = $regionDomain.Region $domain = $regionDomain.Domain Write-Verbose "Setting region to: $region" Write-Verbose "Host domain for Secret Server Cloud: $domain" $testSBHosts = $tssServiceBusHosts.Where({ $_.Domain -eq $domain }) $testDomainIPs = $tssSscDomainIps.Where({ $_.Domain -eq $domain }) $results = @() $ssTcp = [System.Net.Sockets.TcpClient]::new() $sscResult = [Thycotic.PowerShell.DistributedEngines.CloudAccessResult]@{ ItemName = 'Secret Server Cloud Domain' HostAddress = $secretServerHost Port = 443 Status = $null } Write-Verbose "Testing Secret Server Cloud Domain [$secretServerHost] on port [443]" if ($ssTcp.ConnectAsync($secretServerHost,443).Wait([timespan]::FromSeconds($Timeout))) { Write-Warning "Secret Server Cloud Domain test failed on port [443]" $sscResult.Status = 'Failed' } else { Write-Verbose "Secret Server Cloud Domain test successful on port [443]" $sscResult.Status = 'Successful' } $results += $sscResult $siteConnector = Search-TssDistributedEngineConnector -TssSession $TssSession if ($siteConnector) { foreach ($port in $testPortServiceBus) { $customerServiceBus = $siteConnector.Hostname Write-Verbose "Testing Customer Service Bus host [$CustomerServiceBus] on port [$port]" $cSbTcp = [System.Net.Sockets.TcpClient]::new() $cSbResult = [Thycotic.PowerShell.DistributedEngines.CloudAccessResult]@{ ItemName = 'Customer Service Bus Hostname' HostAddress = $customerServiceBus Port = $port Status = $null } if ($cSbTcp.ConnectAsync($customerServiceBus,$port).Wait([timespan]::FromSeconds($Timeout))) { Write-Warning "Service Bus Host test failed on port [$port]" $cSbResult.Status = 'Failed' } else { Write-Verbose "Service Bus Host test successful on port [$port]" $cSbResult.Status = 'Successful' } $results += $cSbResult <# Test Azure Service Bus Hostname connection #> foreach ($sbHost in $testSBHosts) { $currentSBResult = [Thycotic.PowerShell.DistributedEngines.CloudAccessResult]@{ ItemName = 'Azure Service Bus Hostname' HostAddress = $sbHost.HostAddress Port = $port Status = $null } $sbTcp = [System.Net.Sockets.TcpClient]::new() Write-Verbose "Testing Azure Service Bus hostname: [$($sbHost.HostAddress)]" if ($sbTcp.ConnectAsync($sbHost.HostAddress,$port).Wait([timespan]::FromSeconds($Timeout))) { Write-Warning "Azure Service Bus hostname test failed on port [$port]" $currentSBResult.Status = 'Failed' } else { Write-Verbose "Azure Service Bus hostname test successful on port [$port]" $currentSBResult.Status = 'Successful' } $sbTcp.Close() $sbTcp.Dispose() $results += $currentSBResult } } } else { Write-Warning "Unable to retrieve Site Connector details" } <# Test Domain IPs #> foreach ($domainIP in $testDomainIPs) { $currentIPResult = [Thycotic.PowerShell.DistributedEngines.CloudAccessResult]@{ ItemName = 'Secret Server Cloud Domain IP' HostAddress = $domainIP.HostAddress Port = 443 Status = $null } $dTcp = [System.Net.Sockets.TcpClient]::new() Write-Verbose "Testing Secret Server Cloud Domain IP: [$($domainIP.HostAddress)]" if ($dTcp.ConnectAsync($domainIP.HostAddress,443).Wait([timespan]::FromSeconds($Timeout))) { Write-Warning "Secret Server Cloud Domain IP test failed [$($domainIP.HostAddress)]" $currentIPResult.Status = 'Failed' } else { Write-Verbose "Secret Server Cloud Domain IP test successful [$($domainIP.HostAddress)]" $currentIPResult.Status = 'Successful' } $dTcp.Close() $dTcp.Dispose() $results += $currentIPResult } $results | Sort-Object ItemName } else { Write-Warning "No valid session found" } } } |