Public/Session/Connect-vCAVService.ps1
function Connect-vCAVService(){ <# .SYNOPSIS This cmdlet establishes a connection to the specified vCloud Availability server. .DESCRIPTION This cmdlet establishes a connection to the specified vCloud Availability server. The cmdlet starts a new session or re-establishes a previous session with a cloud server using the specified parameters. If a connection to a server already exists, the cmdlet will disconnect the session and re-attempt the connection. In order to perform replication management operations that involve remote sites, your session needs to be "extended" with credentials (vCD auth cookie or org user and password) to the related remote site. The -Extend switch can be used for this purpose. To set the default behavior of PowerCLI when no valid certificates are recognized, use the InvalidCertificateAction parameter of the Set-PowerCLIConfiguration cmdlet. For more information about invalid certificates, run 'Get-Help about_invalid_certificates'. To set the proxy usage behavior of PowerCLI (eg. to bypass a proxy or to use the System Proxy), use the ProxyPolicy parameter of the Set-PowerCLIConfiguration cmdlet. The connection details are kept in a global variable called $DefaultvCAVServer. When you disconnect from a server, the server is removed from the $DefaultvCAVServer variable. You can modify the value of the $DefaultCIServers variable manually. You can also use the -SaveCredentials switches to export credentials that can be used with the -UseSavedCredentials switch for use in Automation. .PARAMETER Server Specifies the IP address or DNS Hostname of the vCloud Availability server .PARAMETER AuthProvider The Authentication Provider which should be used to connect. Local or vSphere SSO for Administrative access and vCloud or vCD Session for vCloud Director based logon. The default is Local authentication .PARAMETER Port Specifies the TCP Port for the connection; the Default is TCP 443. .PARAMETER Credentials Specifies a PSCredential object that contains credentials for authenticating with the server. .PARAMETER APIVersion The API Version to use for the connection. Default is Version 3. (vCloud Availability 3.0.X) During connection if a higher version of the API detected as supported it will be used. .PARAMETER Extend Indicates that the session should be extended with a connection to the specified remote vCloud Availability site. .PARAMETER Site The registered Remote Site to Extend the session to .PARAMETER SaveCredentials Indicates that you want to only save the specified credentials. The credentials and connection details are outputed (with the password encrypted using the local user account) to the local console. Optionally if -CredentialStoreFile is provided the output is also saved into a local file specified in the -CredentialStoreFile parameter. This file can be used in scripts later use in automation. .PARAMETER CredentialStoreFile File path to store or read the connection properties. .PARAMETER UseSavedCredentials Indicates that saved credentials generated from using the -SaveCredentials should be read for the connection. The credentials are read from the well-formed JSON file provided in paramter -CredentialStoreFile .EXAMPLE Connect-vCAVService -Server "vcav.pigeonnuggets.com" -Port 8044 Connects to the vCloud Availability server "vcav.pigeonnuggets.com" on TCP 8044 using the Local Authentication method prompting the user for credentials. .EXAMPLE Connect-vCAVService -Server "vcav.pigeonnuggets.com" -Port 8044 -AuthProvider "vCDSession" Connects to the vCloud Availability server "vcav.pigeonnuggets.com" on TCP 8044 using the vCloud Director credentials stored in the PowerCLI global variable $DefaultCIServers. .EXAMPLE Connect-vCAVService -Server "vcav.pigeonnuggets.com" -AuthProvider "vCDLogin" Connects to the vCloud Availability server "vcav.pigeonnuggets.com" on TCP 443 prompting the user for vCloud Director credentials. (eg. administrator@system) .EXAMPLE Connect-vCAVService -Server "vcav.pigeonnuggets.com" -AuthProvider "SSO" Connects to the vCloud Availability server "vcav.pigeonnuggets.com" on TCP 443 prompting the user for the SSO Lookup Service vSphere SSO Credentials (eg. administrator@vsphere.local) .EXAMPLE Connect-vCAVService -Server "vcav.pigeonnuggets.com" -SaveCredentials -CredentialStoreFile "vcav-pigeonnuggets-com.json" Creates a new saved credential for the "vcav.pigeonnuggets.com" vCAV service and outputs it to "vcav-pigeonnuggets-com.json" in the local directory. .EXAMPLE Connect-vCAVService -UseSavedCredentials -CredentialStoreFile "vcav-pigeonnuggets-com.json" Connects to the vCloud Availability Server specified in the credential store file "vcav-pigeonnuggets-com.json" .EXAMPLE Connect-vCAVService -Extend -Site "Brisbane" -AuthProvider "vcdSession" Extends the current session to the remote site named "Brisbane" using the currently logged in PowerCLI vCloud Director session. .EXAMPLE Connect-vCAVService -Extend -Site "Brisbane" -AuthProvider "vcdLogin" Extends the current session to the remote site named "Brisbane" using the provided vCloud Director credentials. (eg. administrator@testorg) .NOTES This cmdlet does not currently support the SAML authentication method. AUTHOR: Adrian Begg LASTEDIT: 2019-09-10 VERSION: 4.0 #> [CmdletBinding(DefaultParameterSetName="Standard")] Param( [Parameter(Mandatory=$False, ParameterSetName="SaveCredentials")] [switch] $SaveCredentials, [Parameter(Mandatory=$False, ParameterSetName="UseSaved")] [switch] $UseSavedCredentials, [Parameter(Mandatory=$False, ParameterSetName="Extend")] [switch] $Extend, [Parameter(Mandatory=$True, ParameterSetName="Standard")] [Parameter(Mandatory=$True, ParameterSetName="SaveCredentials")] [ValidateNotNullorEmpty()] [string] $Server, [Parameter(Mandatory=$False, ParameterSetName="Standard")] [Parameter(Mandatory=$False, ParameterSetName="SaveCredentials")] [Parameter(Mandatory=$False, ParameterSetName="Extend")] [ValidateSet("Local","SSO","vCDLogin","vCDSession")] [string] $AuthProvider="Local", [Parameter(Mandatory=$False, ParameterSetName="Standard")] [Parameter(Mandatory=$False, ParameterSetName="SaveCredentials")] [ValidateRange(1,65536)] [int] $Port=443, [Parameter(Mandatory=$False, ParameterSetName="Standard")] [Parameter(Mandatory=$False, ParameterSetName="SaveCredentials")] [Parameter(Mandatory=$False, ParameterSetName="Extend")] [PSCredential] $Credentials = [System.Management.Automation.PSCredential]::Empty, [Parameter(Mandatory=$False, ParameterSetName="Standard")] [Parameter(Mandatory=$False, ParameterSetName="SaveCredentials")] [ValidateSet(1,2,3,4)] [int] $APIVersion=3, [Parameter(Mandatory=$True, ParameterSetName="Extend")] [ValidateNotNullorEmpty()] [string] $Site, [Parameter(Mandatory=$True, ParameterSetName="UseSaved")] [Parameter(Mandatory=$False, ParameterSetName="SaveCredentials")] [ValidateNotNullorEmpty()] [string] $CredentialStoreFile ) # Check if we are using a credential file first, this ensures that some checks are skipped if ($PSBoundParameters.ContainsKey("UseSavedCredentials")){ # Attempt to load the credential store if(!(Test-Path -Path $CredentialStoreFile)){ throw "Unable to find a saved credential file $CredentialStoreFile. Please check the path and try again." } # Next try and read the file try{ $JSONvCAVCreds = Get-Content -Raw -Path $CredentialStoreFile | ConvertFrom-Json } catch { throw "An error occured reading the JSON in the credential file $CredentialStoreFile for vCAV login. Please check that the file is well formed." } # Now load the values into memory try{ [SecureString] $APIPassword = $JSONvCAVCreds.EncyptedPassword | ConvertTo-SecureString } catch { throw "Unable to decrypt the encrypted password in the configuration file. Please ensure you are executing as the same user session that generated the file." } # Set the properites $Credentials = New-Object System.Management.Automation.PSCredential ($JSONvCAVCreds.Username, $APIPassword) [string] $Server = $JSONvCAVCreds.Server [int] $Port = $JSONvCAVCreds.Port [string] $AuthProvider = $JSONvCAVCreds.AuthProvider [int] $APIVersion = $JSONvCAVCreds.APIVersion } # Next we need to check if a Parameter for Credentials was provided; this needs to be done here instead of during parameter checking for UseSavedCredentials not to prompt if($Credentials -eq [System.Management.Automation.PSCredential]::Empty) { $Credentials = $Host.ui.PromptForCredential("Enter credentials for $Server", "Please enter your user name and password for the provided auth type.", "", "") } if($PSBoundParameters.ContainsKey("SaveCredentials")){ # Construct an object with the required values for authentication $objAuthCache = New-Object System.Management.Automation.PSObject $objAuthCache | Add-Member Note* Server $Server $objAuthCache | Add-Member Note* Port $Port $objAuthCache | Add-Member Note* AuthProvider $AuthProvider $objAuthCache | Add-Member Note* Username $Credentials.UserName $objAuthCache | Add-Member Note* EncyptedPassword ($Credentials.GetNetworkCredential().Password | ConvertTo-SecureString -AsPlainText -Force | ConvertFrom-SecureString) $objAuthCache | Add-Member Note* APIVersion $APIVersion # Check if a credential file has been specified if($PSBoundParameters.ContainsKey("CredentialStoreFile")){ # Next check if it already exists if(Test-Path -Path $CredentialStoreFile){ Write-Warning "A saved credential file $CredentialStoreFile already exists in the specified path and will be overwritten if you continue." -WarningAction Inquire } # Write the credentials out to file and screen ConvertTo-Json $objAuthCache | Out-File $CredentialStoreFile } # Output to local console ConvertTo-Json $objAuthCache } elseif($PSBoundParameters.ContainsKey("Extend")){ # Check if connected and warn if already connected to a server if(!$global:DefaultvCAVServer.IsConnected){ throw "You are not currently connected to a local vCAV Service. In order to extend your session to a remote site you must first authenticate with the local site." Break } # Next check if the Site provided is registered in the locally connected vCAV Site if((Get-vCAVSites | Where-Object {$_.site -eq $Site} -ne $null)){ $AuthURI = $global:DefaultvCAVServer.ServiceURI + "sessions/extend" # Construct the JSON payload for authentication $objAuthPayload = New-Object System.Management.Automation.PSObject if($AuthProvider -eq "vCDLogin"){ $objAuthPayload | Add-Member Note* type "credentials" $objAuthPayload | Add-Member Note* site $Site $objAuthPayload | Add-Member Note* vcdUser $Credentials.UserName $objAuthPayload | Add-Member Note* vcdPassword $Credentials.GetNetworkCredential().Password } elseif($AuthProvider -eq "vCDSession"){ if($global:DefaultCIServers.IsConnected){ $objAuthPayload | Add-Member Note* type "cookie" $objAuthPayload | Add-Member Note* site $Site $objAuthPayload | Add-Member Note* vcdCookie $global:DefaultCIServers.SessionSecret } else { throw "You are currently not connected to vCloud Director. This Authentication option is only available when connected to vCloud using Connect-CIServer." } } else { throw "The provided AuthProvider is not valid for session extention. Only the vCDLogin and vCDSession methods are supported with this option." } # Make the API call to extend the session and update the Global $JSONExtendRequest = (Invoke-vCAVAPIRequest -URI $AuthURI -Method Post -APIVersion $DefaultvCAVServer.DefaultAPIVersion -Data (ConvertTo-JSON $objAuthPayload)).JSONData $DefaultvCAVServer.Roles = $JSONExtendRequest.roles $DefaultvCAVServer.User = $JSONExtendRequest.user $DefaultvCAVServer.AuthenticatedSites = $JSONExtendRequest.authenticatedSites } else { throw "A Site with the name $Site is not currently paired with the locally connected vCAV installation. Please check the Site configuration and try again." } } else { # Now for main entry point to create a local session # Check if already connected and warn if already connected to a server if($global:DefaultvCAVServer.IsConnected){ Write-Warning "You are currently already connected to the vCAV Service $($global:DefaultvCAVServer.Server). Your existing session will be disconnected if you continue." -WarningAction Inquire Disconnect-vCAVService } # Construct the URI for the API call to connect to the vCAV Service [string] $AuthURI = "https://" + $Server + ":" + $Port + "/sessions" # Construct the JSON payload for authentication $objAuthPayload = New-Object System.Management.Automation.PSObject if($AuthProvider -eq "SSO"){ $objAuthPayload | Add-Member Note* type "ssoCredentials" $objAuthPayload | Add-Member Note* username $Credentials.UserName $objAuthPayload | Add-Member Note* password $Credentials.GetNetworkCredential().Password } elseif($AuthProvider -eq "Local"){ $objAuthPayload | Add-Member Note* type "localUser" $objAuthPayload | Add-Member Note* localUser $Credentials.UserName $objAuthPayload | Add-Member Note* localPassword $Credentials.GetNetworkCredential().Password } elseif($AuthProvider -eq "vCDLogin"){ $objAuthPayload | Add-Member Note* type "vcdCredentials" $objAuthPayload | Add-Member Note* vcdUser $Credentials.UserName $objAuthPayload | Add-Member Note* vcdPassword $Credentials.GetNetworkCredential().Password } elseif($AuthProvider -eq "vCDSession"){ if($global:DefaultCIServers.IsConnected){ $objAuthPayload | Add-Member Note* type "vcdCookie" $objAuthPayload | Add-Member Note* vcdCookie $global:DefaultCIServers.SessionSecret } else { throw "You are currently not connected to vCloud Director. This Authentication option is only available when connected to vCloud using Connect-CIServer." } } # Now make the call to the Logon Service; if no exception is thrown store the session details. $JSONAuthRequest = Invoke-vCAVAPIRequest -URI $AuthURI -Data (ConvertTo-JSON $objAuthPayload) -Method Post -APIVersion $APIVersion -CheckConnection $false $objAuthData = $JSONAuthRequest.JSONData $objvCAVService = New-Object System.Management.Automation.PSObject $objvCAVService | Add-Member Note* Name $Server $objvCAVService | Add-Member Note* ServiceURI ("https://" + $Server + ":" + $Port + "/") $objvCAVService | Add-Member Note* Port $Port $objvCAVService | Add-Member Note* AuthenticationProvider $AuthProvider $objvCAVService | Add-Member Note* AccessToken $($JSONAuthRequest.Headers.'X-VCAV-Auth') $objvCAVService | Add-Member Note* IsConnected $true $objvCAVService | Add-Member Note* Roles $objAuthData.roles $objvCAVService | Add-Member Note* User $objAuthData.user $objvCAVService | Add-Member Note* AuthenticatedSites $objAuthData.authenticatedSites $objvCAVService | Add-Member Note* DefaultAPIVersion $APIVersion $objvCAVService | Add-Member Note* serviceType "" $objvCAVService | Add-Member Note* productName "" $objvCAVService | Add-Member Note* buildVersion "" $objvCAVService | Add-Member Note* buildDate "" Set-Variable -Name "DefaultvCAVServer" -Value $objvCAVService -Scope Global # Next make a call to get version infomration for the endpoint; we need to check the API version first by examining the header from the Auth request [string] $AboutURI = $Global:DefaultvCAVServer.ServiceURI + "diagnostics/about" try{ $JSONAboutRequest = Invoke-vCAVAPIRequest -URI $AboutURI -Method Get -APIVersion $DefaultvCAVServer.DefaultAPIVersion -CheckConnection $false $DefaultvCAVServer.serviceType = $JSONAboutRequest.JSONData.serviceType $DefaultvCAVServer.productName = $JSONAboutRequest.JSONData.productName $DefaultvCAVServer.buildVersion = $JSONAboutRequest.JSONData.buildVersion $DefaultvCAVServer.buildDate = $JSONAboutRequest.JSONData.buildDate } catch { # If an exception is thrown clear the connection Set-Variable -Name "DefaultvCAVServer" -Value $null -Scope Global throw "An error occured during the connection; check the API Version provided is correct and try again. $($_)" } # Finally check the highest version of the API is being used for newer version of the product if($DefaultvCAVServer.buildVersion -ge "3.5"){ $DefaultvCAVServer.DefaultAPIVersion = 4 } } } |