lib/Authentication.ps1
## Define a ZertoSessions Variable to store connection details in New-Variable -Scope global -Name 'ZertoSessions' -Value @{ } -Force function New-ZertoSession { <# .SYNOPSIS Creates a connection to a Zerto VM instance .DESCRIPTION This function creates a connection to the specified Zerto instance using the provided credentials. This session can be used when calling other functions within the Zerto module .PARAMETER SessionName The name that will be used when referring to the created ZertoSession .PARAMETER Server The URI of the Zerto instance to connect to .PARAMETER Credential The credentials to be used twhen connecting to Zerto .PARAMETER AllowInsecureSSL Boolean indicating whether or not an insecure SSL connection is allowed .PARAMETER ProfileName The name of the stored ZertoProfile which contains the connection settings .EXAMPLE $Session = @{ SessionName = 'TMDDEV' Server = 'tmddev.Zerto.net' Credential = (Get-StoredCredential -Name 'ME') } New-ZertoSession @Session .EXAMPLE Get-ZertoProfile -Name 'Zerto.example.com' | New-ZertoSession .EXAMPLE New-ZertoSession -ProfileName 'Zerto.example.com' .OUTPUTS None #> [CmdletBinding()] [Alias('Connect-ZertoServer')] param( [Parameter(Mandatory = $false, ValueFromPipelineByPropertyName = $true)] [Alias('Name')] [String]$SessionName = 'Default', [Parameter(Mandatory = $true, ParameterSetName = 'ByProperty', ValueFromPipelineByPropertyName = $true)] [String]$Server, [Parameter(Mandatory = $true, ParameterSetName = 'ByProperty', ValueFromPipelineByPropertyName = $true)] [Int]$Port = 9669, [Parameter(Mandatory = $true, ParameterSetName = 'ByProperty', ValueFromPipelineByPropertyName = $true)] [PSCredential]$Credential, [Parameter(Mandatory = $false, ParameterSetName = 'ByProperty', ValueFromPipelineByPropertyName = $true)] [Bool]$AllowInsecureSSL = $false, [Parameter(Mandatory = $false)] [Switch]$Passthru, # [Parameter(Mandatory = $true, # ParameterSetName = 'ByProfileObject')] # [ZertoProfile]$ZertoProfile, [Parameter(Mandatory = $true, Position = 0, ParameterSetName = 'ByProfile')] [ArgumentCompleter( { Get-ZertoProfile -List })] [Alias('Profile')] [String]$ProfileName ) begin { ## Create the TMServers Array that will be reachable at $global:ZertoSessions if (-not $global:ZertoSessions) { New-Variable -Name ZertoSessions -Scope Global -Value @{} } } process { if ($ProfileName) { $ZertoProfile = Get-ZertoProfile -Name $ProfileName if (!$ZertoProfile) { Write-Error "Could not load a Zerto profile named '$ProfileName'" return } } if ($ZertoProfile) { $SessionName = (($global:ZertoSessions.Keys -contains 'Default') -and ($SessionName -eq 'Default')) ? $ZertoProfile.Name : 'Default' $Server = $ZertoProfile.Server $Credential = $ZertoProfile.Credential $AllowInsecureSSL = $ZertoProfile.AllowInsecureSSL } else { if ($SessionName -eq 'Default') { $SessionName = (($global:ZertoSessions.Keys -contains 'Default') -and ($SessionName -eq 'Default')) ? $Server : 'Default' } } ## Check for Existing Session to this server if ($global:ZertoSessions.Keys -contains $SessionName) { $NewZertoSession = $global:ZertoSessions[$SessionName] } else { ## Create a session object for this new connection $NewZertoSession = [ZertoSession]::new($SessionName, $Server, $AllowInsecureSSL) } ## Honor SSL Settings from the user $CertSettings = @{ SkipCertificateCheck = $AllowInsecureSSL } ## Trim the server name $Instance = $Server.Replace('https://', '').Replace('http://', '') ## Save the Instance and Port used $NewZertoSession.ZertoServer = $Instance $NewZertoSession.ZertoPort = $Port ## Prepare Request Headers for use in the Session Header Cache $ContentType = 'application/json;charset=UTF-8' # Format the uri $uri = "https://$($Instance):$($Port)/v1/session/add" # Authenticating with Zerto APIs - Basic AUTH over SSL if ($Credential.GetNetworkCredential().domain) { $authInfo = ("{0}\{1}:{2}" -f $Credential.GetNetworkCredential().domain , $Credential.GetNetworkCredential().UserName, $Credential.GetNetworkCredential().Password ) } else { $authInfo = ("{0}:{1}" -f $Credential.GetNetworkCredential().UserName, $Credential.GetNetworkCredential().Password ) } $authInfo = [System.Text.Encoding]::UTF8.GetBytes($authInfo) $authInfo = [System.Convert]::ToBase64String($authInfo) $RequestHeaders = @{ "Authorization" = ("Basic {0}" -f $authInfo) "Accept-Version" = "1.0"; "Content-Type" = $ContentType; "Accept" = "application/json"; "Cache-Control" = "no-cache"; } $WebRequestSplat = @{ Method = 'POST' Uri = $uri Headers = $RequestHeaders SessionVariable = 'ZertoWebSession' PreserveAuthorizationOnRedirect = $true ContentType = $ContentType } ## Attempt Login if ($VerbosePreference -eq 'Continue') { Write-Host "Logging into Zerto instance [ " -NoNewline Write-Host $Instance -ForegroundColor Cyan -NoNewline Write-Host " ]" } # Make the request try { Write-Verbose "Web Request Parameters:" Write-Verbose ($WebRequestSplat | ConvertTo-Json -Depth 10) Write-Verbose "Invoking web request" $Response = Invoke-WebRequest @WebRequestSplat @CertSettings Write-Verbose "Response status code: $($Response.StatusCode)" Write-Verbose "Response Content: $($Response.Content)" } catch { throw $_ } ## Check the Response code for 200 if ($Response.StatusCode -eq 200) { $ZertoSessionToken = $Response.headers.get_item("x-zerto-session") | Select-Object -First 1 $ZertoWebSession.Headers["x-zerto-session"] = $ZertoSessionToken $ZertoWebSession.Headers.Remove('Authorization') } else { Write-Error "Login Failure! Unable to Log into $Server. Check the URL and Credentials and try again" return } $NewZertoSession.ZertoWebSession = $ZertoWebSession ## Add this Session to the ZertoSessions list $global:ZertoSessions[$SessionName] = $NewZertoSession ## Return the session if requested if ($Passthru) { $NewZertoSession } } } # #.ExternalHelp ZertoModule.psm1-help.xml # Function Get-ZertoAuthToken { # [CmdletBinding()] # param( # [Parameter(Mandatory = $false, HelpMessage = 'Zerto Server or ENV:\ZertoServer')] [string] $ZertoServer = ( Get-EnvZertoServer ) , # [Parameter(Mandatory = $false, HelpMessage = 'Zerto Server URL Port')] [string] $ZertoPort = ( Get-EnvZertoPort ), # [Parameter( HelpMessage = 'User to connect to Zerto')] [string] $ZertoUser, # [Parameter( HelpMessage = 'Credential to connect to Zerto')] [PSCredential] $Credential # ) # Set-SSLCertByPass # if ([String]::IsNullOrEmpty($ZertoServer) ) { # throw "Missing Zerto Server" # } # $baseURL = "https://" + $ZertoSessionConfig.ZertoServer + ":" + $ZertoSessionConfig.ZertoPort + "/v1/" # $FullURL = $baseURL + "session/add" # $TypeJSON = "application/json" # Write-Verbose $FullURL # if (-Not $Credential) { # if ([String]::IsNullOrEmpty($ZertoUser)) { # $Credential = Get-Credential -Message "Enter your Zerto credentials for '$ZertoServer'" # } # else { # $Credential = Get-Credential -Message "Enter your Zerto credentials for '$ZertoServer'" -UserName $ZertoUser # } # } # If ($null -NE $Credential) { # #Remove our Zerto Version # Remove-Item ENV:ZertoToken -Force -ErrorAction Ignore # Remove-Item ENV:ZertoVersion -Force -ErrorAction Ignore # # Authenticating with Zerto APIs - Basic AUTH over SSL # if ($Credential.GetNetworkCredential().domain) { # $authInfo = ("{0}\{1}:{2}" -f $Credential.GetNetworkCredential().domain , $Credential.GetNetworkCredential().UserName, $Credential.GetNetworkCredential().Password ) # } # else { # $authInfo = ("{0}:{1}" -f $Credential.GetNetworkCredential().UserName, $Credential.GetNetworkCredential().Password ) # } # $authInfo = [System.Text.Encoding]::UTF8.GetBytes($authInfo) # $authInfo = [System.Convert]::ToBase64String($authInfo) # $headers = @{Authorization = ("Basic {0}" -f $authInfo) } # # $sessionBody = '{"authenticationMethod": 1}' # # $sessionBody = @{ # # AuthenticationMethod = 0 # # login = $Credential.Username # # password = $Credential.GetNetworkCredential().Password # # } | ConvertTo-Json -Compress # #Need to check our Response. # try { # $RequestSplat = @{ # Uri = $FullURL # Headers = $headers # Method = 'POST' # # Body = $sessionBody # ContentType = $TypeJSON # } # ## TODO: Add handling for this # $AllowInsecureSSL = $true # if ($AllowInsecureSSL) { # $RequestSplat.SkipCertificateCheck = $True # } # $xZertoSessionResponse = Invoke-WebRequest @RequestSplat # } # catch { # $xZertoSessionResponse = $_.Exception.Response # } # if ($null -eq $xZertoSessionResponse ) { # Throw "Zerto Server ${ZertoServer}:${ZertoPort} not responding." # } # elseif ($xZertoSessionResponse.StatusCode -eq "200") { # $xZertoSession = $xZertoSessionResponse.headers.get_item("x-zerto-session") # $ZertoSessionHeader = @{"x-zerto-session" = $xZertoSession } # return $ZertoSessionHeader # } # else { # if ($xZertoSessionResponse.StatusCode.value__ -eq "401") { # Throw "User $ZertoUser not authorized or invalid password." # } # return $null # } # } # else { # return $null # } # } # #.ExternalHelp ZertoModule.psm1-help.xml # Function Set-ZertoAuthToken { # [CmdletBinding()] # param( # [Parameter(Mandatory = $false, HelpMessage = 'Zerto Server or ENV:\ZertoServer')] [string] $ZertoServer = ( Get-EnvZertoServer ) , # [Parameter(Mandatory = $false, HelpMessage = 'Zerto Server URL Port')] [string] $ZertoPort = ( Get-EnvZertoPort ), # [Parameter( HelpMessage = 'User to connect to Zerto')] [string] $ZertoUser # ) # Set-Item ENV:ZertoToken ( (Get-ZertoAuthToken -ZertoServer $ZertoServer -ZertoPort $ZertoPort -ZertoUser $ZertoUser) | ConvertTo-Json -Compress) # #Set our Zerto Version # Set-Item ENV:ZertoVersion (Get-ZertoLocalSite).version # } # # .ExternalHelp ZertoModule.psm1-help.xml # Function Remove-ZertoAuthToken { # [CmdletBinding()] # param( # [Parameter(Mandatory = $false, HelpMessage = 'Zerto Server or ENV:\ZertoServer')] [string] $ZertoServer = ( Get-EnvZertoServer ) , # [Parameter(Mandatory = $false, HelpMessage = 'Zerto Server URL Port')] [string] $ZertoPort = ( Get-EnvZertoPort ), # [Parameter(Mandatory = $false, ValueFromPipeline = $true, HelpMessage = 'Zerto authentication token from Get-ZertoAuthToken or ENV:\ZertoToken')] [Hashtable] $ZertoToken = ( Get-EnvZertoToken ) # ) # $baseURL = "https://" + $ZertoSessionConfig.ZertoServer + ":" + $ZertoSessionConfig.ZertoPort + "/v1/" # $TypeJSON = "application/json" # if ( $ZertoToken -eq $null) { # throw "Missing Zerto Authentication Token" # } # $FullURL = $baseURL + "Session" # Write-Verbose $FullURL # try { # $RestMethodSplat = @{ # Uri = $FullURL # TimeoutSec = 100 # ContentType = $TypeJSON # Method = 'GET' # WebSession = $ZertoSessionConfig.ZertoWebSession # } # $Result = Invoke-RestMethod @RestMethodSplat @ZertoCertSettings -Method Delete # } # catch { # throw $_.Exception.Message # } # #Remove Zerto Vars # Remove-Item ENV:ZertoVersion -Force -ErrorAction Ignore # Remove-Item ENV:ZertoToken -Force -ErrorAction Ignore # return $Result # } # # .ExternalHelp ZertoModule.psm1-help.xml # Function Connect-ZertoZVM { # [CmdletBinding()] # param( # [Parameter(Mandatory = $true, HelpMessage = 'Zerto Server or ENV:\ZertoServer')] [string] $ZertoServer , # [Parameter(Mandatory = $false, HelpMessage = 'Zerto Server URL Port')] [string] $ZertoPort = 9669 , # [Parameter(Mandatory = $false, HelpMessage = 'User to connect to Zerto')] [string] $ZertoUser, # [Parameter(Mandatory = $false, HelpMessage = 'Credential to use to connect to Zerto')] [PSCredential] $Credential # ) # Set-Item ENV:ZertoServer $ZertoServer # Set-Item ENV:ZertoPort $ZertoPort # if ($Credential) { # Set-Item ENV:ZertoToken ((Get-ZertoAuthToken -ZertoServer $ZertoServer -ZertoPort $ZertoPort -Credential $Credential) | ConvertTo-Json -Compress) # } # elseif ($ZertoUser) { # Set-Item ENV:ZertoToken ((Get-ZertoAuthToken -ZertoServer $ZertoServer -ZertoPort $ZertoPort -ZertoUser $ZertoUser) | ConvertTo-Json -Compress) # } # else { # Set-Item ENV:ZertoToken ((Get-ZertoAuthToken -ZertoServer $ZertoServer -ZertoPort $ZertoPort) | ConvertTo-Json -Compress) # } # Set-Item ENV:ZertoVersion (Get-ZertoLocalSite).version # } # # .ExternalHelp ZertoModule.psm1-help.xml # Function Disconnect-ZertoZVM { # Remove-ZertoAuthToken # Remove-Item ENV:ZertoVersion -Force -ErrorAction Ignore # Remove-Item ENV:ZertoServer -Force -ErrorAction Ignore # Remove-Item ENV:ZertoPort -Force -ErrorAction Ignore # Remove-Item ENV:ZertoToken -Force -ErrorAction Ignore # } # #endregion |