diff --git a/ZertoApiWrapper/Public/Connect-ZertoServer.ps1 b/ZertoApiWrapper/Public/Connect-ZertoServer.ps1 index f9f33ac..9a8c649 100644 --- a/ZertoApiWrapper/Public/Connect-ZertoServer.ps1 +++ b/ZertoApiWrapper/Public/Connect-ZertoServer.ps1 @@ -22,7 +22,11 @@ function Connect-ZertoServer { HelpMessage = "Valid credentials to connect to the Zerto Management Server" )] [System.Management.Automation.PSCredential]$credential, - [switch]$returnHeaders + [switch]$returnHeaders, + [Parameter( + HelpMessage = "Use this switch to indicate that you would like the module to take care of auto re-authorization and reconnection to the ZVM should the token expire. This option will cache your PSCredential object to be reused" + )] + [switch]$AutoReconnect ) begin { @@ -38,6 +42,10 @@ function Connect-ZertoServer { "Accept" = "application/json" "zerto-triggered-by" = "PowershellWes" } + Set-Variable -Name Reconnect -Scope Script -Value $AutoReconnect.IsPresent + if ($Script:Reconnect) { + Set-Variable -Name CachedCredential -Scope Script -Value $credential + } } process { diff --git a/ZertoApiWrapper/Public/Invoke-ZertoRestRequest.ps1 b/ZertoApiWrapper/Public/Invoke-ZertoRestRequest.ps1 index 97430ab..93d77e4 100644 --- a/ZertoApiWrapper/Public/Invoke-ZertoRestRequest.ps1 +++ b/ZertoApiWrapper/Public/Invoke-ZertoRestRequest.ps1 @@ -41,24 +41,26 @@ function Invoke-ZertoRestRequest { } # If the Headers exist and the Last action was more than 30 minutes ago, Session is Expired - if ( (Test-Path variable:script:zvmHeaders) -and $([datetime]$script:zvmLastAction).addMinutes(30) -lt $(Get-Date) ) { + if ( (Test-Path variable:script:zvmHeaders) -and $([datetime]$script:zvmLastAction).addMinutes(30) -lt $(Get-Date) -and $Script:Reconnect -eq $False ) { Throw "Authorization Token has Expired. Please re-authorize to the Zerto Virtual Manager" - } else { - - # Build the URI to be submitted - $submittedURI = "https://{0}:{1}/{2}/{3}" -f $script:zvmServer, $script:zvmPort, $apiVersion, $uri - try { - # Set the zvmLastAction time and try to submit the REST Request - $script:zvmLastAction = (Get-Date).Ticks - # If running PwSh - Use this Invoke-RestMethod with passed Variables - if ($PSVersionTable.PSVersion.Major -ge 6) { - $apiRequestResults = Invoke-RestMethod -Uri $submittedURI -Headers $script:zvmHeaders -Method $method -Body $body -ContentType $contentType -Credential $credential -SkipCertificateCheck -ResponseHeadersVariable responseHeaders -TimeoutSec 100 - } else { - # If running PowerShell 5.1 --> Do the Following - # Check to see if All Certs are Trusted. If not, Create the Policy to Trust All Certificates - if ([System.Net.ServicePointManager]::CertificatePolicy.GetType().Name -ne "TrustAllCertsPolicy") { - Try { - $type = @' + } elseif (( (Test-Path variable:script:zvmHeaders) -and $([datetime]$script:zvmLastAction).addMinutes(30) -lt $(Get-Date) -and $Script:Reconnect -eq $True )) { + Write-Verbose "Authorization had expired. Attempting Reauthorization." + Connect-ZertoServer -zertoServer $Script:zvmServer -zertoPort $script:zvmPort -credential $Script:CachedCredential + }# else { + # Build the URI to be submitted + $submittedURI = "https://{0}:{1}/{2}/{3}" -f $script:zvmServer, $script:zvmPort, $apiVersion, $uri + try { + # Set the zvmLastAction time and try to submit the REST Request + $script:zvmLastAction = (Get-Date).Ticks + # If running PwSh - Use this Invoke-RestMethod with passed Variables + if ($PSVersionTable.PSVersion.Major -ge 6) { + $apiRequestResults = Invoke-RestMethod -Uri $submittedURI -Headers $script:zvmHeaders -Method $method -Body $body -ContentType $contentType -Credential $credential -SkipCertificateCheck -ResponseHeadersVariable responseHeaders -TimeoutSec 100 + } else { + # If running PowerShell 5.1 --> Do the Following + # Check to see if All Certs are Trusted. If not, Create the Policy to Trust All Certificates + if ([System.Net.ServicePointManager]::CertificatePolicy.GetType().Name -ne "TrustAllCertsPolicy") { + Try { + $type = @' using System.Net; using System.Security.Cryptography.X509Certificates; public class TrustAllCertsPolicy : ICertificatePolicy { @@ -67,42 +69,42 @@ public class TrustAllCertsPolicy : ICertificatePolicy { } } '@ - Add-Type -TypeDefinition $type -ErrorAction SilentlyContinue - } Catch { - if ($error[0].Exception -ne "Cannot add type. The type name 'TrustAllCertsPolicy already exists.") { - Write-Debug $error[0] - } + Add-Type -TypeDefinition $type -ErrorAction SilentlyContinue + } Catch { + if ($error[0].Exception -ne "Cannot add type. The type name 'TrustAllCertsPolicy already exists.") { + Write-Debug $error[0] } - [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy + } + [System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy - } - # If we are authenticating to the ZVM, Use this block to use Invoke-WebRequest and format the Headers as expected. - if ($uri -eq "session/add" -and $method -eq "POST") { - $apiRequestResults = Invoke-WebRequest -Uri $submittedURI -Headers $script:zvmHeaders -Method $method -Body $body -ContentType $contentType -Credential $credential -TimeoutSec 100 - $responseHeaders = @{ } - $responseHeaders['x-zerto-session'] = @($apiRequestResults.Headers['x-zerto-session']) - } elseif ($method -ne "GET") { - # If the Method is something other than 'GET' use this call with a body parameter - $apiRequestResults = Invoke-RestMethod -Uri $submittedURI -Headers $script:zvmHeaders -Method $method -Body $body -ContentType $contentType -Credential $credential -TimeoutSec 100 - } else { - # If the Method we are calling is 'GET' use this call without a body parameter - $apiRequestResults = Invoke-RestMethod -Uri $submittedURI -Headers $script:zvmHeaders -Method $method -ContentType $contentType -Credential $credential -TimeoutSec 100 - } } - } catch { - # If an error is encountered, Catch - Write-Error -ErrorRecord $_ -ErrorAction $callerErrorActionPreference + # If we are authenticating to the ZVM, Use this block to use Invoke-WebRequest and format the Headers as expected. + if ($uri -eq "session/add" -and $method -eq "POST") { + $apiRequestResults = Invoke-WebRequest -Uri $submittedURI -Headers $script:zvmHeaders -Method $method -Body $body -ContentType $contentType -Credential $credential -TimeoutSec 100 + $responseHeaders = @{ } + $responseHeaders['x-zerto-session'] = @($apiRequestResults.Headers['x-zerto-session']) + } elseif ($method -ne "GET") { + # If the Method is something other than 'GET' use this call with a body parameter + $apiRequestResults = Invoke-RestMethod -Uri $submittedURI -Headers $script:zvmHeaders -Method $method -Body $body -ContentType $contentType -Credential $credential -TimeoutSec 100 + } else { + # If the Method we are calling is 'GET' use this call without a body parameter + $apiRequestResults = Invoke-RestMethod -Uri $submittedURI -Headers $script:zvmHeaders -Method $method -ContentType $contentType -Credential $credential -TimeoutSec 100 + } } + } catch { + # If an error is encountered, Catch + Write-Error -ErrorRecord $_ -ErrorAction $callerErrorActionPreference + } - # If the calling function does not need the headers (Default Action) return the results of the API Call - if (-not $returnHeaders) { - return $apiRequestResults - } else { - #If Headers are required, build a PS Custom Object with the Results and the Headers - $apiRequestAndHeaderResults = New-Object -TypeName psobject - $apiRequestAndHeaderResults | Add-Member -MemberType NoteProperty -Name "apiRequestResults" -Value $apiRequestResults - $apiRequestAndHeaderResults | Add-Member -MemberType NoteProperty -Name "Headers" -Value $responseHeaders - return $apiRequestAndHeaderResults - } + # If the calling function does not need the headers (Default Action) return the results of the API Call + if (-not $returnHeaders) { + return $apiRequestResults + } else { + #If Headers are required, build a PS Custom Object with the Results and the Headers + $apiRequestAndHeaderResults = New-Object -TypeName psobject + $apiRequestAndHeaderResults | Add-Member -MemberType NoteProperty -Name "apiRequestResults" -Value $apiRequestResults + $apiRequestAndHeaderResults | Add-Member -MemberType NoteProperty -Name "Headers" -Value $responseHeaders + return $apiRequestAndHeaderResults + #} } }