Public/Connect-TestEnvironment.ps1
|
function Connect-TestEnvironment { <# .EXTERNALHELP TestEnvironment-Help.xml .SYNOPSIS Connects to an identity provider, and fixes which provider the session works against #> [CmdletBinding()] [OutputType('TestEnvironmentConnection')] param( [Parameter(Mandatory = $true, Position = 0)] [ValidateSet('AD', 'Authentik', 'Entra', 'FreeIPA', 'Okta')] [string]$Provider, [Parameter()] [switch]$PassThru ) dynamicparam { # $Provider is not bound as a variable yet - dynamicparam runs during binding - so it is # read from the partially bound parameters. Before it is supplied there is nothing to # mirror, which is why -Provider is the parameter that has to come first. $chosen = $PSBoundParameters['Provider'] if (-not $chosen) { return [System.Management.Automation.RuntimeDefinedParameterDictionary]::new() } # PassThru is declared statically above, and re-declaring a parameter is an error # rather than an override. return Get-TestProviderParameter -CommandName ('Connect-{0}Environment' -f $chosen) -Exclude 'PassThru' } begin { if (-not $script:TestEnvironmentProvider.ContainsKey($Provider)) { Write-Error ("No provider called '$Provider' is loaded. Available: " + (($script:TestEnvironmentProvider.Keys | Sort-Object) -join ', ')) -ErrorAction Stop return } $target = 'Connect-{0}Environment' -f $Provider if (-not (Get-Command -Name $target -ErrorAction SilentlyContinue)) { Write-Error "The $Provider provider does not implement $target." -ErrorAction Stop return } } process { # Set before connecting rather than after, because a provider's connect logic can call # back through the shared dispatchers and those refuse to run without it. Cleared again # on failure, so a half-connected session cannot masquerade as a good one and send the # next command somewhere unexpected. $script:ActiveProvider = $Provider # Forwarded as a splat rather than rebuilt parameter by parameter. Rebuilding means # every new provider parameter has to be added in two places, and the one that gets # forgotten fails silently by simply not being passed on. $forward = @{} foreach ($key in $PSBoundParameters.Keys) { if ($key -in 'Provider', 'PassThru') { continue } $forward[$key] = $PSBoundParameters[$key] } $forward['PassThru'] = $true $connection = $null try { $connection = & $target @forward } catch { $script:ActiveProvider = $null throw } if (-not $connection) { $script:ActiveProvider = $null Write-Error "The $Provider provider did not return a connection." -ErrorAction Stop return } Write-Verbose "Connected through the $Provider provider" if ($PassThru) { return ($connection | Add-Member -NotePropertyName Provider -NotePropertyValue $Provider -Force -PassThru) } } } |