119 Commits

Author SHA1 Message Date
Wes Carroll a2d724a54c Merge pull request #114 from ZertoPublic/wcarroll/where-fix
Wcarroll/where fix
2020-12-16 13:14:46 -05:00
Wes Carroll f06157c75e Bump Version for Release 2020-12-16 13:10:02 -05:00
Wes Carroll d413374c09 CHANGLOG Updates 2020-12-16 09:43:22 -05:00
Wes Carroll 1513cd4f4b Update Synopsis 2020-12-16 09:42:48 -05:00
Wes Carroll 1daac508b2 Update SiteId Lookup Method 2020-12-16 09:42:23 -05:00
Wes Carroll a22d9e3416 Merge pull request #113 from ZertoPublic/wcarroll/issue112
SiteId Query to VirtualizationSites Fixes #112
2020-12-09 21:57:36 -05:00
Wes Carroll 06e81b46d6 Update CHANGELOG for #112 2020-12-09 17:09:53 -05:00
Wes Carroll af33715f02 SiteId Query to VirtualizationSites Fixes #112 2020-12-09 16:13:50 -05:00
Wes Carroll 912bca0f9c Merge pull request #111 from ZertoPublic/export_bug_fix
Export bug fix
2020-10-19 19:10:37 -04:00
Wes Carroll 4ac951607b Add required Mock 2020-10-19 18:43:13 -04:00
Wes Carroll d3d01f892f Bump Version 2020-10-19 18:35:30 -04:00
Wes Carroll 84b7922156 Update CHANGELOG 2020-10-19 18:24:08 -04:00
Wes Carroll 0eaf89608b Clean up VPG Settings Identifier 2020-10-19 18:22:10 -04:00
Wes Carroll 50e03b36f5 Merge pull request #110 from ZertoPublic/Release
Release into Master
2020-09-08 08:55:07 -04:00
Wes Carroll 4531d2d53b Merge branch 'release_prep' into Release 2020-09-08 08:22:32 -04:00
Wes Carroll e6e6be9ede Bump Version 2020-09-08 08:21:10 -04:00
Wes Carroll 5c2dd620d8 Update for Release Notes 2020-09-08 08:20:29 -04:00
Wes Carroll a5a91febcf Merge pull request #109 from jonsouzerto/master
Fixed issue 108
2020-09-04 10:28:45 -04:00
jonsouzerto bb5dbaa0d4 Update CHANGELOG.md
Added fix information
2020-09-03 12:50:49 -04:00
jonsouzerto e6b5777e64 Updated recovery host key
Attempting to resolve issue 108
2020-09-03 12:45:35 -04:00
Wes Carroll ddee165575 Merge pull request #107 from gdbarron/invoke-move-updates
Invoke-ZertoMove parameter, pipeline, and restructuring updates
2020-08-28 13:48:34 -04:00
Brownstein f0279633dd add missing .IsPresent for switch value 2020-08-28 13:43:22 -04:00
Brownstein 139e52f3e2 add new parameter to test 2020-08-27 15:28:01 -04:00
Brownstein eea6e95988 update test and help files 2020-08-27 15:08:28 -04:00
Brownstein 0630cbb20e new param sets, pipeline input 2020-08-21 21:04:15 -04:00
Wes Carroll 682750fc6d Merge pull request #106 from ZertoPublic/Release
Merge pull request #105 from ZertoPublic/master
2020-08-20 13:44:03 -04:00
Wes Carroll 9dc9aa92d0 Merge pull request #105 from ZertoPublic/master
Release 1.5.0
2020-08-20 13:31:28 -04:00
Wes Carroll 23e0b8a665 Prepping for next release 2020-08-20 13:25:37 -04:00
Wes Carroll ae53dcd4d2 Merge pull request #104 from ZertoPublic/wcarroll/issue103
Update target host validation
2020-08-20 12:39:21 -04:00
Wes Carroll ced5671ab2 Update target host validation 2020-08-20 12:29:40 -04:00
Wes Carroll cb528df3d4 Merge pull request #102 from ZertoPublic/Add-VMToVpg
Add-ZertoVpgVm and Remove-ZertoVpgVm
2020-08-05 09:41:09 -04:00
Wes Carroll c91d53ecad Update with changes 2020-08-05 09:34:35 -04:00
Wes Carroll 8d8cb58558 Remove-ZertoVpgVm Tests 2020-08-05 08:47:17 -04:00
Wes Carroll 2dad347544 Remove-ZertoVpgVm Help 2020-08-05 08:41:55 -04:00
Wes Carroll 6f798fd96a Update VM Filter Method 2020-08-05 08:22:19 -04:00
Wes Carroll 649e7413a7 Fix URL typo 2020-08-05 07:46:11 -04:00
Wes Carroll af6e81267b Add Online Help URI 2020-08-05 07:45:55 -04:00
Wes Carroll b6d8083b69 Remove-ZertoVpgVm update 2020-08-04 22:05:35 -04:00
Wes Carroll 9d4b4d3533 Starting Remove-VpgVm 2020-08-04 17:42:37 -04:00
Wes Carroll 510f0b9ed7 Add-ZertoVpgVm Tests 2020-08-04 12:31:37 -04:00
Wes Carroll 9561936be7 Update Help Files 2020-08-04 11:46:12 -04:00
Wes Carroll 961eafb945 Update Event Documentation 2020-08-04 11:44:36 -04:00
Wes Carroll aa73534d7f Create Add-ZertoVpgVm Help File 2020-08-04 11:42:41 -04:00
Wes Carroll 56bbe59ea7 Always return the Vpg Settings Identifier 2020-08-04 11:23:37 -04:00
Wes Carroll 5f786775dc Verbose Output - VM and VPG name 2020-08-04 11:23:20 -04:00
Wes Carroll 14ef5048e4 Only process unique VM names 2020-08-04 11:22:45 -04:00
Wes Carroll d7e46bd263 Check for existence of Vpg 2020-08-04 10:48:58 -04:00
Wes Carroll c64c82f8bc Add parameter alias 2020-08-04 07:53:15 -04:00
Wes Carroll a59feb2d5f Add switch for vpgName 2020-08-03 21:21:05 -04:00
Wes Carroll d9e1063654 update GitIgnore 2020-08-03 21:13:38 -04:00
Wes Carroll d9e6c74f27 Add parameter aliases 2020-07-31 18:02:00 -04:00
Wes Carroll df82bc26ca Add function Add-ZertoVpgVm 2020-07-31 17:42:28 -04:00
Wes Carroll dbde9aa4c2 Merge pull request #101 from ZertoPublic/master
Merge Current Master to Release Branch
2020-07-08 13:14:52 -04:00
Wes Carroll 7dcb6539a5 Merge pull request #100 from ZertoPublic/wcarroll/prep_release
Prep Release Information
2020-07-08 13:10:34 -04:00
Wes Carroll 3621ddef8d Set Version Numbers 2020-07-08 13:08:49 -04:00
Wes Carroll 5b4a25b66d Merge pull request #98 from ZertoPublic:wcarroll/issue95
Remove zvmLocalInfo Script Scope Variable
2020-07-06 14:45:37 -04:00
Wes Carroll 5a2c01341c Update Changlog for Issue 95 2020-07-06 14:32:32 -04:00
Wes Carroll c477d40364 Remove Mocks that are not required any longer 2020-07-06 14:30:07 -04:00
Wes Carroll 494c45b02c Remove tests for removed variable 2020-07-06 14:26:56 -04:00
Wes Carroll 8318229cf4 Remove Removal of Variable no longer required 2020-07-06 14:26:36 -04:00
Wes Carroll 7427ffe707 Remove operation to set ZvmLocalInfo Variable 2020-07-06 14:26:10 -04:00
Wes Carroll 713c94461c Replace Script Scope LocalSite Info Variable 2020-07-06 14:25:43 -04:00
Wes Carroll 0872f1a655 Merge pull request #97 from ZertoPublic/wcarroll/issue96
Fixes Set-ZertoLicense ShouldProcess issue
2020-07-01 19:11:54 -04:00
Wes Carroll a072905253 Update ChangLog with Issue 96 updates 2020-07-01 17:34:25 -04:00
Wes Carroll 41fddf5f13 Set-ZertoLicense - Fix ShouldProcess error
Fixes #96
2020-07-01 17:09:38 -04:00
Wes Carroll 136d1b2c76 Merge pull request #94 from NScuola/patch-1
Adding port information for pairing v7.5+
2020-07-01 14:12:15 -04:00
NScuola a25bf3adfe Adding port information for pairing v7.5+
Adding port information to example for pairing v7.5+.
2020-07-01 14:06:30 -04:00
Wes Carroll 93c55bdd07 Merge pull request #93 from ZertoPublic/issue_90
Make New-ZertoVpg -RecoverySite parameter case-insensitive
2020-06-23 13:13:40 -04:00
Wes Carroll 5627992a04 Update CHANGELOG 2020-06-23 12:54:03 -04:00
Wes Carroll 7fc7edff86 Update PeerSite Lookup Method 2020-06-23 12:51:33 -04:00
Wes Carroll 6f1e582ceb Merge pull request #92 from ZertoPublic/issue_89
Set New-ZertoVpg Default Parameter Set
2020-06-23 12:40:07 -04:00
Wes Carroll 0f1b4302bb Update CHANGELOG with latest updates 2020-06-22 17:18:55 -04:00
Wes Carroll ea8d6f096d Update Parameter with Proper Names 2020-06-22 17:18:40 -04:00
Wes Carroll ddae22fb9f Specify defaultParameterSetName 2020-06-22 17:18:16 -04:00
Wes Carroll 6903ccc99b Update CHANGELOG 2020-06-22 17:03:32 -04:00
Wes Carroll 7ce6369ad7 Add tests for switches 2020-06-22 16:48:32 -04:00
Wes Carroll 2d453ef608 Put params in correct order 2020-06-22 16:48:31 -04:00
Wes Carroll 363b6e727c Update Param Order Syntax in Help File 2020-06-22 16:48:31 -04:00
Wes Carroll f4c1cf630a Moved Credential to Second Position 2020-06-22 16:48:31 -04:00
Wes Carroll 348fcbd28c Update Help for AutoReconnect switch 2020-06-22 16:48:31 -04:00
Wes Carroll 3000a2b013 Initial auto reconnect 2020-06-22 16:48:31 -04:00
Wes Carroll 52609bf64a Merge pull request #88 from ZertoPublic/wcarroll-patch-1
Added Time Example
2020-06-18 13:26:50 -04:00
Wes Carroll e021a7bab0 Added Time Example
Struggled to find a time example. Added one for future use.
2020-06-18 13:20:10 -04:00
Wes Carroll c3ad8dd415 Merge pull request #87 from ZertoPublic/Refactor-Build
Refactor build
2020-06-11 11:35:16 -04:00
Wes Carroll f81a22ca80 Update Artifact Publish task to latest 2020-06-11 09:24:02 -04:00
Wes Carroll de1a85cecd Add ReleaseNotes.md File Creation 2020-06-10 19:30:50 -04:00
Wes Carroll d3acba3967 Remove Unused Publish Task 2020-06-10 15:54:59 -04:00
Wes Carroll 512d5bbd74 Update Publish Location 2020-06-10 15:52:59 -04:00
Wes Carroll 9ad9cb7f1e Update Build Path for Artifact Utilization 2020-06-10 12:20:44 -04:00
Wes Carroll a55b0cd467 Remove SourceFileTests publish 2020-06-10 09:58:32 -04:00
Wes Carroll aab22cf266 Add Branch to Auto-Build 2020-06-10 09:53:01 -04:00
Wes Carroll 906d35186f Update Required Module Versions 2020-06-10 09:44:27 -04:00
Wes Carroll c7c3428dd5 Update release task to use full build process 2020-06-10 09:44:21 -04:00
Wes Carroll e90d2a23cc Update tests to only show failed 2020-06-10 09:44:16 -04:00
Wes Carroll 925ecaf224 Update default build operation 2020-06-10 09:44:11 -04:00
Wes Carroll 32403ec3e3 Update build script with params 2020-06-10 09:44:04 -04:00
Wes Carroll 73540faeb9 Update Build Paths 2020-06-09 22:34:22 -04:00
Wes Carroll 932262e33a Merge pull request #85 from ZertoPublic/wcarroll-patch-2
Add Username Example
2020-06-09 21:27:49 -04:00
Wes Carroll 1e84f5aea0 Add Username Example
added example with username filter
2020-06-09 15:21:11 -04:00
Wes Carroll 7befc7d21e Merge pull request #84 from ZertoPublic/wcarroll-patch-1
Correct example numbering issue
2020-06-05 12:57:07 -04:00
Wes Carroll cdad0c5e79 Correct example numbering issue 2020-06-05 09:43:48 -04:00
Wes Carroll 291aae9dcd Merge pull request #83 from ZertoPublic/ReleasePrep
Release prep
2020-05-17 11:26:23 -04:00
Wes Carroll f8f0d980d0 Update Unreleased to Release Number 2020-05-17 11:22:12 -04:00
Wes Carroll b72099559c Bump Version 2020-05-17 11:21:56 -04:00
Wes Carroll 6046103da0 Merge pull request #82 from ZertoPublic/Fix-ZertoStartClone
Fix zerto start clone
2020-05-17 11:18:15 -04:00
Wes Carroll cccd45b7fd Update ChangeLog 2020-05-17 11:07:31 -04:00
Wes Carroll 77b7e1c376 Fix Body Creation Method 2020-05-17 11:05:15 -04:00
Wes Carroll 8f735bee62 Correct body creation method 2020-05-17 11:04:41 -04:00
Wes Carroll de505debf9 Merge pull request #81 from ZertoPublic/Invoke-ZertoMoveCommit-Fix
Fix Invoke-ZertoMoveCommit
2020-05-13 10:38:31 -04:00
Wes Carroll bc570e9005 Update Changlog with MoveCommit Changes 2020-05-09 20:52:55 -04:00
Wes Carroll 804a60be77 Update for explicit switches 2020-05-09 20:10:13 -04:00
Wes Carroll 1e678214b1 Update for explicit reverse and keep params 2020-05-09 20:10:13 -04:00
Wes Carroll ba0b12e83c Add accepted values 2020-05-09 20:10:13 -04:00
Wes Carroll b33b07b524 Set Explicit Reverse\Keep Options 2020-05-09 20:10:13 -04:00
Wes Carroll d4b4d1b4d7 Merge pull request #80 from ZertoPublic:Get-ZertoEvent-Fix
Get zerto event fix
2020-05-09 11:04:59 -04:00
Wes Carroll fbe3f4d031 Add Get-ZertoEvent Fix 2020-05-09 10:36:37 -04:00
Wes Carroll 26cfb832a4 Update CHANGELOG.md 2020-05-07 20:49:16 -04:00
Wes Carroll 865ca1dd39 Update Logic to Convert VpgName to VpgIdentifier 2020-05-07 20:21:39 -04:00
Wes Carroll 2887f6d450 Update README.md
Fix link to updated WIKI page
2020-05-07 13:54:14 -04:00
46 changed files with 1201 additions and 485 deletions
+1
View File
@@ -6,3 +6,4 @@ SourceTestResults.xml
publish/* publish/*
CodeCoverage.xml CodeCoverage.xml
scratch scratch
.DS_Store
+2 -1
View File
@@ -4,5 +4,6 @@
"editor.insertSpaces": true, "editor.insertSpaces": true,
"editor.tabSize": 4, "editor.tabSize": 4,
"powershell.codeFormatting.preset": "OTBS", "powershell.codeFormatting.preset": "OTBS",
"terminal.integrated.shell.windows": "c:/Program Files/PowerShell/7/pwsh.exe" "terminal.integrated.shell.windows": "c:/Program Files/PowerShell/7/pwsh.exe",
"powershell.codeFormatting.addWhitespaceAroundPipe": true
} }
+68
View File
@@ -5,6 +5,74 @@ 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/), 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). and this project is transitioning to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
## [1.5.3]
### Zerto Virtual Manager
#### Fixed
* Fixed an [issue](https://github.com/ZertoPublic/ZertoApiWrapper/issues/112) where `New-ZertoVpg` would fail when specifying the local site as the target site.
* Updated the method where a Site Identifer is obtained during the `New-ZertoVpg` execution that would occasionally fail on some versions of PowerShell.
#### Updated
* Updated `New-ZertoVpg` function [help documentation](https://github.com/ZertoPublic/ZertoApiWrapper/blob/master/docs/New-ZertoVpg.md) to more clearly specify the return value and the requirement to pass it into the `Save-ZertoVpgSetting` function to commit the VPG.
## [1.5.2]
### Zerto Virtual Manager
#### Fixed
* Fixed an issue when attempting to export more than 100 VPGs with the `Export-ZertoVpg` function that would cause an error.
## [1.5.1]
### Zerto Virtual Manager
#### Fixed
* Fixed an [issue](https://github.com/ZertoPublic/ZertoApiWrapper/issues/108) with `New-ZertoVpg` where when specifying a single host as a recovery target, the host identifier was not properly assigned. - Thanks @jonsouzerto!
* Fixed an [issue](https://github.com/ZertoPublic/ZertoApiWrapper/issues/86) with `Invoke-ZertoMoveVpg` where parameters should have been mandatory in certain workflows. - Thanks @gdbarron!
## [1.5.0]
### Zerto Virtual Manager
#### New
* Added `Add-ZertoVpgVm` function to the module. Read the [help file](https://github.com/ZertoPublic/ZertoApiWrapper/blob/master/docs/Add-ZertoVpgVm.md) for more information.
* Added `Remove-ZertoVpgVm` function to the module. Read the [help file](https://github.com/ZertoPublic/ZertoApiWrapper/blob/master/docs/Remove-ZertoVpgVm.md) for more information.
#### Fixed
* Fixed an [issue](https://github.com/ZertoPublic/ZertoApiWrapper/issues/103) with `Add-ZertoPeerSite` where there was an incorrect settings validator on the `-targetHost` parameter where it would not accept a hostname.
## [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
#### Fixed
* Updated `Get-ZertoEvent` to translate a vpg name parameter to a vpgIdentifier per the API documentation
* Updated `Invoke-ZertoMoveCommit` to ensure that when one of the parameter switches is defined, all required parameters are sent to avoid conflicts with parameters passed with the `Invoke-ZertoMove` command.
* Updated `Start-ZertoCloneVpg` to fix an issue where an error would be thrown if an operation specified a subset of VMs to be cloned.
## [1.4.1] ## [1.4.1]
### General ### General
+1 -1
View File
@@ -27,7 +27,7 @@ PS> Install-Module -name ZertoApiWrapper
## Getting Started ## Getting Started
* [Getting Started with Zerto Virtual Manager and the ZertoApiWrapper](https://github.com/ZertoPublic/ZertoApiWrapper/wiki/Getting-Stated-with-Zerto-Virtual-Manager) * [Getting Started with Zerto Virtual Manager and the ZertoApiWrapper](https://github.com/ZertoPublic/ZertoApiWrapper/wiki/Getting-Started-with-Zerto-Virtual-Manager)
* [Getting Started with Zerto Analytics and the ZertoApiWrapper](https://github.com/ZertoPublic/ZertoApiWrapper/wiki/Getting-Started-with-Zerto-Analytics) * [Getting Started with Zerto Analytics and the ZertoApiWrapper](https://github.com/ZertoPublic/ZertoApiWrapper/wiki/Getting-Started-with-Zerto-Analytics)
## Recent Updates ## Recent Updates
+4 -9
View File
@@ -1,6 +1,6 @@
#Requires -Modules Pester #Requires -Modules Pester
$global:here = (Split-Path -Parent $PSCommandPath) $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' { Describe $global:function -Tag 'Unit', 'Source', 'Built' {
BeforeAll { BeforeAll {
@@ -14,7 +14,7 @@ Describe $global:function -Tag 'Unit', 'Source', 'Built' {
} }
$ParameterTestCases = @( $ParameterTestCases = @(
@{ParameterName = 'targetHost'; Type = 'String'; Mandatory = $true; Validation = 'Script' } @{ParameterName = 'targetHost'; Type = 'String'; Mandatory = $true; Validation = 'NotNullOrEmpty' }
@{ParameterName = 'targetPort'; Type = 'Int32'; Mandatory = $false; Validation = 'Range' } @{ParameterName = 'targetPort'; Type = 'Int32'; Mandatory = $false; Validation = 'Range' }
@{ParameterName = 'token'; Type = 'String'; Mandatory = $false; Validation = 'NotNullOrEmpty' } @{ParameterName = 'token'; Type = 'String'; Mandatory = $false; Validation = 'NotNullOrEmpty' }
) )
@@ -27,11 +27,6 @@ Describe $global:function -Tag 'Unit', 'Source', 'Built' {
It "<ParameterName> parameter has correct validation setting" -TestCases $ParameterTestCases { It "<ParameterName> parameter has correct validation setting" -TestCases $ParameterTestCases {
param($ParameterName, $Validation) param($ParameterName, $Validation)
Switch ($Validation) { Switch ($Validation) {
'Script' {
$attrs = (Get-Command $global:function).Parameters[$ParameterName].Attributes
$attrs.Where{ $_ -is [ValidateScript] }.Count | Should -Be 1
}
'Range' { 'Range' {
$attrs = (Get-Command $global:function).Parameters[$ParameterName].Attributes $attrs = (Get-Command $global:function).Parameters[$ParameterName].Attributes
$attrs.Where{ $_ -is [ValidateRange] }.Count | Should -Be 1 $attrs.Where{ $_ -is [ValidateRange] }.Count | Should -Be 1
@@ -63,8 +58,8 @@ Describe $global:function -Tag 'Unit', 'Source', 'Built' {
It "Supports 'SupportsShouldProcess'" { It "Supports 'SupportsShouldProcess'" {
Get-Command $global:function | Should -HaveParameter WhatIf Get-Command $global:function | Should -HaveParameter WhatIf
Get-Command $global:function | Should -HaveParameter Confirm Get-Command $global:function | Should -HaveParameter Confirm
$script:ScriptBlock | Should -match 'SupportsShouldProcess' $script:ScriptBlock | Should -Match 'SupportsShouldProcess'
$script:ScriptBlock | Should -match '\$PSCmdlet\.ShouldProcess\(.+\)' $script:ScriptBlock | Should -Match '\$PSCmdlet\.ShouldProcess\(.+\)'
} }
} }
+53
View File
@@ -0,0 +1,53 @@
#Requires -Modules Pester
$global:here = (Split-Path -Parent $PSCommandPath)
$global:function = ((Split-Path -Leaf $PSCommandPath).Split('.'))[0]
Describe $global:function -Tag 'Unit', 'Source', 'Built' {
BeforeAll {
$script:ScriptBlock = (Get-Command $global:function).ScriptBlock
}
Context "$global:function::Parameter Unit Tests" {
It "$global:function should have exactly 16 parameters defined" {
(Get-Command $global:function).Parameters.Count | Should -Be 16
}
$ParameterTestCases = @(
@{ParameterName = 'vpgSettingsIdentifier'; Type = 'String'; Mandatory = $true; Validation = 'NotNullOrEmpty' }
@{ParameterName = 'Vm'; Type = 'String[]'; Mandatory = $true; Validation = 'NotNullOrEmpty' }
@{ParameterName = 'VpgName'; Type = 'String'; Mandatory = $true; Validation = 'NotNullOrEmpty' }
)
It "<ParameterName> parameter is of <Type> type" -TestCases $ParameterTestCases {
param($ParameterName, $Type, $Mandatory, $Validation)
Get-Command $global:function | Should -HaveParameter $ParameterName -Mandatory:$Mandatory -Type $Type
}
It "<ParameterName> parameter has correct validation setting" -TestCases $ParameterTestCases {
param($ParameterName, $Validation)
Switch ($Validation) {
'NotNullOrEmpty' {
$attrs = (Get-Command $global:function).Parameters[$ParameterName].Attributes
$attrs.Where{ $_ -is [ValidateNotNullOrEmpty] }.Count | Should -Be 1
}
default {
$true | Should -Be $false -Because "No Validation Selected. Review test cases"
}
}
}
It "Supports 'SupportsShouldProcess'" {
Get-Command $global:function | Should -HaveParameter WhatIf
Get-Command $global:function | Should -HaveParameter Confirm
$script:ScriptBlock | Should -Match 'SupportsShouldProcess'
$script:ScriptBlock | Should -Match '\$PSCmdlet\.ShouldProcess\(.+\)'
}
}
Context "Add-ZertoPeerSite::Functional Unit Tests" {
}
}
Remove-Variable -Name here -Scope Global
Remove-Variable -Name function -Scope Global
+11 -12
View File
@@ -1,6 +1,6 @@
#Requires -Modules Pester #Requires -Modules Pester
$global:here = (Split-Path -Parent $PSCommandPath) $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' { Describe $global:function -Tag 'Unit', 'Source', 'Built' {
BeforeAll { BeforeAll {
@@ -45,6 +45,16 @@ Describe $global:function -Tag 'Unit', 'Source', 'Built' {
{ Connect-ZertoServer -zertoServer -credential 1234 } | Should -Throw { Connect-ZertoServer -zertoServer -credential 1234 } | Should -Throw
{ Connect-ZertoServer -zertoServer -credential $(@{Username = "zerto\build"; Password = 'SecureString' }) } | 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 { InModuleScope -ModuleName ZertoApiWrapper {
@@ -57,10 +67,6 @@ Describe $global:function -Tag 'Unit', 'Source', 'Built' {
return $results 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" { Context "$($global:function)::InModuleScope Function Unit Tests" {
BeforeAll { BeforeAll {
@@ -96,12 +102,6 @@ Describe $global:function -Tag 'Unit', 'Source', 'Built' {
$script:zvmHeaders['Accept'] | Should -BeOfType String $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 $headers = Connect-ZertoServer -zertoServer $Server -credential $credential -returnHeaders
It "returns a Hashtable with 2 keys" { It "returns a Hashtable with 2 keys" {
$headers | Should -BeOfType Hashtable $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 Invoke-ZertoRestRequest -Exactly 4
Assert-MockCalled -ModuleName ZertoApiWrapper -CommandName Get-ZertoLocalSite -Exactly 4
} }
} }
} }
+4
View File
@@ -46,6 +46,10 @@ Describe $global:function -Tag 'Unit', 'Source', 'Built' {
return "1024d377-afb8-4880-82f0-96eeff413ffd" return "1024d377-afb8-4880-82f0-96eeff413ffd"
} }
Mock -ModuleName ZertoApiWrapper -CommandName Remove-ZertoVpgSettingsIdentifier {
return $null
}
Mock -ModuleName ZertoApiWrapper -CommandName Get-ZertoVpgSetting { Mock -ModuleName ZertoApiWrapper -CommandName Get-ZertoVpgSetting {
$returnObj = @{ $returnObj = @{
Backup = $null Backup = $null
+1 -1
View File
@@ -12,7 +12,7 @@ Describe $global:function -Tag 'Unit', 'Source', 'Built' {
$ParameterTestCases = @( $ParameterTestCases = @(
@{ParameterName = 'startDate'; Type = 'String'; Mandatory = $false; Validation = 'NotNullOrEmpty' } @{ParameterName = 'startDate'; Type = 'String'; Mandatory = $false; Validation = 'NotNullOrEmpty' }
@{ParameterName = 'endDate'; Type = 'String'; Mandatory = $false; Validation = 'NotNullOrEmpty' } @{ParameterName = 'endDate'; Type = 'String'; Mandatory = $false; Validation = 'NotNullOrEmpty' }
@{ParameterName = 'vpgName'; Type = 'String'; Mandatory = $false; Validation = 'NotNullOrEmpty' } @{ParameterName = 'vpg'; Type = 'String'; Mandatory = $false; Validation = 'NotNullOrEmpty' }
@{ParameterName = 'vpgIdentifier'; Type = 'String'; Mandatory = $false; Validation = 'NotNullOrEmpty' } @{ParameterName = 'vpgIdentifier'; Type = 'String'; Mandatory = $false; Validation = 'NotNullOrEmpty' }
@{ParameterName = 'eventType'; Type = 'String'; Mandatory = $false; Validation = 'NotNullOrEmpty' } @{ParameterName = 'eventType'; Type = 'String'; Mandatory = $false; Validation = 'NotNullOrEmpty' }
@{ParameterName = 'siteName'; Type = 'String'; Mandatory = $false; Validation = 'NotNullOrEmpty' } @{ParameterName = 'siteName'; Type = 'String'; Mandatory = $false; Validation = 'NotNullOrEmpty' }
+5 -4
View File
@@ -5,17 +5,18 @@ $global:function = ((Split-Path -leaf $PSCommandPath).Split('.'))[0]
Describe $global:function -Tag 'Unit', 'Source', 'Built' { Describe $global:function -Tag 'Unit', 'Source', 'Built' {
Context "$global:function::Parameter Unit Tests" { Context "$global:function::Parameter Unit Tests" {
It "$global:function should have exactly 20 parameters defined" { It "$global:function should have exactly 21 parameters defined" {
(Get-Command $global:function).Parameters.Count | Should -Be 20 (Get-Command $global:function).Parameters.Count | Should -Be 21
} }
$ParameterTestCases = @( $ParameterTestCases = @(
@{ParameterName = 'vpgIdentifier'; Type = 'Guid[]'; Mandatory = $true; Validation = 'NotNullOrEmpty' }
@{ParameterName = 'vpgName'; Type = 'String[]'; Mandatory = $true; Validation = 'NotNullOrEmpty' } @{ParameterName = 'vpgName'; Type = 'String[]'; Mandatory = $true; Validation = 'NotNullOrEmpty' }
@{ParameterName = 'commitPolicy'; Type = 'String'; Mandatory = $false; Validation = 'Set' } @{ParameterName = 'commitPolicy'; Type = 'String'; Mandatory = $false; Validation = 'Set' }
@{ParameterName = 'commitPolicyTimeout'; Type = 'Int'; Mandatory = $false; Validation = 'Range' } @{ParameterName = 'commitPolicyTimeout'; Type = 'Int'; Mandatory = $false; Validation = 'Range' }
@{ParameterName = 'forceShutdown'; Type = 'Switch'; Mandatory = $false; Validation = $null } @{ParameterName = 'forceShutdown'; Type = 'Switch'; Mandatory = $false; Validation = $null }
@{ParameterName = 'disableReverseProtection'; Type = 'Switch'; Mandatory = $true; Validation = $null } @{ParameterName = 'disableReverseProtection'; Type = 'Switch'; Mandatory = $false; Validation = $null }
@{ParameterName = 'keepSourceVms'; Type = 'Switch'; Mandatory = $true; Validation = $null } @{ParameterName = 'keepSourceVms'; Type = 'Switch'; Mandatory = $false; Validation = $null }
@{ParameterName = 'ContinueOnPreScriptFailure'; Type = 'Switch'; Mandatory = $false; Validation = $null } @{ParameterName = 'ContinueOnPreScriptFailure'; Type = 'Switch'; Mandatory = $false; Validation = $null }
@{ParameterName = 'whatIf'; Type = 'Switch'; Mandatory = $false; Validation = 'ShouldProcess' } @{ParameterName = 'whatIf'; Type = 'Switch'; Mandatory = $false; Validation = 'ShouldProcess' }
) )
+52
View File
@@ -0,0 +1,52 @@
#Requires -Modules Pester
$global:here = (Split-Path -Parent $PSCommandPath)
$global:function = ((Split-Path -Leaf $PSCommandPath).Split('.'))[0]
Describe $global:function -Tag 'Unit', 'Source', 'Built' {
BeforeAll {
$script:ScriptBlock = (Get-Command $global:function).ScriptBlock
}
Context "$global:function::Parameter Unit Tests" {
It "$global:function should have exactly 15 parameters defined" {
(Get-Command $global:function).Parameters.Count | Should -Be 15
}
$ParameterTestCases = @(
@{ParameterName = 'Vm'; Type = 'String[]'; Mandatory = $true; Validation = 'NotNullOrEmpty' }
@{ParameterName = 'VpgName'; Type = 'String'; Mandatory = $true; Validation = 'NotNullOrEmpty' }
)
It "<ParameterName> parameter is of <Type> type" -TestCases $ParameterTestCases {
param($ParameterName, $Type, $Mandatory, $Validation)
Get-Command $global:function | Should -HaveParameter $ParameterName -Mandatory:$Mandatory -Type $Type
}
It "<ParameterName> parameter has correct validation setting" -TestCases $ParameterTestCases {
param($ParameterName, $Validation)
Switch ($Validation) {
'NotNullOrEmpty' {
$attrs = (Get-Command $global:function).Parameters[$ParameterName].Attributes
$attrs.Where{ $_ -is [ValidateNotNullOrEmpty] }.Count | Should -Be 1
}
default {
$true | Should -Be $false -Because "No Validation Selected. Review test cases"
}
}
}
It "Supports 'SupportsShouldProcess'" {
Get-Command $global:function | Should -HaveParameter WhatIf
Get-Command $global:function | Should -HaveParameter Confirm
$script:ScriptBlock | Should -Match 'SupportsShouldProcess'
$script:ScriptBlock | Should -Match '\$PSCmdlet\.ShouldProcess\(.+\)'
}
}
Context "Add-ZertoPeerSite::Functional Unit Tests" {
}
}
Remove-Variable -Name here -Scope Global
Remove-Variable -Name function -Scope Global
+2 -2
View File
@@ -7,7 +7,7 @@
SkipPublisherCheck = $true SkipPublisherCheck = $true
} }
Target = 'CurrentUser' Target = 'CurrentUser'
Version = '5.5.11' Version = '5.6.0'
Tags = 'Bootstrap' Tags = 'Bootstrap'
} }
@@ -31,7 +31,7 @@
SkipPublisherCheck = $true SkipPublisherCheck = $true
} }
Target = 'CurrentUser' Target = 'CurrentUser'
Version = '1.18.3' Version = '1.19.0'
Tags = 'Bootstrap' Tags = 'Bootstrap'
} }
+44 -43
View File
@@ -1,23 +1,24 @@
#Requires -Modules 'InvokeBuild' #Requires -Modules 'InvokeBuild'
$version = "{0}" -f $(Get-Content .\version.txt) $version = "{0}" -f $(Get-Content .\version.txt)
$moduleOutPath = "{0}\publish\ZertoApiWrapper" -f $BuildRoot
#Define the default task #Define the default task
task . CreateArtifacts task . build
#Region - Helper Functions #Region - Helper Functions
function ImportSourceModule() { function ImportSourceModule {
If (Get-Module -Name ZertoApiWrapper) { If (Get-Module -Name ZertoApiWrapper) {
Remove-Module -Name ZertoApiWrapper -Force -ErrorAction Stop Remove-Module -Name ZertoApiWrapper -Force -ErrorAction Stop
} }
Import-Module "$BuildRoot\ZertoApiWrapper\ZertoApiWrapper.psd1" -ErrorAction Stop Import-Module "$BuildRoot\ZertoApiWrapper\ZertoApiWrapper.psd1" -ErrorAction Stop
} }
function ImportBuiltModule() { function ImportBuiltModule {
If (Get-Module -Name ZertoApiWrapper) { If (Get-Module -Name ZertoApiWrapper) {
Remove-Module -Name ZertoApiWrapper -Force -ErrorAction Stop 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 #EndRegion
@@ -65,7 +66,7 @@ task AnalyzeSourceFiles CheckPSScriptAnalyzerInstalled, {
task AnalyzeBuiltFiles CheckPSScriptAnalyzerInstalled, CreatePsm1ForRelease, { task AnalyzeBuiltFiles CheckPSScriptAnalyzerInstalled, CreatePsm1ForRelease, {
$scriptAnalyzerParams = @{ $scriptAnalyzerParams = @{
Path = "$BuildRoot\temp\" Path = $moduleOutPath
Severity = @('Error', 'Warning') Severity = @('Error', 'Warning')
Recurse = $true Recurse = $true
Verbose = $false Verbose = $false
@@ -81,17 +82,13 @@ task AnalyzeBuiltFiles CheckPSScriptAnalyzerInstalled, CreatePsm1ForRelease, {
#EndRegion #EndRegion
#Region - Clean Operations #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 { task CleanPublish {
if ($(Test-Path "$BuildRoot\publish")) { if ($(Test-Path "$BuildRoot\publish")) {
Remove-Item -Recurse -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 #EndRegion
@@ -107,7 +104,7 @@ task SourceFileTests CheckPesterInstalled, {
task BuiltFileTests CreatePsm1ForRelease, CheckPesterInstalled, { task BuiltFileTests CreatePsm1ForRelease, CheckPesterInstalled, {
ImportBuiltModule ImportBuiltModule
$testResultsFile = "$BuildRoot\Tests\BuiltTestResults.xml" $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 $FailureMessage = '{0} Unit test(s) failed. Aborting build' -f $results.FailedCount
Assert ($results.FailedCount -eq 0) $FailureMessage Assert ($results.FailedCount -eq 0) $FailureMessage
} }
@@ -116,7 +113,7 @@ task BuiltFileTests CreatePsm1ForRelease, CheckPesterInstalled, {
#Region - Build Help System #Region - Build Help System
$buildMamlParams = @{ $buildMamlParams = @{
Inputs = { Get-ChildItem docs\*.md } 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, { task BuildMamlHelp CheckPlatyPSInstalled, {
@@ -126,19 +123,19 @@ task BuildMamlHelp CheckPlatyPSInstalled, {
platyPS\New-ExternalHelp .\docs -Force -OutputPath $buildMamlParams.Outputs platyPS\New-ExternalHelp .\docs -Force -OutputPath $buildMamlParams.Outputs
} }
task UpdateMarkdownHelp CheckPlatyPSInstalled, { task UpdateMarkdownHelp quickBuild, CheckPlatyPSInstalled, {
ImportSourceModule ImportBuiltModule
Update-MarkdownHelpModule -Path docs -AlphabeticParamsOrder Update-MarkdownHelpModule -Path docs -AlphabeticParamsOrder
} }
#EndRegion #EndRegion
#Region - Build Module Files #Region - Build Module Files
task CreatePsd1ForRelease CleanTemp, { task CreatePsd1ForRelease CleanPublish, {
$functionsToExport = Get-ChildItem -Path 'ZertoApiWrapper\Public\*.ps1' | ForEach-Object { $_.BaseName } $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 $releaseNotes = "Please review the [Release Notes](https://github.com/ZertoPublic/ZertoApiWrapper/releases/tag/{0}) on GitHub." -f $version
$ManifestParams = @{ $ManifestParams = @{
Path = "$BuildRoot\temp\ZertoApiWrapper.psd1" Path = "{0}\ZertoApiWrapper.psd1" -f $moduleOutPath
RootModule = 'ZertoApiWrapper.psm1' RootModule = 'ZertoApiWrapper.psm1'
ModuleVersion = $version ModuleVersion = $version
GUID = '4c0b9e17-141b-4dd5-8549-fb21cccaa325' GUID = '4c0b9e17-141b-4dd5-8549-fb21cccaa325'
@@ -161,43 +158,47 @@ task CreatePsd1ForRelease CleanTemp, {
task CreatePsm1ForRelease CreatePsd1ForRelease, { task CreatePsm1ForRelease CreatePsd1ForRelease, {
$emptyLine = "" $emptyLine = ""
$psm1Path = "$BuildRoot\temp\ZertoApiWrapper.psm1" $psm1Path = "{0}\ZertoApiWrapper.psm1" -f $moduleOutPath
$lines = '#------------------------------------------------------------#' $lines = '#------------------------------------------------------------#'
$Private = @( Get-ChildItem -Path $BuildRoot\ZertoApiWrapper\Private\*.ps1 -ErrorAction Stop ) $Private = @( Get-ChildItem -Path $BuildRoot\ZertoApiWrapper\Private\*.ps1 -ErrorAction Stop )
$Public = @( Get-ChildItem -Path $BuildRoot\ZertoApiWrapper\Public\*.ps1 -ErrorAction Stop ) $Public = @( Get-ChildItem -Path $BuildRoot\ZertoApiWrapper\Public\*.ps1 -ErrorAction Stop )
Add-Content -Path $psm1Path -Value $lines Add-Content -Path $psm1Path -Value $lines -Encoding 'utf8'
Add-Content -Path $psm1Path -Value "#---------------------Private Functions----------------------#" Add-Content -Path $psm1Path -Value "#---------------------Private Functions----------------------#" -Encoding 'utf8'
Add-Content -Path $psm1Path -Value $lines Add-Content -Path $psm1Path -Value $lines -Encoding 'utf8'
Add-Content -Path $psm1Path -Value $emptyLine Add-Content -Path $psm1Path -Value $emptyLine -Encoding 'utf8'
foreach ($file in $private) { foreach ($file in $private) {
Add-Content -Path $psm1Path -Value $(Get-Content -Path $file.Fullname -Raw) Add-Content -Path $psm1Path -Value $(Get-Content -Path $file.Fullname -Raw) -Encoding 'utf8'
Add-Content -Path $psm1Path -Value $emptyLine Add-Content -Path $psm1Path -Value $emptyLine -Encoding 'utf8'
} }
Add-Content -Path $psm1Path -Value $lines Add-Content -Path $psm1Path -Value $lines -Encoding 'utf8'
Add-Content -Path $psm1Path -Value "#----------------------Public Functions----------------------#" Add-Content -Path $psm1Path -Value "#----------------------Public Functions----------------------#" -Encoding 'utf8'
Add-Content -Path $psm1Path -Value $lines Add-Content -Path $psm1Path -Value $lines -Encoding 'utf8'
Add-Content -Path $psm1Path -Value $emptyLine Add-Content -Path $psm1Path -Value $emptyLine -Encoding 'utf8'
foreach ($file in $public) { foreach ($file in $public) {
Add-Content -Path $psm1Path -Value $(Get-Content -Path $file.Fullname -Raw) Add-Content -Path $psm1Path -Value $(Get-Content -Path $file.Fullname -Raw) -Encoding 'utf8'
Add-Content -Path $psm1Path -Value $emptyLine Add-Content -Path $psm1Path -Value $emptyLine -Encoding 'utf8'
} }
# Add-Content -Path $psm1Path -Value $emptyLine
# Add-Content -Path $psm1Path -Value "Export-ModuleMember -Function $exportString"
} }
#EndRegion #EndRegion
#Region - Artifacts \ Publish #Region - Artifacts \ Publish
# Full Build Process - No Publishing # Full Build Process - No Publishing
task CreateArtifacts CleanPublish, CleanTemp, AnalyzeSourceFiles, SourceFileTests, AnalyzeBuiltFiles, BuiltFileTests, BuildMamlHelp, { task CreateArtifacts CleanPublish, AnalyzeBuiltFiles, BuiltFileTests, BuildMamlHelp, {
if (-not $(Test-Path "$BuildRoot\publish")) { Compress-Archive -Path $moduleOutPath -DestinationPath .\publish\ZertoApiWrapper.zip
New-Item -Path $BuildRoot -Name "publish" -ItemType Directory $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 #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
}
+1 -1
View File
@@ -6,7 +6,7 @@ function Add-ZertoPeerSite {
Mandatory, Mandatory,
HelpMessage = "Target Hostname or IP address to pair the localsite to." HelpMessage = "Target Hostname or IP address to pair the localsite to."
)] )]
[ValidateScript( { $_ -match [IPAddress]$_ } )] [ValidateNotNullOrEmpty()]
[string]$targetHost, [string]$targetHost,
[Parameter( [Parameter(
HelpMessage = "Target communication port. Default is 9081" HelpMessage = "Target communication port. Default is 9081"
+104
View File
@@ -0,0 +1,104 @@
<# .ExternalHelp ./en-us/ZertoApiWrapper-help.xml #>
function Add-ZertoVpgVm {
[CmdletBinding(SupportsShouldProcess, DefaultParameterSetName = "VpgName")]
param (
[Parameter(
Mandatory,
HelpMessage = "Vpg Settings Identifier",
ValueFromPipeline,
ValueFromPipelineByPropertyName,
ValueFromRemainingArguments,
ParameterSetName = "VpgSettingsIdentifier"
)]
[ValidateNotNullOrEmpty()]
[Alias("sid", "settingsIdentifier", "vpgSettingsId")]
[String]$vpgSettingsIdentifier,
[Parameter(
Mandatory,
HelpMessage = "Target VPG Name to Add the VM",
ParameterSetName = "VpgName"
)]
[ValidateNotNullOrEmpty()]
[String]$VpgName,
[Parameter(
Mandatory,
HelpMessage = "Name of VM(s) to add to the VPG"
)]
[ValidateNotNullOrEmpty()]
[String[]]$Vm
)
begin {
}
process {
if ($PSCmdlet.ParameterSetName -eq "VpgName") {
$VpgIdentifier = Get-ZertoVpg -name $VpgName | Select-Object -ExpandProperty VpgIdentifier
if (-not $VpgIdentifier) {
Write-Error "Unable to find Vpg with name $VpgName. Please check your parameters and try again." -ErrorAction Stop
} else {
$vpgSettingsIdentifier = New-ZertoVpgSettingsIdentifier -vpgIdentifier $VpgIdentifier
}
}
$baseUrl = "vpgsettings/{0}/vms" -f $vpgSettingsIdentifier
$baseSettings = Get-ZertoVpgSetting -vpgSettingsIdentifier $vpgSettingsIdentifier
if ($PSCmdlet.ParameterSetName -eq "VpgSettingsIdentifier") {
$VpgName = $baseSettings.Basic.Name
}
$unprotectedVms = Get-ZertoUnprotectedVm
$protectedVms = Get-ZertoProtectedVm
$vmMap = Get-Map -inputObject $unprotectedVms -key VmName -value VmIdentifier
$vmMap = $vmMap + (Get-Map -inputObject $protectedVms -key VmName -value VmIdentifier)
# Create array of VM identifiers
$vmIdentifiers = foreach ($machine in ($Vm | Select-Object -Unique)) {
if ($vmMap[$machine] -notin $baseSettings.Vms.vmIdentifier ) {
# If the VM is unprotected, get the identifier
$vmIdentifier = $unprotectedVms | Where-Object { $_.vmName -like $machine } | Select-Object -ExpandProperty vmIdentifier
# If the VM is not unprotected, check the protected VMs
if ( -not $vmIdentifier) {
# Get all identifiers to test if the VM is eligible to be a member of an additional VPG
$results = $protectedVms | Where-Object { $_.VmName -like $machine } | Select-Object -ExpandProperty vmIdentifier
$recoverySiteIdentifiers = $protectedVms | Where-Object { $_.VmName -like $machine } | Select-Object -ExpandProperty RecoverySite | Select-Object -ExpandProperty identifier
# If VM is currently a member of 3 VPGs, skip it. If it cannot be found, skip it. Otherwise, set the identifier
if ($baseSettings.basic.RecoverySiteIdentifier -in $recoverySiteIdentifiers) {
Write-Warning "$machine is already replicating to target site. It cannot be added to an additional VPG replicating to that site. Please check your configurations and try again. Skipping $machine"
continue
} elseif ($results.count -eq 3) {
Write-Warning "$machine is already a part of 3 VPGs and cannot be part of an additional VPG. Skipping $machine"
continue
} elseif ($results.count -eq 0) {
Write-Warning "$machine not found. Skipping $machine"
continue
} else {
$vmIdentifier = $results | Select-Object -First 1
}
}
# Create a custom object to store the information to easily convert to JSON. Return to vmIdentifiers array.
$vmIdentifier
} else {
Write-Warning "$machine is already a member of this VPG Settings object. It will not be added again. Skipping $machine"
continue
}
}
if ($vmIdentifiers.Count -gt 0 -and $PSCmdlet.ShouldProcess($VmIdentifiers, "Adding VM(s): $Vm to Vpg $VpgName")) {
foreach ($id in $VmIdentifiers) {
# Build the Body
$Body = @{VmIdentifier = $id }
# Submit the request. Out to Null to prevent line returns while running.
$null = Invoke-ZertoRestRequest -uri $baseUrl -method POST -body ($Body | ConvertTo-Json -Depth 10)
}
$vpgSettingsIdentifier
} else {
Write-Warning "No VMs found to add. Please check your parameters and try again."
if ($PSCmdlet.ParameterSetName -eq "VpgName") {
Remove-ZertoVpgSettingsIdentifier -vpgSettingsIdentifier $vpgSettingsIdentifier
}
}
}
end {
}
}
+19 -8
View File
@@ -5,11 +5,18 @@ function Connect-ZertoServer {
param( param(
[Parameter( [Parameter(
Mandatory, Mandatory,
HelpMessage = "IP address or FQDN of your Zerto Management Server" HelpMessage = "IP address or FQDN of your Zerto Management Server",
Position = 0
)] )]
[ValidateNotNullOrEmpty()] [ValidateNotNullOrEmpty()]
[Alias("server", "zvm")] [Alias("server", "zvm")]
[string]$zertoServer, [string]$zertoServer,
[Parameter(
Mandatory,
HelpMessage = "Valid credentials to connect to the Zerto Management Server",
Position = 1
)]
[System.Management.Automation.PSCredential]$credential,
[Parameter( [Parameter(
HelpMessage = "Zerto Virtual Manager management port. Default value is 9669." HelpMessage = "Zerto Virtual Manager management port. Default value is 9669."
)] )]
@@ -18,11 +25,14 @@ function Connect-ZertoServer {
[Alias("port")] [Alias("port")]
[string]$zertoPort = "9669", [string]$zertoPort = "9669",
[Parameter( [Parameter(
Mandatory, 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"
HelpMessage = "Valid credentials to connect to the Zerto Management Server" )]
[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 [switch]$returnHeaders
) )
begin { begin {
@@ -38,6 +48,10 @@ function Connect-ZertoServer {
"Accept" = "application/json" "Accept" = "application/json"
"zerto-triggered-by" = "PowershellWes" "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 { process {
@@ -48,10 +62,7 @@ function Connect-ZertoServer {
end { end {
# Build Headers Hashtable with Authorization Token # Build Headers Hashtable with Authorization Token
$Script:zvmHeaders['x-zerto-session'] = $results.Headers['x-zerto-session'][0].ToString() $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 # Have the option to return the headers to a variable
if ($returnHeaders) { if ($returnHeaders) {
return $Script:zvmHeaders return $Script:zvmHeaders
@@ -12,5 +12,4 @@ function Disconnect-ZertoServer {
Remove-Variable -Name zvmPort -Scope Script Remove-Variable -Name zvmPort -Scope Script
Remove-Variable -Name zvmLastAction -Scope Script Remove-Variable -Name zvmLastAction -Scope Script
Remove-Variable -Name zvmHeaders -Scope Script Remove-Variable -Name zvmHeaders -Scope Script
Remove-Variable -Name zvmLocalInfo -Scope Script
} }
@@ -38,6 +38,7 @@ function Export-ZertoVpg {
$vpgSettings = Get-ZertoVpgSetting -vpgSettingsIdentifier $vpgSettingsIdentifier $vpgSettings = Get-ZertoVpgSetting -vpgSettingsIdentifier $vpgSettingsIdentifier
$filePath = "{0}\{1}.json" -f $outputPath, $name $filePath = "{0}\{1}.json" -f $outputPath, $name
$vpgSettings | Convertto-Json -depth 10 | Out-File -FilePath $filePath $vpgSettings | Convertto-Json -depth 10 | Out-File -FilePath $filePath
$null = Remove-ZertoVpgSettingsIdentifier -vpgSettingsIdentifier $vpgSettingsIdentifier
} }
} }
+6 -2
View File
@@ -19,8 +19,8 @@ function Get-ZertoEvent {
HelpMessage = "The name of the VPG for which you want to return events." HelpMessage = "The name of the VPG for which you want to return events."
)] )]
[ValidateNotNullOrEmpty()] [ValidateNotNullOrEmpty()]
[Alias("vpg")] [Alias("vpgName")]
[string]$vpgName, [string]$vpg,
[Parameter( [Parameter(
ParameterSetName = "filter", ParameterSetName = "filter",
HelpMessage = "The identifier of the VPG for which you want to return events." HelpMessage = "The identifier of the VPG for which you want to return events."
@@ -137,6 +137,10 @@ function Get-ZertoEvent {
# If a filter is applied, create the filter and return the events that fall in that filter # If a filter is applied, create the filter and return the events that fall in that filter
"filter" { "filter" {
$filter = Get-ZertoApiFilter -filterTable $PSBoundParameters $filter = Get-ZertoApiFilter -filterTable $PSBoundParameters
if ($PSBoundParameters.Keys -contains 'vpg') {
$vpgIdentifier = (Get-ZertoVpg -name $vpg).vpgIdentifier
$filter = $filter.replace("vpg=$vpg", "vpg=$vpgIdentifier")
}
$uri = "{0}{1}" -f $baseUri, $filter $uri = "{0}{1}" -f $baseUri, $filter
$returnObject = Invoke-ZertoRestRequest -uri $uri $returnObject = Invoke-ZertoRestRequest -uri $uri
} }
@@ -2,6 +2,6 @@
function Get-ZertoUnprotectedVm { function Get-ZertoUnprotectedVm {
[cmdletbinding()] [cmdletbinding()]
param() param()
$uri = "virtualizationsites/{0}/vms" -f $script:zvmLocalInfo.siteidentifier $uri = "virtualizationsites/{0}/vms" -f (Get-ZertoLocalSite).siteIdentifier
Invoke-ZertoRestRequest -uri $uri Invoke-ZertoRestRequest -uri $uri
} }
+1 -1
View File
@@ -111,7 +111,7 @@ function Install-ZertoVra {
# If the VRA does not exist, proceed with the installation. If it does exist, bypass and # If the VRA does not exist, proceed with the installation. If it does exist, bypass and
if ( -not (Get-ZertoVra -vraName $vraName) ) { if ( -not (Get-ZertoVra -vraName $vraName) ) {
# Get identifiers for each item provided by name. # 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 $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 $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 $datastoreIdentifier = Get-ZertoVirtualizationSite -siteIdentifier $siteIdentifier -datastores | Where-Object { $_.DatastoreName -eq $datastoreName } | Select-Object DatastoreIdentifier -ExpandProperty DatastoreIdentifier
+75 -46
View File
@@ -1,22 +1,57 @@
<# .ExternalHelp ./en-us/ZertoApiWrapper-help.xml #> <# .ExternalHelp ./en-us/ZertoApiWrapper-help.xml #>
function Invoke-ZertoMove { function Invoke-ZertoMove {
[CmdletBinding( DefaultParameterSetName = "main", SupportsShouldProcess = $true )] [CmdletBinding( DefaultParameterSetName = "id", SupportsShouldProcess = $true )]
param( param(
[Parameter( [Parameter(
ParameterSetName = 'name',
HelpMessage = "Name(s) of the VPG(s) you want to move.",
Mandatory
)]
[Parameter(
ParameterSetName = 'commitName',
HelpMessage = "Name(s) of the VPG(s) you want to move.", HelpMessage = "Name(s) of the VPG(s) you want to move.",
Mandatory Mandatory
)] )]
[ValidateNotNullOrEmpty()] [ValidateNotNullOrEmpty()]
[string[]]$vpgName, [string[]]$vpgName,
[Parameter( [Parameter(
ParameterSetName = 'id',
HelpMessage = "ID(s) of the VPG(s) you want to move.",
Mandatory,
ValueFromPipelineByPropertyName
)]
[Parameter(
ParameterSetName = 'commitId',
HelpMessage = "ID(s) of the VPG(s) you want to move.",
Mandatory,
ValueFromPipelineByPropertyName
)]
[ValidateNotNullOrEmpty()]
[guid[]]$vpgIdentifier,
[Parameter(
ParameterSetName = 'commitName',
HelpMessage = "'Rollback': After the seconds specified in the commitValue setting have elapsed, the failover is rolled back. HelpMessage = "'Rollback': After the seconds specified in the commitValue setting have elapsed, the failover is rolled back.
'Commit': After the seconds specified in the commitValue setting have elapsed, the failover continues, committing the virtual machines in the recovery site. 'Commit': After the seconds specified in the commitValue setting have elapsed, the failover continues, committing the virtual machines in the recovery site.
'None': The virtual machines in the VPG being failed over remain in the Before Commit state until either they are committed with Commit a failover, or rolled back with Roll back a failover. 'None': The virtual machines in the VPG being failed over remain in the Before Commit state until either they are committed with Commit a failover, or rolled back with Roll back a failover.
Default is the Site Settings setting." Default is the Site Settings setting.",
Mandatory
)]
[Parameter(
ParameterSetName = 'commitId',
HelpMessage = "'Rollback': After the seconds specified in the commitValue setting have elapsed, the failover is rolled back.
'Commit': After the seconds specified in the commitValue setting have elapsed, the failover continues, committing the virtual machines in the recovery site.
'None': The virtual machines in the VPG being failed over remain in the Before Commit state until either they are committed with Commit a failover, or rolled back with Roll back a failover.
Default is the Site Settings setting.",
Mandatory
)] )]
[ValidateSet("Rollback", "Commit", "None")] [ValidateSet("Rollback", "Commit", "None")]
[string]$commitPolicy, [string]$commitPolicy,
[Parameter( [Parameter(
ParameterSetName = 'commitName',
HelpMessage = "The amount of time, in seconds, the Move is in a 'Before Commit' state, before performing the commitPolicy setting. If omitted, the site settings default will be applied."
)]
[Parameter(
ParameterSetName = 'commitId',
HelpMessage = "The amount of time, in seconds, the Move is in a 'Before Commit' state, before performing the commitPolicy setting. If omitted, the site settings default will be applied." HelpMessage = "The amount of time, in seconds, the Move is in a 'Before Commit' state, before performing the commitPolicy setting. If omitted, the site settings default will be applied."
)] )]
# Min 5 Minutes, Max 24 Hours, Default Site Settigns. # Min 5 Minutes, Max 24 Hours, Default Site Settigns.
@@ -27,15 +62,11 @@ function Invoke-ZertoMove {
)] )]
[switch]$forceShutdown, [switch]$forceShutdown,
[Parameter( [Parameter(
ParameterSetName = "disableReverseProtection", HelpMessage = "Do not enable reverse protection. The VPG definition is kept with the status Needs Configuration and the reverse settings in the VPG definition are not set."
HelpMessage = "Do not enable reverse protection. The VPG definition is kept with the status Needs Configuration and the reverse settings in the VPG definition are not set.",
Mandatory
)] )]
[switch]$disableReverseProtection, [switch]$disableReverseProtection,
[Parameter( [Parameter(
ParameterSetName = "keepSourceVms", HelpMessage = "Prevent the protected virtual machines from being deleted in the protected site. Using this setting disables reverse protection."
HelpMessage = "Prevent the protected virtual machines from being deleted in the protected site. Using this setting disables reverse protection.",
Mandatory
)] )]
[switch]$keepSourceVms, [switch]$keepSourceVms,
[Parameter( [Parameter(
@@ -46,52 +77,50 @@ function Invoke-ZertoMove {
begin { begin {
$baseUri = "vpgs" $baseUri = "vpgs"
$body = @{
forceShutdown = $forceShutdown.IsPresent
ContinueOnPreScriptFailure = $ContinueOnPreScriptFailure.IsPresent
keepSourceVms = $keepSourceVms.IsPresent
reverseProtection = -not $disableReverseProtection.IsPresent
}
if ( $keepSourceVms.IsPresent -and -not $disableReverseProtection.IsPresent ) {
Write-Verbose 'Disabling reverse protection as keepSourceVms requires it'
$body['reverseProtection'] = $false
}
if ($PSBoundParameters.ContainsKey('commitPolicy')) {
$body['commitPolicy'] = $commitPolicy
if ($PSBoundParameters.ContainsKey('commitPolicyTimeout')) {
$body['commitPolicyTimeout'] = $commitPolicyTimeout
}
}
} }
process { process {
$body = @{ }
#TODO - use a foreach loop to populate the body without all the if statments
if ($PSBoundParameters.ContainsKey('commitPolicy')) {
$body['commitPolicy'] = $commitPolicy
}
if ($PSBoundParameters.ContainsKey('commitPolicyTimeout')) {
$body['commitPolicyTimeout'] = $commitPolicyTimeout
}
if ($PSBoundParameters.ContainsKey('forceShutdown')) {
$body['forceShutdown'] = $true
} else {
$body['forceShutdown'] = $false
}
if ($PSBoundParameters.ContainsKey('ContinueOnPreScriptFailure')) {
$body['ContinueOnPreScriptFailure'] = $true
} else {
$body['ContinueOnPreScriptFailure'] = $false
}
switch ($PSCmdlet.ParameterSetName) { switch ($PSCmdlet.ParameterSetName) {
"disableReverseProtection" { { $_ -in 'name', 'commitName' } {
$body['reverseProtection'] = $false $vpgIds = foreach ($name in $vpgName) {
$body['keepSourceVms'] = $false $vpgId = $(Get-ZertoVpg -name $name).vpgIdentifier
if ( -not $vpgId ) {
Write-Error "VPG: '$name' not found. Please check the name and try again. Skipping"
} else {
Write-Verbose "VPG: $name, ID: $vpgId"
$vpgId
}
}
} }
"keepSourceVms" { { $_ -in 'id', 'commitId' } {
$body['reverseProtection'] = $false $vpgIds = $vpgIdentifier
$body['keepSourceVms'] = $true
}
"main" {
$body['reverseProtection'] = $true
$body['keepSourceVms'] = $false
} }
} }
foreach ($name in $vpgName) {
$vpgId = $(Get-ZertoVpg -name $name).vpgIdentifier foreach ($thisId in $vpgIds) {
if ( -not $vpgId ) { $uri = "{0}/{1}/move" -f $baseUri, $thisId
Write-Error "VPG: $name not found. Please check the name and try again. Skipping" if ($PSCmdlet.ShouldProcess("Moving VPG: $thisId with settings: $($body | ConvertTo-Json)")) {
} else { Invoke-ZertoRestRequest -uri $uri -method "POST" -body $($body | ConvertTo-Json)
$uri = "{0}/{1}/move" -f $baseUri, $vpgId
if ($PSCmdlet.ShouldProcess("Moving VPG: $name with settings: $($body | convertto-json)")) {
Invoke-ZertoRestRequest -uri $uri -method "POST" -body $($body | ConvertTo-Json)
}
} }
} }
} }
@@ -1,6 +1,6 @@
<# .ExternalHelp ./en-us/ZertoApiWrapper-help.xml #> <# .ExternalHelp ./en-us/ZertoApiWrapper-help.xml #>
function Invoke-ZertoMoveCommit { function Invoke-ZertoMoveCommit {
[cmdletbinding(SupportsShouldProcess = $true)] [cmdletbinding(SupportsShouldProcess = $true, DefaultParameterSetName = "Main")]
param( param(
[Parameter( [Parameter(
HelpMessage = "Name(s) of the VPG(s) to commit.", HelpMessage = "Name(s) of the VPG(s) to commit.",
@@ -9,11 +9,16 @@ function Invoke-ZertoMoveCommit {
[ValidateNotNullOrEmpty()] [ValidateNotNullOrEmpty()]
[string[]]$vpgName, [string[]]$vpgName,
[Parameter( [Parameter(
HelpMessage = "Set this to True to reverse protect the VPG(s) to the source site. If not set, will use selection made during move initiation. True or False" HelpMessage = "Use this switch to reverse protect the VPG(s) to the source site. If neither 'ReverseProtction' nor 'KeepSourceVms' switch is specified, the commit process will use selection made during move initiation.",
ParameterSetName = 'ReverseProtect',
Mandatory
)] )]
[switch]$reverseProtection, [switch]$reverseProtection,
[Parameter( [Parameter(
HelpMessage = "Use this switch to keep the source VMs. If not set, they will be destroyed." HelpMessage = "Use this switch to keep the source VMs at the source site. If neither 'ReverseProtction' nor 'KeepSourceVms' switch is specified, the commit process will use selection made during move initiation.",
ParameterSetName = 'KeepSource',
Mandatory
)] )]
[switch]$keepSourceVms [switch]$keepSourceVms
) )
@@ -21,10 +26,16 @@ function Invoke-ZertoMoveCommit {
begin { begin {
$baseUri = "vpgs" $baseUri = "vpgs"
$body = @{ } $body = @{ }
if ($reverseProtection) { Switch ($PSCmdlet.ParameterSetName){
$body["ReverseProtection"] = $true 'KeepSource' {
} elseif ($keepSourceVms) { $body["KeepSourceVms"] = $true
$body["KeepSourceVms"] = $true $body["ReverseProtection"] = $false
}
'ReverseProtect' {
$body["ReverseProtection"] = $true
$body["KeepSourceVms"] = $false
}
} }
} }
@@ -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 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" Throw "Authorization Token has Expired. Please re-authorize to the Zerto Virtual Manager"
} else { } 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."
# Build the URI to be submitted Connect-ZertoServer -zertoServer $Script:zvmServer -zertoPort $script:zvmPort -credential $Script:CachedCredential
$submittedURI = "https://{0}:{1}/{2}/{3}" -f $script:zvmServer, $script:zvmPort, $apiVersion, $uri }# else {
try { # Build the URI to be submitted
# Set the zvmLastAction time and try to submit the REST Request $submittedURI = "https://{0}:{1}/{2}/{3}" -f $script:zvmServer, $script:zvmPort, $apiVersion, $uri
$script:zvmLastAction = (Get-Date).Ticks try {
# If running PwSh - Use this Invoke-RestMethod with passed Variables # Set the zvmLastAction time and try to submit the REST Request
if ($PSVersionTable.PSVersion.Major -ge 6) { $script:zvmLastAction = (Get-Date).Ticks
$apiRequestResults = Invoke-RestMethod -Uri $submittedURI -Headers $script:zvmHeaders -Method $method -Body $body -ContentType $contentType -Credential $credential -SkipCertificateCheck -ResponseHeadersVariable responseHeaders -TimeoutSec 100 # If running PwSh - Use this Invoke-RestMethod with passed Variables
} else { if ($PSVersionTable.PSVersion.Major -ge 6) {
# If running PowerShell 5.1 --> Do the Following $apiRequestResults = Invoke-RestMethod -Uri $submittedURI -Headers $script:zvmHeaders -Method $method -Body $body -ContentType $contentType -Credential $credential -SkipCertificateCheck -ResponseHeadersVariable responseHeaders -TimeoutSec 100
# Check to see if All Certs are Trusted. If not, Create the Policy to Trust All Certificates } else {
if ([System.Net.ServicePointManager]::CertificatePolicy.GetType().Name -ne "TrustAllCertsPolicy") { # If running PowerShell 5.1 --> Do the Following
Try { # Check to see if All Certs are Trusted. If not, Create the Policy to Trust All Certificates
$type = @' if ([System.Net.ServicePointManager]::CertificatePolicy.GetType().Name -ne "TrustAllCertsPolicy") {
Try {
$type = @'
using System.Net; using System.Net;
using System.Security.Cryptography.X509Certificates; using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy { public class TrustAllCertsPolicy : ICertificatePolicy {
@@ -67,42 +69,42 @@ public class TrustAllCertsPolicy : ICertificatePolicy {
} }
} }
'@ '@
Add-Type -TypeDefinition $type -ErrorAction SilentlyContinue Add-Type -TypeDefinition $type -ErrorAction SilentlyContinue
} Catch { } Catch {
if ($error[0].Exception -ne "Cannot add type. The type name 'TrustAllCertsPolicy already exists.") { if ($error[0].Exception -ne "Cannot add type. The type name 'TrustAllCertsPolicy already exists.") {
Write-Debug $error[0] 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 we are authenticating to the ZVM, Use this block to use Invoke-WebRequest and format the Headers as expected.
# If an error is encountered, Catch if ($uri -eq "session/add" -and $method -eq "POST") {
Write-Error -ErrorRecord $_ -ErrorAction $callerErrorActionPreference $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 the calling function does not need the headers (Default Action) return the results of the API Call
if (-not $returnHeaders) { if (-not $returnHeaders) {
return $apiRequestResults return $apiRequestResults
} else { } else {
#If Headers are required, build a PS Custom Object with the Results and the Headers #If Headers are required, build a PS Custom Object with the Results and the Headers
$apiRequestAndHeaderResults = New-Object -TypeName psobject $apiRequestAndHeaderResults = New-Object -TypeName psobject
$apiRequestAndHeaderResults | Add-Member -MemberType NoteProperty -Name "apiRequestResults" -Value $apiRequestResults $apiRequestAndHeaderResults | Add-Member -MemberType NoteProperty -Name "apiRequestResults" -Value $apiRequestResults
$apiRequestAndHeaderResults | Add-Member -MemberType NoteProperty -Name "Headers" -Value $responseHeaders $apiRequestAndHeaderResults | Add-Member -MemberType NoteProperty -Name "Headers" -Value $responseHeaders
return $apiRequestAndHeaderResults return $apiRequestAndHeaderResults
} #}
} }
} }
+11 -11
View File
@@ -1,6 +1,6 @@
<# .ExternalHelp ./en-us/ZertoApiWrapper-help.xml #> <# .ExternalHelp ./en-us/ZertoApiWrapper-help.xml #>
function New-ZertoVpg { function New-ZertoVpg {
[cmdletbinding(SupportsShouldProcess = $true)] [cmdletbinding(SupportsShouldProcess = $true, DefaultParameterSetName = "recoveryHostDatastore")]
param( param(
[Parameter( [Parameter(
HelpMessage = "Name of the VPG", HelpMessage = "Name of the VPG",
@@ -165,7 +165,7 @@ function New-ZertoVpg {
begin { begin {
# Create an identifiers table, and start converting names to identifiers. # Create an identifiers table, and start converting names to identifiers.
$identifiersTable = @{ } $identifiersTable = @{ }
$identifiersTable['recoverySiteIdentifier'] = $(Get-ZertoPeerSite -peerName $recoverySite).siteIdentifier $identifiersTable['recoverySiteIdentifier'] = Get-ZertoVirtualizationSite | Where-Object { $_.VirtualizationSiteName -like $recoverySite } | Select-Object -ExpandProperty SiteIdentifier
$peerSiteNetworks = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -networks) $peerSiteNetworks = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -networks)
$identifiersTable['failoverNetworkIdentifier'] = $peerSiteNetworks | Where-Object { $_.VirtualizationNetworkName -like $recoveryNetwork } | Select-Object -ExpandProperty NetworkIdentifier $identifiersTable['failoverNetworkIdentifier'] = $peerSiteNetworks | Where-Object { $_.VirtualizationNetworkName -like $recoveryNetwork } | Select-Object -ExpandProperty NetworkIdentifier
$identifiersTable['testNetworkIdentifier'] = $peerSiteNetworks | Where-Object { $_.VirtualizationNetworkName -like $testNetwork } | 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 # Get identifiers based on parameter set name
switch ($PSCmdlet.ParameterSetName) { switch ($PSCmdlet.ParameterSetName) {
"recoveryClusterDatastoreCluster" { "recoveryClusterDatastoreCluster" {
$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['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
} }
"recoveryClusterDatastore" { "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 $identifiersTable['datastoreIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -datastores | Where-Object { $_.DatastoreName -like $datastore }).DatastoreIdentifier
} }
"recoveryHostDatastoreCluster" { "recoveryHostDatastoreCluster" {
$identifiersTable['recoveryHostIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -hosts | Where-Object { $_.VirtualizationHostName -like $recoveryHost }).HostIdentifier $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" { "recoveryHostDatastore" {
@@ -202,12 +202,12 @@ function New-ZertoVpg {
} }
"recoveryResourcePoolDatastoreCluster" { "recoveryResourcePoolDatastoreCluster" {
$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['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
} }
"recoveryResourcePoolDatastore" { "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 $identifiersTable['datastoreIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -datastores | Where-Object { $_.DatastoreName -like $datastore }).DatastoreIdentifier
} }
} }
@@ -295,11 +295,11 @@ function New-ZertoVpg {
"recoveryHostDatastoreCluster" { "recoveryHostDatastoreCluster" {
$baseSettings.Recovery.DefaultDatastoreClusterIdentifier = $identifiersTable['datastoreClusterIdentifier'] $baseSettings.Recovery.DefaultDatastoreClusterIdentifier = $identifiersTable['datastoreClusterIdentifier']
$baseSettings.Recovery.DefaultHostIdentifier = $identifiersTable['hostIdentifier'] $baseSettings.Recovery.DefaultHostIdentifier = $identifiersTable['recoveryHostIdentifier']
} }
"recoveryHostDatastore" { "recoveryHostDatastore" {
$baseSettings.Recovery.DefaultHostIdentifier = $identifiersTable['hostIdentifier'] $baseSettings.Recovery.DefaultHostIdentifier = $identifiersTable['recoveryHostIdentifier']
$baseSettings.Recovery.DefaultDatastoreIdentifier = $identifiersTable['datastoreIdentifier'] $baseSettings.Recovery.DefaultDatastoreIdentifier = $identifiersTable['datastoreIdentifier']
} }
@@ -0,0 +1,53 @@
<# .ExternalHelp ./en-us/ZertoApiWrapper-help.xml #>
function Remove-ZertoVpgVm {
[CmdletBinding(SupportsShouldProcess, ConfirmImpact = "High")]
param (
[Parameter(
Mandatory,
HelpMessage = "Name of the VPG that contains the VM you wish to remove",
ParameterSetName = "VpgName"
)]
[ValidateNotNullOrEmpty()]
[String]$VpgName,
[Parameter(
Mandatory,
HelpMessage = "Name of VM(s) to remove from the VPG"
)]
[ValidateNotNullOrEmpty()]
[String[]]$Vm
)
begin {
}
process {
$VpgData = Get-ZertoVpg -vpgName $VpgName
if (-not $VpgData) {
Write-Error "Unable to find Vpg with name $VpgName. Please check your parameters and try again." -ErrorAction Stop
} else {
$protectedVms = Get-ZertoProtectedVm -vpgName $VpgData.VpgName
}
$VmIdentifiers = foreach ($machine in ($vm | Select-Object -Unique)) {
if ($machine -in $protectedVms.VmName) {
$protectedVms.Where( { $_.VmName -like $machine }) | Select-Object -ExpandProperty VmIdentifier
} else {
Write-Warning "Virtual Machine: '$machine' is not found in Vpg: '$VpgName'. Check your parameters. Skipping $machine"
}
}
if ($VmIdentifiers.Count -gt 0 -and $PSCmdlet.ShouldProcess(($Vm | Select-Object -Unique), "Removing VM(s): $($Vm | Select-Object -Unique) from Vpg $VpgName")) {
$vpgSettingsIdentifier = New-ZertoVpgSettingsIdentifier -vpgIdentifier $VpgData.VpgIdentifier
foreach ($identifier in $VmIdentifiers) {
$url = "vpgSettings/{0}/vms/{1}" -f $vpgSettingsIdentifier, $identifier
Invoke-ZertoRestRequest -uri $url -method DELETE
}
Save-ZertoVpgSetting -vpgSettingsIdentifier $vpgSettingsIdentifier
} else {
Write-Warning "No VMs found to remove. Please check your parameters and try again."
}
}
end {
}
}
@@ -11,7 +11,7 @@ function Save-ZertoVpgSetting {
ValueFromPipelineByPropertyName = $true ValueFromPipelineByPropertyName = $true
)] )]
[ValidateNotNullOrEmpty()] [ValidateNotNullOrEmpty()]
[Alias("vpgSettingsId")] [Alias("sid", "settingsIdentifier", "vpgSettingsId")]
[string]$vpgSettingsIdentifier [string]$vpgSettingsIdentifier
) )
+1 -1
View File
@@ -16,7 +16,7 @@ function Set-ZertoLicense {
} }
process { 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" Invoke-ZertoRestRequest -uri $baseUri -body $($body | ConvertTo-Json) -method "PUT"
} }
} }
+11 -16
View File
@@ -27,18 +27,25 @@ function Start-ZertoCloneVpg {
) )
begin { begin {
}
process {
$baseUri = "vpgs" $baseUri = "vpgs"
$vpgInfo = Get-ZertoVpg -name $vpgName $vpgInfo = Get-ZertoVpg -name $vpgName
if ( -not $vpgInfo ) { if ( -not $vpgInfo ) {
Write-Error "VPG: $vpgName could not be found. Please check the name and try again." Write-Error "VPG: $vpgName could not be found. Please check the name and try again."
} }
$vpgIdentifier = $vpgInfo.vpgIdentifier $vpgIdentifier = $vpgInfo.vpgIdentifier
$body = @{ }
if ( $PSBoundParameters.ContainsKey('datastoreName') ) { if ( $PSBoundParameters.ContainsKey('datastoreName') ) {
$recoverysiteIdentifier = $vpgInfo.recoverysite.identifier $recoverysiteIdentifier = $vpgInfo.recoverysite.identifier
$recoverySiteDatastores = Get-ZertoVirtualizationSite -siteIdentifier $recoverysiteIdentifier -datastores $recoverySiteDatastores = Get-ZertoVirtualizationSite -siteIdentifier $recoverysiteIdentifier -datastores
$datastoreIdentifier = $($recoverySiteDatastores | Where-Object { $_.datastoreName -like $datastoreName }).DatastoreIdentifier $datastoreIdentifier = $($recoverySiteDatastores | Where-Object { $_.datastoreName -like $datastoreName }).DatastoreIdentifier
if ( -not $datastoreIdentifier ) { if ( -not $datastoreIdentifier ) {
Write-Error "Datastore: $datastoreName is not a valid datastore. Please check the name and try again." -ErrorAction Stop Write-Error "Datastore: $datastoreName is not a valid datastore. Please check the name and try again." -ErrorAction Stop
} else {
$body['DatastoreIdentifier'] = $datastoreIdentifier
} }
} }
if ( $PSBoundParameters.ContainsKey('vmName') ) { if ( $PSBoundParameters.ContainsKey('vmName') ) {
@@ -55,32 +62,20 @@ function Start-ZertoCloneVpg {
} }
} }
$body['VmIdentifiers'] = $vmIdentifiers $body['VmIdentifiers'] = $vmIdentifiers
if ($checkpointIdentifier) {
$body['CheckpointIdentifier'] = $checkpointIdentifier
}
} }
}
process {
$uri = "{0}/{1}/CloneStart" -f $baseUri, $vpgIdentifier
$body = [ordered]@{ }
if ( $PSBoundParameters.ContainsKey('checkpointIdentifier') ) { if ( $PSBoundParameters.ContainsKey('checkpointIdentifier') ) {
$body['checkpointId'] = $checkpointIdentifier $body['checkpointId'] = $checkpointIdentifier
} }
if ( $datastoreIdentifier ) {
$body['DatastoreIdentifier'] = $datastoreIdentifier
}
if ( $vmIdentifiers ) {
$body['VmIdentifiers'] = $vmIdentifiers
}
Write-Verbose $body Write-Verbose $body
$uri = "{0}/{1}/CloneStart" -f $baseUri, $vpgIdentifier
if ($PSCmdlet.ShouldProcess("Clone Vpg")) { if ($PSCmdlet.ShouldProcess("Clone Vpg")) {
Invoke-ZertoRestRequest -uri $uri -body $($body | ConvertTo-Json) -method "POST" Invoke-ZertoRestRequest -uri $uri -body $($body | ConvertTo-Json) -method "POST"
Write-Verbose "Call Submitted to $uri"
Write-Verbose "With the following information: $($body | ConvertTo-Json)"
} }
} }
end { end {
Write-Verbose "Call Submitted to $uri"
Write-Verbose "With the following information: $($body | ConvertTo-Json)"
} }
} }
+55 -89
View File
@@ -11,6 +11,7 @@ trigger:
include: include:
- master - master
- PowerShellBackPort - PowerShellBackPort
- Refactor-Build
# Trigger CI on pull requests to master and develop branches # Trigger CI on pull requests to master and develop branches
pr: pr:
@@ -24,26 +25,18 @@ jobs:
pool: pool:
vmImage: windows-latest vmImage: windows-latest
steps: steps:
# Run build.ps1 script in PowerShell Core # Run build.ps1 script in PowerShell Core
- powershell: | - powershell: |
.\build.ps1 -Verbose .\build.ps1 -Verbose
displayName: 'Build and Test' displayName: "Build and Test"
# Upload test results to Azure Pipeline # Upload test results to Azure Pipeline
- task: PublishTestResults@2 - task: PublishTestResults@2
inputs: inputs:
testRunner: 'NUnit' testRunner: "NUnit"
testResultsFiles: '**/SourceTestResults.xml' testResultsFiles: "**/BuiltTestResults.xml"
testRunTitle: 'PS_Win2016_Source' testRunTitle: "PS_Win2016_Built"
displayName: 'Publish Test Results' displayName: "Publish Test Results"
condition: always() condition: always()
- task: PublishTestResults@2
inputs:
testRunner: 'NUnit'
testResultsFiles: '**/BuiltTestResults.xml'
testRunTitle: 'PS_Win2016_Built'
displayName: 'Publish Test Results'
condition: always()
# Windows PowerShell Core Build Job # Windows PowerShell Core Build Job
- job: Build_PSCore_Windows - job: Build_PSCore_Windows
@@ -52,25 +45,18 @@ jobs:
pool: pool:
vmImage: windows-latest vmImage: windows-latest
steps: steps:
# Run build.ps1 script in PowerShell Core # Run build.ps1 script in PowerShell Core
- pwsh: | - pwsh: |
.\build.ps1 -Verbose .\build.ps1 -Verbose
displayName: 'Build and Test' displayName: "Build and Test"
# Upload test results to Azure Pipeline # Upload test results to Azure Pipeline
- task: PublishTestResults@2 - task: PublishTestResults@2
inputs: inputs:
testRunner: 'NUnit' testRunner: "NUnit"
testResultsFiles: '**/SourceTestResults.xml' testResultsFiles: "**/BuiltTestResults.xml"
testRunTitle: 'PSCore_Win2016_Source' testRunTitle: "PSCore_Win2016_Built"
displayName: 'Publish Test Results' displayName: "Publish Test Results"
condition: always() condition: always()
- task: PublishTestResults@2
inputs:
testRunner: 'NUnit'
testResultsFiles: '**/BuiltTestResults.xml'
testRunTitle: 'PSCore_Win2016_Built'
displayName: 'Publish Test Results'
condition: always()
# Linux Build Job # Linux Build Job
- job: Build_PSCore_Ubuntu - job: Build_PSCore_Ubuntu
@@ -79,37 +65,24 @@ jobs:
pool: pool:
vmImage: ubuntu-latest vmImage: ubuntu-latest
steps: steps:
# Run build.ps1 script in PowerShell Core # Run build.ps1 script in PowerShell Core
- pwsh: | - pwsh: |
.\build.ps1 -verbose .\build.ps1 -verbose
displayName: 'Build and Test' displayName: "Build and Test"
# Upload test results to Azure Pipeline # Upload test results to Azure Pipeline
- task: PublishTestResults@2 - task: PublishTestResults@2
inputs: inputs:
testRunner: 'NUnit' testRunner: "NUnit"
testResultsFiles: '**/SourceTestResults.xml' testResultsFiles: "**/BuiltTestResults.xml"
testRunTitle: 'PSCore_Ubuntu_Source' testRunTitle: "PSCore_Ubuntu_Built"
displayName: 'Publish Test Results' displayName: "Publish Test Results"
condition: always() condition: always()
- task: PublishTestResults@2 - task: PublishPipelineArtifact@1
inputs: displayName: "Publish Data"
testRunner: 'NUnit' inputs:
testResultsFiles: '**/BuiltTestResults.xml' artifactName: "ReleaseData"
testRunTitle: 'PSCore_Ubuntu_Built' targetPath: ./publish
displayName: 'Publish Test Results' condition: always()
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()
# MacOS Build Job # MacOS Build Job
- job: Build_PSCore_MacOS - job: Build_PSCore_MacOS
@@ -118,22 +91,15 @@ jobs:
pool: pool:
vmImage: macOS-latest vmImage: macOS-latest
steps: steps:
# Run build.ps1 script in PowerShell Core # Run build.ps1 script in PowerShell Core
- pwsh: | - pwsh: |
.\build.ps1 -verbose .\build.ps1 -verbose
displayName: 'Build and Test' displayName: "Build and Test"
# Upload test results to Azure Pipeline # Upload test results to Azure Pipeline
- task: PublishTestResults@2 - task: PublishTestResults@2
inputs: inputs:
testRunner: 'NUnit' testRunner: "NUnit"
testResultsFiles: '**/SourceTestResults.xml' testResultsFiles: "**/BuiltTestResults.xml"
testRunTitle: 'PSCore_MacOS1013_Source' testRunTitle: "PSCore_MacOS1013_Built"
displayName: 'Publish Test Results' displayName: "Publish Test Results"
condition: always() condition: always()
- task: PublishTestResults@2
inputs:
testRunner: 'NUnit'
testResultsFiles: '**/BuiltTestResults.xml'
testRunTitle: 'PSCore_MacOS1013_Built'
displayName: 'Publish Test Results'
condition: always()
+5 -2
View File
@@ -1,3 +1,5 @@
param([validateSet("build", "release")]$operation = "build")
# Bootstrap the environment # Bootstrap the environment
$null = Get-PackageProvider -Name NuGet -ForceBootstrap $null = Get-PackageProvider -Name NuGet -ForceBootstrap
@@ -11,6 +13,7 @@ Invoke-PSDepend `
-Force ` -Force `
-Import ` -Import `
-Install ` -Install `
-Tags 'Bootstrap' -Tags 'Bootstrap' `
-ErrorAction Continue
Invoke-Build . Invoke-Build $operation
+2 -2
View File
@@ -31,10 +31,10 @@ Pairs the current Zerto Virtual Manager to the Zerto Virtual Manager at IP addre
### Example 2 ### Example 2
```powershell ```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 ## PARAMETERS
+138
View File
@@ -0,0 +1,138 @@
---
external help file: ZertoApiWrapper-help.xml
Module Name: ZertoApiWrapper
online version: https://github.com/ZertoPublic/ZertoApiWrapper/blob/master/docs/Add-ZertoVpgVm.md
schema: 2.0.0
---
# Add-ZertoVpgVm
## SYNOPSIS
Adds one or more virtual machines to an existing VPG. A VPG Settings Identifier will be returned for use in either further customization of the VPG or passed to the `Save-ZertoVpgSetting` command to commit the changes.
## SYNTAX
### VpgName (Default)
```
Add-ZertoVpgVm -VpgName <String> -Vm <String[]> [-WhatIf] [-Confirm] [<CommonParameters>]
```
### VpgSettingsIdentifier
```
Add-ZertoVpgVm -vpgSettingsIdentifier <String> -Vm <String[]> [-WhatIf] [-Confirm] [<CommonParameters>]
```
## DESCRIPTION
Adds one or more virtual machines to an existing VPG. A VPG Settings Identifier will be returned for use in either further customization of the VPG or passed to the `Save-ZertoVpgSetting` command to commit the changes.
Internal logic to the function will only process unique items and ensure that VMs meet requirements to replicate to the target site. These requirements include not currently a member of the specified VPG, not currently replicating to the target site, and not a member of 3 or more VPGs.
## EXAMPLES
### Example 1
```powershell
PS C:\> Add-ZertoVpgVm -VpgSettingsIdentifier $vpgSettingsIdentifier -Vm "VM 1", "Vm 2"
```
Adds "VM 1" and "VM 2" to the Vpg with VpgSettingsIdentifer specified in `$VpgSettingsIdentifier`. This variable was obtained via other functions that create and return a Vpg Settings Identifier. The Vpg Settings Identifier passed into the function will be returned.
### Example 2
```powershell
PS C:\> Add-ZertoVpgVm -VpgName "My Vpg" -Vm "VM 1", "Vm 2"
```
Adds "VM 1" and "VM 2" to the Vpg named "My Vpg". In this case, a new Vpg Settings Identifier will be created and returned.
## PARAMETERS
### -Vm
Name of VM(s) to add to the VPG
```yaml
Type: String[]
Parameter Sets: (All)
Aliases:
Required: True
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -VpgName
Target VPG Name to Add the VM
```yaml
Type: String
Parameter Sets: VpgName
Aliases:
Required: True
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -vpgSettingsIdentifier
Vpg Settings Identifier
```yaml
Type: String
Parameter Sets: VpgSettingsIdentifier
Aliases: sid, settingsIdentifier, vpgSettingsId
Required: True
Position: Named
Default value: None
Accept pipeline input: True (ByPropertyName, ByValue)
Accept wildcard characters: False
```
### -Confirm
Prompts you for confirmation before running the cmdlet.
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases: cf
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -WhatIf
Shows what would happen if the cmdlet runs.
The cmdlet is not run.
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases: wi
Required: False
Position: Named
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
### System.String
## OUTPUTS
### System.Object
## NOTES
## RELATED LINKS
[Adding VMs to a VPG Settings Object](https://s3.amazonaws.com/zertodownload_docs/Latest/Zerto%20Virtual%20Replication%20Zerto%20Virtual%20Manager%20(ZVM)%20-%20vSphere%20Online%20Help/content/zvr_apis/vpg_management_api.htm?tocpath=ZVR%20RESTful%20APIs%7CZerto%20APIs%7C_____20#statusapis_4057192544_1358357)
+135 -112
View File
@@ -1,112 +1,135 @@
--- ---
external help file: ZertoApiWrapper-help.xml external help file: ZertoApiWrapper-help.xml
Module Name: ZertoApiWrapper Module Name: ZertoApiWrapper
online version: https://github.com/ZertoPublic/ZertoApiWrapper/blob/master/docs/Connect-ZertoServer.md online version: https://github.com/ZertoPublic/ZertoApiWrapper/blob/master/docs/Connect-ZertoServer.md
schema: 2.0.0 schema: 2.0.0
--- ---
# Connect-ZertoServer # Connect-ZertoServer
## SYNOPSIS ## SYNOPSIS
Establishes a connection to a ZVM. Establishes a connection to a ZVM.
## SYNTAX ## SYNTAX
``` ```
Connect-ZertoServer [-zertoServer] <String> [[-zertoPort] <String>] [-credential] <PSCredential> Connect-ZertoServer [-zertoServer] <String> [-credential] <PSCredential> [-zertoPort <String>] [-AutoReconnect]
[-returnHeaders] [<CommonParameters>] [-returnHeaders] [<CommonParameters>]
``` ```
## DESCRIPTION ## DESCRIPTION
Establishes a connection to a ZVM using credentials provided via a PSCredential Object leveraging the Zerto Session API end point. Establishes a connection to a ZVM using credentials provided via a PSCredential Object leveraging the Zerto Session API end point.
## EXAMPLES ## EXAMPLES
### Example 1 ### Example 1
```powershell ```powershell
PS C:\> Connect-ZertoServer -zertoServer "192.168.1.100" -zertoPort "9669" -credential $credential 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. Establishes a connection to ZVM 192.168.1.100 on port 9669 with supplied PSCredential object.
## PARAMETERS ### Example 2
```powershell
### -credential PS C:\> Connect-ZertoServer -zertoServer "192.168.1.100" -zertoPort "9669" -credential $credential -AutoReconnect
Valid credentials to connect to the Zerto Management Server ```
```yaml Establishes a connection to ZVM 192.168.1.100 on port 9669 with supplied PSCredential object. Adding the `-AutoReconnect` switch
Type: PSCredential will cache the PSCredential object should the session need to be reauthorized due to an expired token.
Parameter Sets: (All)
Aliases: ## PARAMETERS
Required: True ### -AutoReconnect
Position: 2 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
Default value: None
Accept pipeline input: False ```yaml
Accept wildcard characters: False Type: SwitchParameter
``` Parameter Sets: (All)
Aliases:
### -returnHeaders
Use this switch to return the headers to a specified variable or to the default output. Required: False
Position: Named
```yaml Default value: None
Type: SwitchParameter Accept pipeline input: False
Parameter Sets: (All) Accept wildcard characters: False
Aliases: ```
Required: False ### -credential
Position: Named Valid credentials to connect to the Zerto Management Server
Default value: None
Accept pipeline input: False ```yaml
Accept wildcard characters: False Type: PSCredential
``` Parameter Sets: (All)
Aliases:
### -zertoPort
Zerto Virtual Manager management port. Required: True
Default value is 9669. Position: 1
Default value: None
```yaml Accept pipeline input: False
Type: String Accept wildcard characters: False
Parameter Sets: (All) ```
Aliases: port
### -returnHeaders
Required: False Use this switch to return the headers to a specified variable or to the default output.
Position: 1
Default value: "9669" ```yaml
Accept pipeline input: False Type: SwitchParameter
Accept wildcard characters: False Parameter Sets: (All)
``` Aliases:
### -zertoServer Required: False
IP address or FQDN of your Zerto Management Server Position: Named
Default value: None
```yaml Accept pipeline input: False
Type: String Accept wildcard characters: False
Parameter Sets: (All) ```
Aliases: server, zvm
### -zertoPort
Required: True Zerto Virtual Manager management port.
Position: 0 Default value is 9669.
Default value: None
Accept pipeline input: False ```yaml
Accept wildcard characters: False Type: String
``` Parameter Sets: (All)
Aliases: port
### 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). Required: False
Position: Named
## INPUTS Default value: "9669"
Accept pipeline input: False
### None Accept wildcard characters: False
## OUTPUTS ```
### System.Object ### -zertoServer
## NOTES IP address or FQDN of your Zerto Management Server
## RELATED LINKS ```yaml
Type: String
[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) Parameter Sets: (All)
Aliases: server, zvm
[PSCredential Documentation](https://docs.microsoft.com/en-us/dotnet/api/system.management.automation.pscredential?view=pscore-6.0.0)
Required: True
[Get-Credential Documentation](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/get-credential?view=powershell-6) 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)
+25 -8
View File
@@ -19,7 +19,7 @@ Get-ZertoEvent [<CommonParameters>]
### filter ### filter
``` ```
Get-ZertoEvent [-startDate <String>] [-endDate <String>] [-vpgName <String>] [-vpgIdentifier <String>] Get-ZertoEvent [-startDate <String>] [-endDate <String>] [-vpg <String>] [-vpgIdentifier <String>]
[-eventType <String>] [-siteName <String>] [-siteIdentifier <String>] [-zorgIdentifier <String>] [-eventType <String>] [-siteName <String>] [-siteIdentifier <String>] [-zorgIdentifier <String>]
[-entityType <String>] [-userName <String>] [-category <String>] [-eventCategory <String>] [-entityType <String>] [-userName <String>] [-category <String>] [-eventCategory <String>]
[-alertIdentifier <String>] [<CommonParameters>] [-alertIdentifier <String>] [<CommonParameters>]
@@ -66,13 +66,27 @@ PS C:\> Get-ZertoEvent -eventId "Need an eventID"
Returns information for each -eventID specified. Returns information for each -eventID specified.
### Example 1 ### Example 3
```powershell ```powershell
PS C:\> Get-ZertoEvent -startDate "2019-01-01" -endDate "2019-01-07" -vpg "My Vpg" 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" 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 ## PARAMETERS
### -alertIdentifier ### -alertIdentifier
@@ -112,6 +126,7 @@ The type of event to return. This filter behaves in the same way as the eventCat
Type: String Type: String
Parameter Sets: filter Parameter Sets: filter
Aliases: Aliases:
Accepted values: All, Events, Alerts
Required: False Required: False
Position: Named Position: Named
@@ -159,6 +174,7 @@ The type of entity for which you wish to return results. Possible Values are: 'V
Type: String Type: String
Parameter Sets: filter Parameter Sets: filter
Aliases: Aliases:
Accepted values: VPG, VRA, Unknown, Site
Required: False Required: False
Position: Named Position: Named
@@ -174,6 +190,7 @@ This filter behaves in the same way as the category filter. If both category and
Type: String Type: String
Parameter Sets: filter Parameter Sets: filter
Aliases: Aliases:
Accepted values: All, Events, Alerts
Required: False Required: False
Position: Named Position: Named
@@ -292,13 +309,13 @@ Accept pipeline input: False
Accept wildcard characters: False Accept wildcard characters: False
``` ```
### -vpgIdentifier ### -vpg
The identifier of the VPG for which you want to return events. The name of the VPG for which you want to return events.
```yaml ```yaml
Type: String Type: String
Parameter Sets: filter Parameter Sets: filter
Aliases: vpgId Aliases: vpgName
Required: False Required: False
Position: Named Position: Named
@@ -307,13 +324,13 @@ Accept pipeline input: False
Accept wildcard characters: False Accept wildcard characters: False
``` ```
### -vpgName ### -vpgIdentifier
The name of the VPG for which you want to return events. The identifier of the VPG for which you want to return events.
```yaml ```yaml
Type: String Type: String
Parameter Sets: filter Parameter Sets: filter
Aliases: vpg Aliases: vpgId
Required: False Required: False
Position: Named Position: Named
+1
View File
@@ -88,6 +88,7 @@ The priority specified for the VPG. Possible values are: 'Low', 'Medium', or 'Hi
Type: String Type: String
Parameter Sets: filter Parameter Sets: filter
Aliases: Aliases:
Accepted values: Low, Medium, High
Required: False Required: False
Position: Named Position: Named
+1
View File
@@ -102,6 +102,7 @@ Possible values are: 'Failover', 'Failover Test', or 'Move'
Type: String Type: String
Parameter Sets: filter Parameter Sets: filter
Aliases: Aliases:
Accepted values: Failover, Failover Test, Move
Required: False Required: False
Position: Named Position: Named
+1
View File
@@ -129,6 +129,7 @@ The status of the task. Possible values are: 'InProgress', 'Paused', 'Failed', '
Type: String Type: String
Parameter Sets: filter Parameter Sets: filter
Aliases: Aliases:
Accepted values: InProgress, Paused, Failed, Completed, Cancelling
Required: False Required: False
Position: Named Position: Named
+1
View File
@@ -271,6 +271,7 @@ The VPG priority. Possible values are: 'Low', 'Medium', 'High'
Type: String Type: String
Parameter Sets: filter Parameter Sets: filter
Aliases: Aliases:
Accepted values: Low, Medium, High
Required: False Required: False
Position: Named Position: Named
+62 -25
View File
@@ -12,23 +12,30 @@ Start a move of a VPG.
## SYNTAX ## SYNTAX
### main (Default) ### id (Default)
``` ```
Invoke-ZertoMove [-vpgName] <String[]> [[-commitPolicy] <String>] [[-commitPolicyTimeout] <Int32>] Invoke-ZertoMove -vpgIdentifier <Guid[]> [-forceShutdown] [-disableReverseProtection] [-keepSourceVms]
[-forceShutdown] [-ContinueOnPreScriptFailure] [-WhatIf] [-Confirm] [<CommonParameters>] [-ContinueOnPreScriptFailure] [-WhatIf] [-Confirm] [<CommonParameters>]
``` ```
### disableReverseProtection ### commitName
``` ```
Invoke-ZertoMove [-vpgName] <String[]> [[-commitPolicy] <String>] [[-commitPolicyTimeout] <Int32>] Invoke-ZertoMove -vpgName <String[]> -commitPolicy <String> [-commitPolicyTimeout <Int32>] [-forceShutdown]
[-forceShutdown] [-disableReverseProtection] [-ContinueOnPreScriptFailure] [-WhatIf] [-Confirm] [-disableReverseProtection] [-keepSourceVms] [-ContinueOnPreScriptFailure] [-WhatIf] [-Confirm]
[<CommonParameters>] [<CommonParameters>]
``` ```
### keepSourceVms ### name
``` ```
Invoke-ZertoMove [-vpgName] <String[]> [[-commitPolicy] <String>] [[-commitPolicyTimeout] <Int32>] Invoke-ZertoMove -vpgName <String[]> [-forceShutdown] [-disableReverseProtection] [-keepSourceVms]
[-forceShutdown] [-keepSourceVms] [-ContinueOnPreScriptFailure] [-WhatIf] [-Confirm] [<CommonParameters>] [-ContinueOnPreScriptFailure] [-WhatIf] [-Confirm] [<CommonParameters>]
```
### commitId
```
Invoke-ZertoMove -vpgIdentifier <Guid[]> -commitPolicy <String> [-commitPolicyTimeout <Int32>] [-forceShutdown]
[-disableReverseProtection] [-keepSourceVms] [-ContinueOnPreScriptFailure] [-WhatIf] [-Confirm]
[<CommonParameters>]
``` ```
## DESCRIPTION ## DESCRIPTION
@@ -38,10 +45,24 @@ Start a move of a VPG.
### Example 1 ### Example 1
```powershell ```powershell
PS C:\> Invoke-ZertoMove -vpgName "MyVpg" PS C:\> Invoke-ZertoMove -vpgName 'MyVpg'
``` ```
Starts a move operation of VPG "MyVpg" Specify the name of a vpg to move
### Example 2
```powershell
PS C:\> Invoke-ZertoMove -vpgIdentifier '2fbbf6b5-cddc-4653-b1fe-564f069eeb64'
```
Specify the identifier of a vpg to move
### Example 3
```powershell
PS C:\> Get-ZertoVpg | Invoke-ZertoMove
```
Utilize the pipeline to move multiple vpgs
## PARAMETERS ## PARAMETERS
@@ -56,11 +77,12 @@ Default is the Site Settings setting.
```yaml ```yaml
Type: String Type: String
Parameter Sets: (All) Parameter Sets: commitName, commitId
Aliases: Aliases:
Accepted values: Rollback, Commit, None
Required: False Required: True
Position: 1 Position: Named
Default value: None Default value: None
Accept pipeline input: False Accept pipeline input: False
Accept wildcard characters: False Accept wildcard characters: False
@@ -72,11 +94,11 @@ If omitted, the site settings default will be applied.
```yaml ```yaml
Type: Int32 Type: Int32
Parameter Sets: (All) Parameter Sets: commitName, commitId
Aliases: Aliases:
Required: False Required: False
Position: 2 Position: Named
Default value: None Default value: None
Accept pipeline input: False Accept pipeline input: False
Accept wildcard characters: False Accept wildcard characters: False
@@ -91,7 +113,7 @@ Parameter Sets: (All)
Aliases: Aliases:
Required: False Required: False
Position: 6 Position: Named
Default value: None Default value: None
Accept pipeline input: False Accept pipeline input: False
Accept wildcard characters: False Accept wildcard characters: False
@@ -102,10 +124,10 @@ Do not enable reverse protection. The VPG definition is kept with the status Nee
```yaml ```yaml
Type: SwitchParameter Type: SwitchParameter
Parameter Sets: disableReverseProtection Parameter Sets: (All)
Aliases: Aliases:
Required: True Required: False
Position: Named Position: Named
Default value: None Default value: None
Accept pipeline input: False Accept pipeline input: False
@@ -121,7 +143,7 @@ Parameter Sets: (All)
Aliases: Aliases:
Required: False Required: False
Position: 3 Position: Named
Default value: None Default value: None
Accept pipeline input: False Accept pipeline input: False
Accept wildcard characters: False Accept wildcard characters: False
@@ -132,13 +154,28 @@ Use this switch to Prevent the protected virtual machines from being deleted in
```yaml ```yaml
Type: SwitchParameter Type: SwitchParameter
Parameter Sets: keepSourceVms Parameter Sets: (All)
Aliases:
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -vpgIdentifier
ID(s) of the VPG(s) you want to move.
```yaml
Type: Guid[]
Parameter Sets: id, commitId
Aliases: Aliases:
Required: True Required: True
Position: 5 Position: Named
Default value: None Default value: None
Accept pipeline input: False Accept pipeline input: True (ByPropertyName)
Accept wildcard characters: False Accept wildcard characters: False
``` ```
@@ -147,11 +184,11 @@ Name(s) of the VPG(s) you want to move.
```yaml ```yaml
Type: String[] Type: String[]
Parameter Sets: (All) Parameter Sets: commitName, name
Aliases: Aliases:
Required: True Required: True
Position: 0 Position: Named
Default value: None Default value: None
Accept pipeline input: False Accept pipeline input: False
Accept wildcard characters: False Accept wildcard characters: False
+34 -11
View File
@@ -12,9 +12,19 @@ Commit a VPG currently undergoing a move operation.
## SYNTAX ## SYNTAX
### Main (Default)
``` ```
Invoke-ZertoMoveCommit [-vpgName] <String[]> [-reverseProtection] [-keepSourceVms] [-WhatIf] [-Confirm] Invoke-ZertoMoveCommit -vpgName <String[]> [-WhatIf] [-Confirm] [<CommonParameters>]
[<CommonParameters>] ```
### ReverseProtect
```
Invoke-ZertoMoveCommit -vpgName <String[]> [-reverseProtection] [-WhatIf] [-Confirm] [<CommonParameters>]
```
### KeepSource
```
Invoke-ZertoMoveCommit -vpgName <String[]> [-keepSourceVms] [-WhatIf] [-Confirm] [<CommonParameters>]
``` ```
## DESCRIPTION ## DESCRIPTION
@@ -27,20 +37,33 @@ Commit a VPG currently undergoing a move operation.
PS C:\> Invoke-ZertoMoveCommit -vpgName "MyVpg" PS C:\> Invoke-ZertoMoveCommit -vpgName "MyVpg"
``` ```
Commit VPG "MyVpg" after a move has been started. Commit VPG "MyVpg" after a move operation has been completed. This commit process with use the `-KeepSourceVms` or `-ReverseProtection` selection made during the move initation.
### Example 2
```powershell
PS C:\> Invoke-ZertoMoveCommit -vpgName "MyVpg" -keepSourceVms
```
Commit VPG "MyVpg" after a move operation has been completed specifying to keep the vms at the source location and NOT reverse protection. This commit process will overrule any reverse protection or keep source vms selection made during the move initiation.
### Example 3
```powershell
PS C:\> Invoke-ZertoMoveCommit -vpgName "MyVpg" -reverseProtection
```
Commit VPG "MyVpg" after a move operation has been completed specifying to reverse protection of the VMs back to the source location. The VMs at the source location will be removed from inventory at the source location and the disks will be used as pre-seed volumes. This commit process will overrule any reverse protection or keep source vms selection made during the move initiation.
## PARAMETERS ## PARAMETERS
### -keepSourceVms ### -keepSourceVms
Use this switch to keep the source VMs. "Use this switch to keep the source VMs at the source site. If neither 'ReverseProtction' nor 'KeepSourceVms' switch is specified, the commit process will use selection made during move initiation."
If not set, they will be destroyed.
```yaml ```yaml
Type: SwitchParameter Type: SwitchParameter
Parameter Sets: (All) Parameter Sets: KeepSource
Aliases: Aliases:
Required: False Required: True
Position: Named Position: Named
Default value: None Default value: None
Accept pipeline input: False Accept pipeline input: False
@@ -48,14 +71,14 @@ Accept wildcard characters: False
``` ```
### -reverseProtection ### -reverseProtection
Set this to True to reverse protect the VPG(s) to the source site. If not set, will use selection made during move initiation. True or False "Use this switch to reverse protect the VPG(s) to the source site. If neither 'ReverseProtction' nor 'KeepSourceVms' switch is specified, the commit process will use selection made during move initiation."
```yaml ```yaml
Type: SwitchParameter Type: SwitchParameter
Parameter Sets: (All) Parameter Sets: ReverseProtect
Aliases: Aliases:
Required: False Required: True
Position: Named Position: Named
Default value: None Default value: None
Accept pipeline input: False Accept pipeline input: False
@@ -71,7 +94,7 @@ Parameter Sets: (All)
Aliases: Aliases:
Required: True Required: True
Position: 0 Position: Named
Default value: None Default value: None
Accept pipeline input: False Accept pipeline input: False
Accept wildcard characters: False Accept wildcard characters: False
+13 -13
View File
@@ -8,10 +8,20 @@ schema: 2.0.0
# New-ZertoVpg # New-ZertoVpg
## SYNOPSIS ## SYNOPSIS
Creates a New VPG with default settings only. Customization of VM settings can be accomplished with other module level functions. Creates a New VPG with default settings only. Customization of VM settings can be accomplished with other module level functions. Returns a VpgSettingsIdentifier to be passed into the `Save-ZertoVpgSetting` function to create the VPG.
## SYNTAX ## SYNTAX
### recoveryHostDatastore (Default)
```
New-ZertoVpg -vpgName <String> [-vpgPriority <String>] [-journalHistoryInHours <Int32>] -protectedVm <String[]>
-recoverySite <String> -recoveryHost <String> -datastore <String> -recoveryFolder <String>
[-rpoInSeconds <Int32>] [-testIntervalInMinutes <Int32>] [-serviceProfile <String>]
[-useWanCompression <Boolean>] [-zorg <String>] -recoveryNetwork <String> -testNetwork <String>
[-journalDatastore <String>] [-journalHardLimitInMb <UInt64>] [-journalWarningThresholdInMb <UInt64>]
[-WhatIf] [-Confirm] [<CommonParameters>]
```
### recoveryClusterDatastoreCluster ### recoveryClusterDatastoreCluster
``` ```
New-ZertoVpg -vpgName <String> [-vpgPriority <String>] [-journalHistoryInHours <Int32>] -protectedVm <String[]> New-ZertoVpg -vpgName <String> [-vpgPriority <String>] [-journalHistoryInHours <Int32>] -protectedVm <String[]>
@@ -42,16 +52,6 @@ New-ZertoVpg -vpgName <String> [-vpgPriority <String>] [-journalHistoryInHours <
[-WhatIf] [-Confirm] [<CommonParameters>] [-WhatIf] [-Confirm] [<CommonParameters>]
``` ```
### recoveryHostDatastore
```
New-ZertoVpg -vpgName <String> [-vpgPriority <String>] [-journalHistoryInHours <Int32>] -protectedVm <String[]>
-recoverySite <String> -recoveryHost <String> -datastore <String> -recoveryFolder <String>
[-rpoInSeconds <Int32>] [-testIntervalInMinutes <Int32>] [-serviceProfile <String>]
[-useWanCompression <Boolean>] [-zorg <String>] -recoveryNetwork <String> -testNetwork <String>
[-journalDatastore <String>] [-journalHardLimitInMb <UInt64>] [-journalWarningThresholdInMb <UInt64>]
[-WhatIf] [-Confirm] [<CommonParameters>]
```
### recoveryResourcePoolDatastoreCluster ### recoveryResourcePoolDatastoreCluster
``` ```
New-ZertoVpg -vpgName <String> [-vpgPriority <String>] [-journalHistoryInHours <Int32>] -protectedVm <String[]> New-ZertoVpg -vpgName <String> [-vpgPriority <String>] [-journalHistoryInHours <Int32>] -protectedVm <String[]>
@@ -176,7 +176,7 @@ Name of the datastore where the VM(s), Volume(s), and Journal(s) will reside.
```yaml ```yaml
Type: String Type: String
Parameter Sets: recoveryClusterDatastore, recoveryHostDatastore, recoveryResourcePoolDatastore Parameter Sets: recoveryHostDatastore, recoveryClusterDatastore, recoveryResourcePoolDatastore
Aliases: Aliases:
Required: True Required: True
@@ -312,7 +312,7 @@ Name of the host where the VM(s) will be recovered.
```yaml ```yaml
Type: String Type: String
Parameter Sets: recoveryHostDatastoreCluster, recoveryHostDatastore Parameter Sets: recoveryHostDatastore, recoveryHostDatastoreCluster
Aliases: Aliases:
Required: True Required: True
+2 -2
View File
@@ -21,7 +21,7 @@ Remove-ZertoVpg -vpgidentifier <String[]> [-keepRecoveryVolumes] [-force] [-What
### vpgName ### vpgName
``` ```
Remove-ZertoVpg [-vpgName] <String[]> [-keepRecoveryVolumes] [-force] [-WhatIf] [-Confirm] [<CommonParameters>] Remove-ZertoVpg -vpgName <String[]> [-keepRecoveryVolumes] [-force] [-WhatIf] [-Confirm] [<CommonParameters>]
``` ```
## DESCRIPTION ## DESCRIPTION
@@ -122,7 +122,7 @@ Parameter Sets: vpgName
Aliases: Aliases:
Required: True Required: True
Position: 0 Position: Named
Default value: None Default value: None
Accept pipeline input: True (ByPropertyName, ByValue) Accept pipeline input: True (ByPropertyName, ByValue)
Accept wildcard characters: False Accept wildcard characters: False
+121
View File
@@ -0,0 +1,121 @@
---
external help file: ZertoApiWrapper-help.xml
Module Name: ZertoApiWrapper
online version: https://github.com/ZertoPublic/ZertoApiWrapper/blob/master/docs/Resume-ZertoVpgVm.md
schema: 2.0.0
---
# Remove-ZertoVpgVm
## SYNOPSIS
Removes one or more VMs from a specified VPG. A Task Identifier is returned to track progress.
## SYNTAX
```
Remove-ZertoVpgVm -VpgName <String> -Vm <String[]> [-WhatIf] [-Confirm] [<CommonParameters>]
```
## DESCRIPTION
Removes one or more VMs from a specified VPG. A Task Identifier is returned to track progress. Internal logic will remove duplicate VM names from the list of VMs provided as well as ensure membership in the VPG specified prior to attempting to remove the VM from the VPG. Finally the VPG is saved to commit the changes. ChangeImpact is set to 'High' to get the confirmation prompt.
## EXAMPLES
### Example 1
```powershell
PS C:\> Remove-ZertoVpgVm -VpgName 'My Vpg' -Vm 'Vm 1'
```
Removes 'Vm 1' from Vpg named 'My Vpg'
### Example 2
```powershell
PS C:\> Remove-ZertoVpgVm -VpgName 'My Vpg' -Vm 'Vm 1', 'Vm 2'
```
Removes 'Vm 1' and 'Vm 2' from Vpg named 'My Vpg'.
### Example 3
```powershell
PS C:\> Remove-ZertoVpgVm -VpgName 'My Vpg' -Vm 'Vm 1', 'Vm 2' -Confirm:$False
```
Removes 'Vm 1' and 'Vm 2' from Vpg named 'My Vpg' and bypasses the confirmation prompt
## PARAMETERS
### -Vm
Name of VM(s) to remove from the VPG
```yaml
Type: String[]
Parameter Sets: (All)
Aliases:
Required: True
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -VpgName
Name of the VPG that contains the VM you wish to remove
```yaml
Type: String
Parameter Sets: (All)
Aliases:
Required: True
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -Confirm
Prompts you for confirmation before running the cmdlet.
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases: cf
Required: False
Position: Named
Default value: None
Accept pipeline input: False
Accept wildcard characters: False
```
### -WhatIf
Shows what would happen if the cmdlet runs.
The cmdlet is not run.
```yaml
Type: SwitchParameter
Parameter Sets: (All)
Aliases: wi
Required: False
Position: Named
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
[Remove Vms from a VPG Settings Object](https://s3.amazonaws.com/zertodownload_docs/Latest/Zerto%20Virtual%20Replication%20Zerto%20Virtual%20Manager%20(ZVM)%20-%20vSphere%20Online%20Help/content/zvr_apis/vpg_management_api.htm?tocpath=ZVR%20RESTful%20APIs%7CZerto%20APIs%7C_____20#statusapis_4057192544_1361409)
+2 -2
View File
@@ -36,10 +36,10 @@ VpgSettings Identifier to save
```yaml ```yaml
Type: String Type: String
Parameter Sets: (All) Parameter Sets: (All)
Aliases: vpgSettingsId Aliases: sid, settingsIdentifier, vpgSettingsId
Required: True Required: True
Position: 1 Position: 0
Default value: None Default value: None
Accept pipeline input: True (ByPropertyName, ByValue) Accept pipeline input: True (ByPropertyName, ByValue)
Accept wildcard characters: False Accept wildcard characters: False
+1 -1
View File
@@ -1 +1 @@
1.4.1 1.5.3