diff --git a/CHANGELOG.md b/CHANGELOG.md index 3b4a119..341c6f1 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -5,6 +5,21 @@ All notable changes to this project will be documented in this file. The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), and this project is transitioning to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). +## [1.4.3] + +### Zerto Virtual Manager + +#### Updated + +* Updated `Connect-ZertoServer` with a `-AutoReconnect` switch to allow the auto reconnection of a session that has timed-out. +* Updated `New-ZertoVpg` to have a Default Parameter Set of `recoveryHostDatastore` should no parameters be passed when calling the function. +* Updated `New-ZertoVpg -recoverySite` parameter to be case-insensitive + +#### Fixed + +* Fixed an [issue](https://github.com/ZertoPublic/ZertoApiWrapper/issues/96) with `Set-ZertoLicense` so that ShouldProcess functions properly. +* Fixed an [issue](https://github.com/ZertoPublic/ZertoApiWrapper/issues/95) when attempting to connect to an unlicensed site. + ## [1.4.2] ### Zerto Virtual Manager diff --git a/Tests/Public/Connect-ZertoServer.Tests.ps1 b/Tests/Public/Connect-ZertoServer.Tests.ps1 index 6d6e185..802cc9b 100644 --- a/Tests/Public/Connect-ZertoServer.Tests.ps1 +++ b/Tests/Public/Connect-ZertoServer.Tests.ps1 @@ -1,6 +1,6 @@ #Requires -Modules Pester $global:here = (Split-Path -Parent $PSCommandPath) -$global:function = ((Split-Path -leaf $PSCommandPath).Split('.'))[0] +$global:function = ((Split-Path -Leaf $PSCommandPath).Split('.'))[0] Describe $global:function -Tag 'Unit', 'Source', 'Built' { BeforeAll { @@ -45,6 +45,16 @@ Describe $global:function -Tag 'Unit', 'Source', 'Built' { { Connect-ZertoServer -zertoServer -credential 1234 } | Should -Throw { Connect-ZertoServer -zertoServer -credential $(@{Username = "zerto\build"; Password = 'SecureString' }) } | Should -Throw } + + It "has a switch parameter to return the headers" { + Get-Command $global:function | Should -HaveParameter returnHeaders + Get-Command $global:function | Should -HaveParameter returnHeaders -Type Switch + } + + It "has a switch parameter to auto reauthorize the session" { + Get-Command $global:function | Should -HaveParameter autoReconnect + Get-Command $global:function | Should -HaveParameter autoReconnect -Type Switch + } } InModuleScope -ModuleName ZertoApiWrapper { @@ -57,10 +67,6 @@ Describe $global:function -Tag 'Unit', 'Source', 'Built' { return $results } - Mock -ModuleName ZertoApiWrapper -CommandName Get-ZertoLocalSite { - return (Get-Content -Path "$global:here\Mocks\LocalSiteInfo.json" -Raw | ConvertFrom-Json) - } - Context "$($global:function)::InModuleScope Function Unit Tests" { BeforeAll { @@ -96,12 +102,6 @@ Describe $global:function -Tag 'Unit', 'Source', 'Built' { $script:zvmHeaders['Accept'] | Should -BeOfType String } - It "Module Scope zvmLocalInfo variable tests" { - $script:zvmLocalInfo | Should -Not -BeNullOrEmpty - $script:zvmLocalInfo | Should -BeOfType PSCustomObject - $script:zvmLocalInfo.SiteIdentifier | Should -BeOfType String - } - $headers = Connect-ZertoServer -zertoServer $Server -credential $credential -returnHeaders It "returns a Hashtable with 2 keys" { $headers | Should -BeOfType Hashtable @@ -134,7 +134,6 @@ Describe $global:function -Tag 'Unit', 'Source', 'Built' { } Assert-MockCalled -ModuleName ZertoApiWrapper -CommandName Invoke-ZertoRestRequest -Exactly 4 - Assert-MockCalled -ModuleName ZertoApiWrapper -CommandName Get-ZertoLocalSite -Exactly 4 } } } diff --git a/ZertoApiWrapper.Depend.psd1 b/ZertoApiWrapper.Depend.psd1 index 820e1f4..e3f8356 100644 --- a/ZertoApiWrapper.Depend.psd1 +++ b/ZertoApiWrapper.Depend.psd1 @@ -7,7 +7,7 @@ SkipPublisherCheck = $true } Target = 'CurrentUser' - Version = '5.5.11' + Version = '5.6.0' Tags = 'Bootstrap' } @@ -31,7 +31,7 @@ SkipPublisherCheck = $true } Target = 'CurrentUser' - Version = '1.18.3' + Version = '1.19.0' Tags = 'Bootstrap' } diff --git a/ZertoApiWrapper.build.ps1 b/ZertoApiWrapper.build.ps1 index 853d110..08efbac 100644 --- a/ZertoApiWrapper.build.ps1 +++ b/ZertoApiWrapper.build.ps1 @@ -1,23 +1,24 @@ #Requires -Modules 'InvokeBuild' $version = "{0}" -f $(Get-Content .\version.txt) +$moduleOutPath = "{0}\publish\ZertoApiWrapper" -f $BuildRoot #Define the default task -task . CreateArtifacts +task . build #Region - Helper Functions -function ImportSourceModule() { +function ImportSourceModule { If (Get-Module -Name ZertoApiWrapper) { Remove-Module -Name ZertoApiWrapper -Force -ErrorAction Stop } Import-Module "$BuildRoot\ZertoApiWrapper\ZertoApiWrapper.psd1" -ErrorAction Stop } -function ImportBuiltModule() { +function ImportBuiltModule { If (Get-Module -Name ZertoApiWrapper) { Remove-Module -Name ZertoApiWrapper -Force -ErrorAction Stop } - Import-Module "$BuildRoot\temp\ZertoApiWrapper.psd1" -ErrorAction Stop + Import-Module ("{0}\ZertoApiWrapper.psd1" -f $moduleOutPath) -ErrorAction Stop } #EndRegion @@ -65,7 +66,7 @@ task AnalyzeSourceFiles CheckPSScriptAnalyzerInstalled, { task AnalyzeBuiltFiles CheckPSScriptAnalyzerInstalled, CreatePsm1ForRelease, { $scriptAnalyzerParams = @{ - Path = "$BuildRoot\temp\" + Path = $moduleOutPath Severity = @('Error', 'Warning') Recurse = $true Verbose = $false @@ -81,17 +82,13 @@ task AnalyzeBuiltFiles CheckPSScriptAnalyzerInstalled, CreatePsm1ForRelease, { #EndRegion #Region - Clean Operations -task CleanTemp { - if (-not $(Test-Path "$BuildRoot\temp")) { - New-Item -Path $BuildRoot -Name "temp" -ItemType "Directory" - } - Remove-Item -Recurse -Path "$BuildRoot\temp\*" -} - task CleanPublish { if ($(Test-Path "$BuildRoot\publish")) { Remove-Item -Recurse -Path "$BuildRoot\publish\*" + } else { + New-Item -Path $BuildRoot -Name "publish" -ItemType Directory } + New-Item -Path $moduleOutPath -ItemType "Directory" } #EndRegion @@ -107,7 +104,7 @@ task SourceFileTests CheckPesterInstalled, { task BuiltFileTests CreatePsm1ForRelease, CheckPesterInstalled, { ImportBuiltModule $testResultsFile = "$BuildRoot\Tests\BuiltTestResults.xml" - $script:results = Invoke-Pester -Script "$BuildRoot" -Tag Unit -OutputFile $testResultsFile -PassThru -Show Fails + $script:results = Invoke-Pester -Script "$BuildRoot" -Tag Unit -OutputFile $testResultsFile -PassThru -Show Failed $FailureMessage = '{0} Unit test(s) failed. Aborting build' -f $results.FailedCount Assert ($results.FailedCount -eq 0) $FailureMessage } @@ -116,7 +113,7 @@ task BuiltFileTests CreatePsm1ForRelease, CheckPesterInstalled, { #Region - Build Help System $buildMamlParams = @{ Inputs = { Get-ChildItem docs\*.md } - Outputs = "$BuildRoot\temp\en-us\ZertoApiWrapper-help.xml" + Outputs = "{0}\en-us\ZertoApiWrapper-help.xml" -f $moduleOutPath } task BuildMamlHelp CheckPlatyPSInstalled, { @@ -126,19 +123,19 @@ task BuildMamlHelp CheckPlatyPSInstalled, { platyPS\New-ExternalHelp .\docs -Force -OutputPath $buildMamlParams.Outputs } -task UpdateMarkdownHelp CheckPlatyPSInstalled, { - ImportSourceModule +task UpdateMarkdownHelp quickBuild, CheckPlatyPSInstalled, { + ImportBuiltModule Update-MarkdownHelpModule -Path docs -AlphabeticParamsOrder } #EndRegion #Region - Build Module Files -task CreatePsd1ForRelease CleanTemp, { +task CreatePsd1ForRelease CleanPublish, { $functionsToExport = Get-ChildItem -Path 'ZertoApiWrapper\Public\*.ps1' | ForEach-Object { $_.BaseName } $releaseNotes = "Please review the [Release Notes](https://github.com/ZertoPublic/ZertoApiWrapper/releases/tag/{0}) on GitHub." -f $version $ManifestParams = @{ - Path = "$BuildRoot\temp\ZertoApiWrapper.psd1" + Path = "{0}\ZertoApiWrapper.psd1" -f $moduleOutPath RootModule = 'ZertoApiWrapper.psm1' ModuleVersion = $version GUID = '4c0b9e17-141b-4dd5-8549-fb21cccaa325' @@ -161,43 +158,47 @@ task CreatePsd1ForRelease CleanTemp, { task CreatePsm1ForRelease CreatePsd1ForRelease, { $emptyLine = "" - $psm1Path = "$BuildRoot\temp\ZertoApiWrapper.psm1" + $psm1Path = "{0}\ZertoApiWrapper.psm1" -f $moduleOutPath $lines = '#------------------------------------------------------------#' $Private = @( Get-ChildItem -Path $BuildRoot\ZertoApiWrapper\Private\*.ps1 -ErrorAction Stop ) $Public = @( Get-ChildItem -Path $BuildRoot\ZertoApiWrapper\Public\*.ps1 -ErrorAction Stop ) - Add-Content -Path $psm1Path -Value $lines - Add-Content -Path $psm1Path -Value "#---------------------Private Functions----------------------#" - Add-Content -Path $psm1Path -Value $lines - Add-Content -Path $psm1Path -Value $emptyLine + Add-Content -Path $psm1Path -Value $lines -Encoding 'utf8' + Add-Content -Path $psm1Path -Value "#---------------------Private Functions----------------------#" -Encoding 'utf8' + Add-Content -Path $psm1Path -Value $lines -Encoding 'utf8' + Add-Content -Path $psm1Path -Value $emptyLine -Encoding 'utf8' foreach ($file in $private) { - Add-Content -Path $psm1Path -Value $(Get-Content -Path $file.Fullname -Raw) - Add-Content -Path $psm1Path -Value $emptyLine + Add-Content -Path $psm1Path -Value $(Get-Content -Path $file.Fullname -Raw) -Encoding 'utf8' + Add-Content -Path $psm1Path -Value $emptyLine -Encoding 'utf8' } - Add-Content -Path $psm1Path -Value $lines - Add-Content -Path $psm1Path -Value "#----------------------Public Functions----------------------#" - Add-Content -Path $psm1Path -Value $lines - Add-Content -Path $psm1Path -Value $emptyLine + Add-Content -Path $psm1Path -Value $lines -Encoding 'utf8' + Add-Content -Path $psm1Path -Value "#----------------------Public Functions----------------------#" -Encoding 'utf8' + Add-Content -Path $psm1Path -Value $lines -Encoding 'utf8' + Add-Content -Path $psm1Path -Value $emptyLine -Encoding 'utf8' foreach ($file in $public) { - Add-Content -Path $psm1Path -Value $(Get-Content -Path $file.Fullname -Raw) - Add-Content -Path $psm1Path -Value $emptyLine + Add-Content -Path $psm1Path -Value $(Get-Content -Path $file.Fullname -Raw) -Encoding 'utf8' + Add-Content -Path $psm1Path -Value $emptyLine -Encoding 'utf8' } - # Add-Content -Path $psm1Path -Value $emptyLine - # Add-Content -Path $psm1Path -Value "Export-ModuleMember -Function $exportString" } #EndRegion #Region - Artifacts \ Publish # Full Build Process - No Publishing -task CreateArtifacts CleanPublish, CleanTemp, AnalyzeSourceFiles, SourceFileTests, AnalyzeBuiltFiles, BuiltFileTests, BuildMamlHelp, { - if (-not $(Test-Path "$BuildRoot\publish")) { - New-Item -Path $BuildRoot -Name "publish" -ItemType Directory +task CreateArtifacts CleanPublish, AnalyzeBuiltFiles, BuiltFileTests, BuildMamlHelp, { + Compress-Archive -Path $moduleOutPath -DestinationPath .\publish\ZertoApiWrapper.zip + $MyMatches = Select-String -Path "$BuildRoot\CHANGELOG.md" "^##\s\[" + $data = Get-Content "$BuildRoot\CHANGELOG.md" + $range = ($MyMatches[0].LineNumber - 1)..($MyMatches[1].LineNumber - 3) + foreach ($i in $range) { + Add-Content -Path "$BuildRoot\publish\ReleaseNotes.md" -Value ($data[$i]).replace("## ", "# ") -Encoding utf8 } - Compress-Archive -Path .\temp\* -DestinationPath .\publish\ZertoApiWrapper.zip - #ImportBuiltModule - #(Get-Module ZertoApiWrapper).ReleaseNotes | Add-Content .\publish\release-notes.txt - #(Get-Module ZertoApiWrapper).Version.ToString() | Add-Content .\publish\release-version.txt - Copy-Item "$BuildRoot\ZertoApiWrapper.build.ps1" "$BuildRoot\publish\ZertoApiWrapper.build.ps1" - Copy-Item "$BuildRoot\ZertoApiWrapper.Depend.psd1" "$BuildRoot\publish\ZertoApiWrapper.Depend.psd1" - Copy-Item "$BuildRoot\build.ps1" "$BuildRoot\publish\build.ps1" } #EndRegion + +task build CleanPublish, CreatePsm1ForRelease, AnalyzeBuiltFiles, BuiltFileTests, CreateArtifacts +task quickBuild CleanPublish, CreatePsm1ForRelease, AnalyzeBuiltFiles, { + Get-Module -Name ZertoApiWrapper | Remove-Module -Force + ImportBuiltModule +} +task release build, { + Publish-Module -Path $moduleOutPath -NuGetApiKey "1234" -WhatIf +} diff --git a/ZertoApiWrapper/Public/Connect-ZertoServer.ps1 b/ZertoApiWrapper/Public/Connect-ZertoServer.ps1 index f9f33ac..237f845 100644 --- a/ZertoApiWrapper/Public/Connect-ZertoServer.ps1 +++ b/ZertoApiWrapper/Public/Connect-ZertoServer.ps1 @@ -5,11 +5,18 @@ function Connect-ZertoServer { param( [Parameter( Mandatory, - HelpMessage = "IP address or FQDN of your Zerto Management Server" + HelpMessage = "IP address or FQDN of your Zerto Management Server", + Position = 0 )] [ValidateNotNullOrEmpty()] [Alias("server", "zvm")] [string]$zertoServer, + [Parameter( + Mandatory, + HelpMessage = "Valid credentials to connect to the Zerto Management Server", + Position = 1 + )] + [System.Management.Automation.PSCredential]$credential, [Parameter( HelpMessage = "Zerto Virtual Manager management port. Default value is 9669." )] @@ -18,11 +25,14 @@ function Connect-ZertoServer { [Alias("port")] [string]$zertoPort = "9669", [Parameter( - Mandatory, - HelpMessage = "Valid credentials to connect to the Zerto Management Server" + 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, + [Parameter( + HelpMessage = "Use this switch to return the headers to a specified variable or to the default output." )] - [System.Management.Automation.PSCredential]$credential, [switch]$returnHeaders + ) begin { @@ -38,6 +48,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 { @@ -48,10 +62,7 @@ function Connect-ZertoServer { end { # Build Headers Hashtable with Authorization Token $Script:zvmHeaders['x-zerto-session'] = $results.Headers['x-zerto-session'][0].ToString() - # Set common Script Scope Variables to be used other functions (Headers and Local Site Info) - # Set-Variable -Name zvmHeaders -Scope Script -Value $zertoAuthorizationHeaders - Set-Variable -Name zvmLocalInfo -Scope Script -Value (Get-ZertoLocalSite) - + # Have the option to return the headers to a variable if ($returnHeaders) { return $Script:zvmHeaders diff --git a/ZertoApiWrapper/Public/Disconnect-ZertoServer.ps1 b/ZertoApiWrapper/Public/Disconnect-ZertoServer.ps1 index b9d3032..080ec50 100644 --- a/ZertoApiWrapper/Public/Disconnect-ZertoServer.ps1 +++ b/ZertoApiWrapper/Public/Disconnect-ZertoServer.ps1 @@ -12,5 +12,4 @@ function Disconnect-ZertoServer { Remove-Variable -Name zvmPort -Scope Script Remove-Variable -Name zvmLastAction -Scope Script Remove-Variable -Name zvmHeaders -Scope Script - Remove-Variable -Name zvmLocalInfo -Scope Script } diff --git a/ZertoApiWrapper/Public/Get-ZertoUnprotectedVm.ps1 b/ZertoApiWrapper/Public/Get-ZertoUnprotectedVm.ps1 index d76e96c..68a20f4 100644 --- a/ZertoApiWrapper/Public/Get-ZertoUnprotectedVm.ps1 +++ b/ZertoApiWrapper/Public/Get-ZertoUnprotectedVm.ps1 @@ -2,6 +2,6 @@ function Get-ZertoUnprotectedVm { [cmdletbinding()] param() - $uri = "virtualizationsites/{0}/vms" -f $script:zvmLocalInfo.siteidentifier + $uri = "virtualizationsites/{0}/vms" -f (Get-ZertoLocalSite).siteIdentifier Invoke-ZertoRestRequest -uri $uri } diff --git a/ZertoApiWrapper/Public/Install-ZertoVra.ps1 b/ZertoApiWrapper/Public/Install-ZertoVra.ps1 index 70f74a5..3ce61d2 100644 --- a/ZertoApiWrapper/Public/Install-ZertoVra.ps1 +++ b/ZertoApiWrapper/Public/Install-ZertoVra.ps1 @@ -111,7 +111,7 @@ function Install-ZertoVra { # If the VRA does not exist, proceed with the installation. If it does exist, bypass and if ( -not (Get-ZertoVra -vraName $vraName) ) { # Get identifiers for each item provided by name. - $siteIdentifier = $script:zvmLocalInfo.SiteIdentifier + $siteIdentifier = (Get-ZertoLocalSite).SiteIdentifier $hostIdentifier = Get-ZertoVirtualizationSite -siteIdentifier $siteIdentifier -hosts | Where-Object { $_.VirtualizationHostName -eq $hostName } | Select-Object hostIdentifier -ExpandProperty hostIdentifier $networkIdentifier = Get-ZertoVirtualizationSite -siteIdentifier $siteIdentifier -networks | Where-Object { $_.VirtualizationNetworkName -eq $networkName } | Select-Object NetworkIdentifier -ExpandProperty NetworkIdentifier $datastoreIdentifier = Get-ZertoVirtualizationSite -siteIdentifier $siteIdentifier -datastores | Where-Object { $_.DatastoreName -eq $datastoreName } | Select-Object DatastoreIdentifier -ExpandProperty DatastoreIdentifier 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 + #} } } diff --git a/ZertoApiWrapper/Public/New-ZertoVpg.ps1 b/ZertoApiWrapper/Public/New-ZertoVpg.ps1 index 4ae6f60..710f51d 100644 --- a/ZertoApiWrapper/Public/New-ZertoVpg.ps1 +++ b/ZertoApiWrapper/Public/New-ZertoVpg.ps1 @@ -1,6 +1,6 @@ <# .ExternalHelp ./en-us/ZertoApiWrapper-help.xml #> function New-ZertoVpg { - [cmdletbinding(SupportsShouldProcess = $true)] + [cmdletbinding(SupportsShouldProcess = $true, DefaultParameterSetName = "recoveryHostDatastore")] param( [Parameter( HelpMessage = "Name of the VPG", @@ -165,7 +165,7 @@ function New-ZertoVpg { begin { # Create an identifiers table, and start converting names to identifiers. $identifiersTable = @{ } - $identifiersTable['recoverySiteIdentifier'] = $(Get-ZertoPeerSite -peerName $recoverySite).siteIdentifier + $identifiersTable['recoverySiteIdentifier'] = (Get-ZertoPeerSite).Where({$_.PeerSiteName -like $recoverySite}) | Select-Object -ExpandProperty SiteIdentifier $peerSiteNetworks = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -networks) $identifiersTable['failoverNetworkIdentifier'] = $peerSiteNetworks | Where-Object { $_.VirtualizationNetworkName -like $recoveryNetwork } | Select-Object -ExpandProperty NetworkIdentifier $identifiersTable['testNetworkIdentifier'] = $peerSiteNetworks | Where-Object { $_.VirtualizationNetworkName -like $testNetwork } | Select-Object -ExpandProperty NetworkIdentifier @@ -182,18 +182,18 @@ function New-ZertoVpg { # Get identifiers based on parameter set name switch ($PSCmdlet.ParameterSetName) { "recoveryClusterDatastoreCluster" { - $identifiersTable['clusterIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -hostclusters | Where-Object { $_.VirtualizationClusterName -like $recoveryCluster }).ClusterIdentifier - $identifiersTable['datastoreClusterIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -datastoreclusters | Where-Object { $_.DatastoreClusterName -like $datastoreCluster }).DatastoreClusterIdentifier + $identifiersTable['clusterIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -hostClusters | Where-Object { $_.VirtualizationClusterName -like $recoveryCluster }).ClusterIdentifier + $identifiersTable['datastoreClusterIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -datastoreClusters | Where-Object { $_.DatastoreClusterName -like $datastoreCluster }).DatastoreClusterIdentifier } "recoveryClusterDatastore" { - $identifiersTable['clusterIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -hostclusters | Where-Object { $_.VirtualizationClusterName -like $recoveryCluster }).ClusterIdentifier + $identifiersTable['clusterIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -hostClusters | Where-Object { $_.VirtualizationClusterName -like $recoveryCluster }).ClusterIdentifier $identifiersTable['datastoreIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -datastores | Where-Object { $_.DatastoreName -like $datastore }).DatastoreIdentifier } "recoveryHostDatastoreCluster" { $identifiersTable['recoveryHostIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -hosts | Where-Object { $_.VirtualizationHostName -like $recoveryHost }).HostIdentifier - $identifiersTable['datastoreClusterIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -datastoreclusters | Where-Object { $_.DatastoreClusterName -like $datastoreCluster }).DatastoreClusterIdentifier + $identifiersTable['datastoreClusterIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -datastoreClusters | Where-Object { $_.DatastoreClusterName -like $datastoreCluster }).DatastoreClusterIdentifier } "recoveryHostDatastore" { @@ -202,12 +202,12 @@ function New-ZertoVpg { } "recoveryResourcePoolDatastoreCluster" { - $identifiersTable['recoveryResourcePoolIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -resourcepools | Where-Object { $_.ResourcePoolName -like $recoveryResourcePool }).ResourcePoolIdentifier - $identifiersTable['datastoreClusterIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -datastoreclusters | Where-Object { $_.DatastoreClusterName -like $datastoreCluster }).DatastoreClusterIdentifier + $identifiersTable['recoveryResourcePoolIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -resourcePools | Where-Object { $_.ResourcePoolName -like $recoveryResourcePool }).ResourcePoolIdentifier + $identifiersTable['datastoreClusterIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -datastoreClusters | Where-Object { $_.DatastoreClusterName -like $datastoreCluster }).DatastoreClusterIdentifier } "recoveryResourcePoolDatastore" { - $identifiersTable['recoveryResourcePoolIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -resourcepools | Where-Object { $_.ResourcePoolName -like $recoveryResourcePool }).ResourcePoolIdentifier + $identifiersTable['recoveryResourcePoolIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -resourcePools | Where-Object { $_.ResourcePoolName -like $recoveryResourcePool }).ResourcePoolIdentifier $identifiersTable['datastoreIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -datastores | Where-Object { $_.DatastoreName -like $datastore }).DatastoreIdentifier } } diff --git a/ZertoApiWrapper/Public/Set-ZertoLicense.ps1 b/ZertoApiWrapper/Public/Set-ZertoLicense.ps1 index aa95042..90fdd47 100644 --- a/ZertoApiWrapper/Public/Set-ZertoLicense.ps1 +++ b/ZertoApiWrapper/Public/Set-ZertoLicense.ps1 @@ -16,7 +16,7 @@ function Set-ZertoLicense { } process { - if ($PSCmdlet.ShouldProcess()) { + if ($PSCmdlet.ShouldProcess("Applying License Key: $licenseKey to server: $($script:zvmServer)")) { Invoke-ZertoRestRequest -uri $baseUri -body $($body | ConvertTo-Json) -method "PUT" } } diff --git a/azure-pipelines.yml b/azure-pipelines.yml index e5c7180..b20a9a2 100644 --- a/azure-pipelines.yml +++ b/azure-pipelines.yml @@ -11,6 +11,7 @@ trigger: include: - master - PowerShellBackPort + - Refactor-Build # Trigger CI on pull requests to master and develop branches pr: @@ -24,26 +25,18 @@ jobs: pool: vmImage: windows-latest steps: - # Run build.ps1 script in PowerShell Core - - powershell: | - .\build.ps1 -Verbose - displayName: 'Build and Test' - # Upload test results to Azure Pipeline - - task: PublishTestResults@2 - inputs: - testRunner: 'NUnit' - testResultsFiles: '**/SourceTestResults.xml' - testRunTitle: 'PS_Win2016_Source' - displayName: 'Publish Test Results' - condition: always() - - task: PublishTestResults@2 - inputs: - testRunner: 'NUnit' - testResultsFiles: '**/BuiltTestResults.xml' - testRunTitle: 'PS_Win2016_Built' - displayName: 'Publish Test Results' - condition: always() - + # Run build.ps1 script in PowerShell Core + - powershell: | + .\build.ps1 -Verbose + displayName: "Build and Test" + # Upload test results to Azure Pipeline + - task: PublishTestResults@2 + inputs: + testRunner: "NUnit" + testResultsFiles: "**/BuiltTestResults.xml" + testRunTitle: "PS_Win2016_Built" + displayName: "Publish Test Results" + condition: always() # Windows PowerShell Core Build Job - job: Build_PSCore_Windows @@ -52,25 +45,18 @@ jobs: pool: vmImage: windows-latest steps: - # Run build.ps1 script in PowerShell Core - - pwsh: | - .\build.ps1 -Verbose - displayName: 'Build and Test' - # Upload test results to Azure Pipeline - - task: PublishTestResults@2 - inputs: - testRunner: 'NUnit' - testResultsFiles: '**/SourceTestResults.xml' - testRunTitle: 'PSCore_Win2016_Source' - displayName: 'Publish Test Results' - condition: always() - - task: PublishTestResults@2 - inputs: - testRunner: 'NUnit' - testResultsFiles: '**/BuiltTestResults.xml' - testRunTitle: 'PSCore_Win2016_Built' - displayName: 'Publish Test Results' - condition: always() + # Run build.ps1 script in PowerShell Core + - pwsh: | + .\build.ps1 -Verbose + displayName: "Build and Test" + # Upload test results to Azure Pipeline + - task: PublishTestResults@2 + inputs: + testRunner: "NUnit" + testResultsFiles: "**/BuiltTestResults.xml" + testRunTitle: "PSCore_Win2016_Built" + displayName: "Publish Test Results" + condition: always() # Linux Build Job - job: Build_PSCore_Ubuntu @@ -79,37 +65,24 @@ jobs: pool: vmImage: ubuntu-latest steps: - # Run build.ps1 script in PowerShell Core - - pwsh: | - .\build.ps1 -verbose - displayName: 'Build and Test' - # Upload test results to Azure Pipeline - - task: PublishTestResults@2 - inputs: - testRunner: 'NUnit' - testResultsFiles: '**/SourceTestResults.xml' - testRunTitle: 'PSCore_Ubuntu_Source' - displayName: 'Publish Test Results' - condition: always() - - task: PublishTestResults@2 - inputs: - testRunner: 'NUnit' - testResultsFiles: '**/BuiltTestResults.xml' - testRunTitle: 'PSCore_Ubuntu_Built' - displayName: 'Publish Test Results' - condition: always() - - task: PublishPipelineArtifact@0 - displayName: 'Publish compiled module Artifact' - inputs: - artifactName: 'ZertoApiWrapper' - targetPath: ./temp - condition: always() - - task: PublishPipelineArtifact@0 - displayName: 'Publish Data' - inputs: - artifactName: 'ReleaseData' - targetPath: ./publish - condition: always() + # Run build.ps1 script in PowerShell Core + - pwsh: | + .\build.ps1 -verbose + displayName: "Build and Test" + # Upload test results to Azure Pipeline + - task: PublishTestResults@2 + inputs: + testRunner: "NUnit" + testResultsFiles: "**/BuiltTestResults.xml" + testRunTitle: "PSCore_Ubuntu_Built" + displayName: "Publish Test Results" + condition: always() + - task: PublishPipelineArtifact@1 + displayName: "Publish Data" + inputs: + artifactName: "ReleaseData" + targetPath: ./publish + condition: always() # MacOS Build Job - job: Build_PSCore_MacOS @@ -118,22 +91,15 @@ jobs: pool: vmImage: macOS-latest steps: - # Run build.ps1 script in PowerShell Core - - pwsh: | - .\build.ps1 -verbose - displayName: 'Build and Test' - # Upload test results to Azure Pipeline - - task: PublishTestResults@2 - inputs: - testRunner: 'NUnit' - testResultsFiles: '**/SourceTestResults.xml' - testRunTitle: 'PSCore_MacOS1013_Source' - displayName: 'Publish Test Results' - condition: always() - - task: PublishTestResults@2 - inputs: - testRunner: 'NUnit' - testResultsFiles: '**/BuiltTestResults.xml' - testRunTitle: 'PSCore_MacOS1013_Built' - displayName: 'Publish Test Results' - condition: always() + # Run build.ps1 script in PowerShell Core + - pwsh: | + .\build.ps1 -verbose + displayName: "Build and Test" + # Upload test results to Azure Pipeline + - task: PublishTestResults@2 + inputs: + testRunner: "NUnit" + testResultsFiles: "**/BuiltTestResults.xml" + testRunTitle: "PSCore_MacOS1013_Built" + displayName: "Publish Test Results" + condition: always() diff --git a/build.ps1 b/build.ps1 index 9ce90cf..2f2c873 100644 --- a/build.ps1 +++ b/build.ps1 @@ -1,3 +1,5 @@ +param([validateSet("build", "release")]$operation = "build") + # Bootstrap the environment $null = Get-PackageProvider -Name NuGet -ForceBootstrap @@ -11,6 +13,7 @@ Invoke-PSDepend ` -Force ` -Import ` -Install ` - -Tags 'Bootstrap' + -Tags 'Bootstrap' ` + -ErrorAction Continue -Invoke-Build . +Invoke-Build $operation diff --git a/docs/Add-ZertoPeerSite.md b/docs/Add-ZertoPeerSite.md index 7fafff4..72d82c2 100644 --- a/docs/Add-ZertoPeerSite.md +++ b/docs/Add-ZertoPeerSite.md @@ -31,10 +31,10 @@ Pairs the current Zerto Virtual Manager to the Zerto Virtual Manager at IP addre ### Example 2 ```powershell -PS C:\> Add-ZertoPeerSite -targetHost "192.168.2.100" -token "GeneratedFromTargetZVM" +PS C:\> Add-ZertoPeerSite -targetHost "192.168.2.100" -targetPort "9071" -token "GeneratedFromTargetZVM" ``` -Pairs the current Zerto Virtual Manager to the Zerto Virtual Manager at IP address 192.168.2.100. Use this method when pairing Zerto Virtual Managers that are version 7.5 or later. +Pairs the current Zerto Virtual Manager to the Zerto Virtual Manager at IP address 192.168.2.100 over Port 9071. Use this method when pairing Zerto Virtual Managers that are version 7.5 or later. ## PARAMETERS diff --git a/docs/Connect-ZertoServer.md b/docs/Connect-ZertoServer.md index 160ac31..9a08e8d 100644 --- a/docs/Connect-ZertoServer.md +++ b/docs/Connect-ZertoServer.md @@ -1,112 +1,135 @@ ---- -external help file: ZertoApiWrapper-help.xml -Module Name: ZertoApiWrapper -online version: https://github.com/ZertoPublic/ZertoApiWrapper/blob/master/docs/Connect-ZertoServer.md -schema: 2.0.0 ---- - -# Connect-ZertoServer - -## SYNOPSIS -Establishes a connection to a ZVM. - -## SYNTAX - -``` -Connect-ZertoServer [-zertoServer] [[-zertoPort] ] [-credential] - [-returnHeaders] [] -``` - -## DESCRIPTION -Establishes a connection to a ZVM using credentials provided via a PSCredential Object leveraging the Zerto Session API end point. - -## EXAMPLES - -### Example 1 -```powershell -PS C:\> Connect-ZertoServer -zertoServer "192.168.1.100" -zertoPort "9669" -credential $credential -``` - -Establishes a connection to ZVM 192.168.1.100 on port 9669 with supplied PSCredential object. - -## PARAMETERS - -### -credential -Valid credentials to connect to the Zerto Management Server - -```yaml -Type: PSCredential -Parameter Sets: (All) -Aliases: - -Required: True -Position: 2 -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -returnHeaders -Use this switch to return the headers to a specified variable or to the default output. - -```yaml -Type: SwitchParameter -Parameter Sets: (All) -Aliases: - -Required: False -Position: Named -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -zertoPort -Zerto Virtual Manager management port. -Default value is 9669. - -```yaml -Type: String -Parameter Sets: (All) -Aliases: port - -Required: False -Position: 1 -Default value: "9669" -Accept pipeline input: False -Accept wildcard characters: False -``` - -### -zertoServer -IP address or FQDN of your Zerto Management Server - -```yaml -Type: String -Parameter Sets: (All) -Aliases: server, zvm - -Required: True -Position: 0 -Default value: None -Accept pipeline input: False -Accept wildcard characters: False -``` - -### CommonParameters -This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). - -## INPUTS - -### None -## OUTPUTS - -### System.Object -## NOTES - -## RELATED LINKS - -[Zerto REST API Session End Point Documentation](http://s3.amazonaws.com/zertodownload_docs/Latest/Zerto%20Virtual%20Replication%20Zerto%20Virtual%20Manager%20%28ZVM%29%20-%20vSphere%20Online%20Help/index.html#page/RestfulAPIs%2FStatusAPIs.5.068.html%23) - -[PSCredential Documentation](https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.pscredential?view=pscore-6.0.0) - -[Get-Credential Documentation](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/get-credential?view=powershell-6) +--- +external help file: ZertoApiWrapper-help.xml +Module Name: ZertoApiWrapper +online version: https://github.com/ZertoPublic/ZertoApiWrapper/blob/master/docs/Connect-ZertoServer.md +schema: 2.0.0 +--- + +# Connect-ZertoServer + +## SYNOPSIS +Establishes a connection to a ZVM. + +## SYNTAX + +``` +Connect-ZertoServer [-zertoServer] [-credential] [-zertoPort ] [-AutoReconnect] + [-returnHeaders] [] +``` + +## DESCRIPTION +Establishes a connection to a ZVM using credentials provided via a PSCredential Object leveraging the Zerto Session API end point. + +## EXAMPLES + +### Example 1 +```powershell +PS C:\> Connect-ZertoServer -zertoServer "192.168.1.100" -zertoPort "9669" -credential $credential +``` + +Establishes a connection to ZVM 192.168.1.100 on port 9669 with supplied PSCredential object. + +### Example 2 +```powershell +PS C:\> Connect-ZertoServer -zertoServer "192.168.1.100" -zertoPort "9669" -credential $credential -AutoReconnect +``` + +Establishes a connection to ZVM 192.168.1.100 on port 9669 with supplied PSCredential object. Adding the `-AutoReconnect` switch +will cache the PSCredential object should the session need to be reauthorized due to an expired token. + +## PARAMETERS + +### -AutoReconnect +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 + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -credential +Valid credentials to connect to the Zerto Management Server + +```yaml +Type: PSCredential +Parameter Sets: (All) +Aliases: + +Required: True +Position: 1 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -returnHeaders +Use this switch to return the headers to a specified variable or to the default output. + +```yaml +Type: SwitchParameter +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -zertoPort +Zerto Virtual Manager management port. +Default value is 9669. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: port + +Required: False +Position: Named +Default value: "9669" +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -zertoServer +IP address or FQDN of your Zerto Management Server + +```yaml +Type: String +Parameter Sets: (All) +Aliases: server, zvm + +Required: True +Position: 0 +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### CommonParameters +This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable, -InformationAction, -InformationVariable, -OutVariable, -OutBuffer, -PipelineVariable, -Verbose, -WarningAction, and -WarningVariable. For more information, see [about_CommonParameters](http://go.microsoft.com/fwlink/?LinkID=113216). + +## INPUTS + +### None +## OUTPUTS + +### System.Object +## NOTES + +## RELATED LINKS + +[Zerto REST API Session End Point Documentation](http://s3.amazonaws.com/zertodownload_docs/Latest/Zerto%20Virtual%20Replication%20Zerto%20Virtual%20Manager%20%28ZVM%29%20-%20vSphere%20Online%20Help/index.html#page/RestfulAPIs%2FStatusAPIs.5.068.html%23) + +[PSCredential Documentation](https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.pscredential?view=pscore-6.0.0) + +[Get-Credential Documentation](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/get-credential?view=powershell-6) diff --git a/docs/Get-ZertoEvent.md b/docs/Get-ZertoEvent.md index d9e842e..25532cb 100644 --- a/docs/Get-ZertoEvent.md +++ b/docs/Get-ZertoEvent.md @@ -66,13 +66,27 @@ PS C:\> Get-ZertoEvent -eventId "Need an eventID" Returns information for each -eventID specified. -### Example 1 +### Example 3 ```powershell PS C:\> Get-ZertoEvent -startDate "2019-01-01" -endDate "2019-01-07" -vpg "My Vpg" ``` Returns all events between Jan. 01, 2019 and Jan. 07, 2019 (inclusive) for the vpg "My Vpg" +### Example 4 +```powershell +PS C:\> Get-ZertoEvent -userName "Domain.tld\MyUser +``` + +Returns all events associated with the username passed into the command. + +### Example 5 +```powershell +PS C:\> Get-ZertoEvent -startDate "2019-01-01T12:30:00" -endDate "2019-01-01T13:30:00" -vpg "My Vpg" +``` + +Returns all events between Jan. 01, 2019 12:30 PM and Jan. 01, 2019 1:30 PM (inclusive) for the vpg "My Vpg" + ## PARAMETERS ### -alertIdentifier diff --git a/version.txt b/version.txt index 9df886c..428b770 100644 --- a/version.txt +++ b/version.txt @@ -1 +1 @@ -1.4.2 +1.4.3