Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Tests/Public/Copy-ZertoVpg.Tests.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ Describe $global:function -Tag 'Unit', 'Source', 'Built' {
@{ParameterName = 'SourceVpgName'; Type = 'String'; Mandatory = $true; Validation = 'NotNullOrEmpty' }
@{ParameterName = 'NewVpgName'; Type = 'String'; Mandatory = $true; Validation = 'NotNullOrEmpty' }
@{ParameterName = 'VMs'; Type = 'String[]'; Mandatory = $true; Validation = 'NotNullOrEmpty' }
@{ParameterName = 'StoragePolicyIdentifier'; Type = 'String'; Mandatory = $false; Validation = 'NotNullOrEmpty' }
)

It "<ParameterName> parameter is of <Type> type" -TestCases $ParameterTestCases {
Expand Down
19 changes: 13 additions & 6 deletions ZertoApiWrapper/Public/Copy-ZertoVpg.ps1
Original file line number Diff line number Diff line change
Expand Up @@ -11,25 +11,29 @@ function Copy-ZertoVpg {
[Parameter(Mandatory,
HelpMessage = "Name to assign the newly created VPG")]
[ValidateNotNullOrEmpty()]
[String]$NewVpgName, # Name of VMs to add to the VPG
[String]$NewVpgName, # New VPG Name
[Parameter(Mandatory,
HelpMessage = "Name(s) of the Virtual Machine(s) to add to the VPG")]
[ValidateNotNullOrEmpty()]
[String[]]$VMs
[String[]]$VMs, # Name of VMs to add to the VPG
[Parameter(HelpMessage = "vdcstorageProfile Identifier for VPGs that recover to VCD")]
[ValidateNotNullOrEmpty()]
[String]$StoragePolicyIdentifier
)

begin {

}

process {
$VpgIdToCopy = @{ VpgIdentifier = (Get-ZertoVpg -vpgName $SourceVpgName).vpgIdentifier }
$SourceVpg = Get-ZertoVpg -vpgName $SourceVpgName
$VpgIdToCopy = @{ VpgIdentifier = $SourceVpg.vpgIdentifier }
if ( $null -eq $VpgIdToCopy.VpgIdentifier ) {
Throw "Unable to find a VPG with the name: $SourceVpgName. Please check the name and try again."
}
$BaseUri = "vpgSettings/copyVpgSettings"
$VmsMap = Get-Map -InputObject (Get-ZertoUnprotectedVm) -Key 'VmName' -Value 'VmIdentifier'
$VmsMap += Get-Map -InputObject (Get-ZertoProtectedVm) -Key 'VmName' -Value 'VmIdentifier'
$VmsMap = Get-Map -InputObject (Get-ZertoUnprotectedVm -site $SourceVpg.protectedsite.identifier) -Key 'VmName' -Value 'VmIdentifier'
$VmsMap += Get-Map -InputObject (Get-ZertoProtectedVm -protectedSiteIdentifier $SourceVpg.protectedsite.identifier) -Key 'VmName' -Value 'VmIdentifier'
$VMsToAdd = foreach ($VM in $VMs) {
if ($VmsMap.Keys -contains $VM) {
[PSCustomObject]@{
Expand All @@ -43,11 +47,14 @@ function Copy-ZertoVpg {
$NewVpgId = Invoke-ZertoRestRequest -Uri $BaseUri -Body ($VpgIdToCopy | ConvertTo-Json) -Method "POST"
$Uri = "{0}/{1}/vms" -f "vpgSettings", $NewVpgId
foreach ($VM in $VMsToAdd) {
$null = Invoke-ZertoRestRequest -Uri $Uri -Body ($VM | ConvertTo-Json) -Method "POST" -ErrorAction Stop
$null = Invoke-ZertoRestRequest -Uri $Uri -Body ($VM | ConvertTo-Json) -Method "POST" -ErrorAction Continue
}
$Uri = "vpgSettings/{0}" -f $NewVpgId
$CurrentSettings = Invoke-ZertoRestRequest -Uri $Uri
$CurrentSettings.Basic.Name = $NewVpgName
if ($CurrentSettings.Recovery.VCD.OrgVdcIdentifier -ne $null) {
$CurrentSettings.vms[0].Recovery.VCD.StoragePolicyIdentifier = $StoragePolicyIdentifier
}
$Null = Invoke-ZertoRestRequest -Uri $Uri -Method "Put" -Body $($CurrentSettings | ConvertTo-Json -Depth 20)
Save-ZertoVpgSetting -vpgSettingsIdentifier $NewVpgId
}
Expand Down
202 changes: 202 additions & 0 deletions ZertoApiWrapper/Public/en-us/ZertoApiWrapper-help.xml
Original file line number Diff line number Diff line change
Expand Up @@ -437,6 +437,208 @@
</maml:navigationLink>
</command:relatedLinks>
</command:command>
<command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10" xmlns:MSHelp="http://msdn.microsoft.com/mshelp">
<command:details>
<command:name>Copy-ZertoVpg</command:name>
<command:verb>Copy</command:verb>
<command:noun>ZertoVpg</command:noun>
<maml:description>
<maml:para>Copy an existing VPG settings object to create a new VPG with the same settings. New VMs must be added to the copied VPG.</maml:para>
</maml:description>
</command:details>
<maml:description>
<maml:para>Copy an existing VPG settings object to create a new VPG with the same settings. New VMs must be added to the copied VPG.</maml:para>
</maml:description>
<command:syntax>
<command:syntaxItem>
<maml:name>Copy-ZertoVpg</maml:name>
<command:parameter required="true" variableLength="true" globbing="false" pipelineInput="False" position="1" aliases="none">
<maml:name>SourceVpgName</maml:name>
<maml:Description>
<maml:para>Name of the VPG to clone</maml:para>
</maml:Description>
<command:parameterValue required="true" variableLength="false">String</command:parameterValue>
<dev:type>
<maml:name>String</maml:name>
<maml:uri />
</dev:type>
<dev:defaultValue>None</dev:defaultValue>
</command:parameter>
<command:parameter required="true" variableLength="true" globbing="false" pipelineInput="False" position="2" aliases="none">
<maml:name>NewVpgName</maml:name>
<maml:Description>
<maml:para>Name to assign the newly created VPG</maml:para>
</maml:Description>
<command:parameterValue required="true" variableLength="false">String</command:parameterValue>
<dev:type>
<maml:name>String</maml:name>
<maml:uri />
</dev:type>
<dev:defaultValue>None</dev:defaultValue>
</command:parameter>
<command:parameter required="true" variableLength="true" globbing="false" pipelineInput="False" position="3" aliases="none">
<maml:name>VMs</maml:name>
<maml:Description>
<maml:para>Name of VMs to add to the VPG</maml:para>
</maml:Description>
<command:parameterValue required="true" variableLength="false">String[]</command:parameterValue>
<dev:type>
<maml:name>String[]</maml:name>
<maml:uri />
</dev:type>
<dev:defaultValue>None</dev:defaultValue>
</command:parameter>
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="1" aliases="none">
<maml:name>StoragePolicyIdentifier</maml:name>
<maml:Description>
<maml:para>VCD Storage Profile Identifier for VPGs that recover to VCD</maml:para>
</maml:Description>
<command:parameterValue required="false" variableLength="false">String</command:parameterValue>
<dev:type>
<maml:name>String</maml:name>
<maml:uri />
</dev:type>
<dev:defaultValue>None</dev:defaultValue>
</command:parameter>
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="named" aliases="cf">
<maml:name>Confirm</maml:name>
<maml:Description>
<maml:para>Prompts you for confirmation before running the cmdlet.</maml:para>
</maml:Description>
<dev:type>
<maml:name>SwitchParameter</maml:name>
<maml:uri />
</dev:type>
<dev:defaultValue>False</dev:defaultValue>
</command:parameter>
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="named" aliases="wi">
<maml:name>WhatIf</maml:name>
<maml:Description>
<maml:para>Shows what would happen if the cmdlet runs. The cmdlet is not run.</maml:para>
</maml:Description>
<dev:type>
<maml:name>SwitchParameter</maml:name>
<maml:uri />
</dev:type>
<dev:defaultValue>False</dev:defaultValue>
</command:parameter>
</command:syntaxItem>
</command:syntax>
<command:parameters>
<command:parameter required="true" variableLength="true" globbing="false" pipelineInput="False" position="2" aliases="none">
<maml:name>NewVpgName</maml:name>
<maml:Description>
<maml:para>Name to assign the newly created VPG</maml:para>
</maml:Description>
<command:parameterValue required="true" variableLength="false">String</command:parameterValue>
<dev:type>
<maml:name>String</maml:name>
<maml:uri />
</dev:type>
<dev:defaultValue>None</dev:defaultValue>
</command:parameter>
<command:parameter required="true" variableLength="true" globbing="false" pipelineInput="False" position="1" aliases="none">
<maml:name>SourceVpgName</maml:name>
<maml:Description>
<maml:para>Name of the VPG to clone</maml:para>
</maml:Description>
<command:parameterValue required="true" variableLength="false">String</command:parameterValue>
<dev:type>
<maml:name>String</maml:name>
<maml:uri />
</dev:type>
<dev:defaultValue>None</dev:defaultValue>
</command:parameter>
<command:parameter required="true" variableLength="true" globbing="false" pipelineInput="False" position="3" aliases="none">
<maml:name>VMs</maml:name>
<maml:Description>
<maml:para>Name of VMs to add to the VPG</maml:para>
</maml:Description>
<command:parameterValue required="true" variableLength="false">String[]</command:parameterValue>
<dev:type>
<maml:name>String[]</maml:name>
<maml:uri />
</dev:type>
<dev:defaultValue>None</dev:defaultValue>
</command:parameter>
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="3" aliases="none">
<maml:name>StoragePolicyIdentifier</maml:name>
<maml:Description>
<maml:para>VCD Storage Profile Identifier for VPGs that recover to VCD</maml:para>
</maml:Description>
<command:parameterValue required="false" variableLength="false">String[]</command:parameterValue>
<dev:type>
<maml:name>String[]</maml:name>
<maml:uri />
</dev:type>
<dev:defaultValue>None</dev:defaultValue>
</command:parameter>
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="named" aliases="cf">
<maml:name>Confirm</maml:name>
<maml:Description>
<maml:para>Prompts you for confirmation before running the cmdlet.</maml:para>
</maml:Description>
<command:parameterValue required="false" variableLength="false">SwitchParameter</command:parameterValue>
<dev:type>
<maml:name>SwitchParameter</maml:name>
<maml:uri />
</dev:type>
<dev:defaultValue>False</dev:defaultValue>
</command:parameter>
<command:parameter required="false" variableLength="true" globbing="false" pipelineInput="False" position="named" aliases="wi">
<maml:name>WhatIf</maml:name>
<maml:Description>
<maml:para>Shows what would happen if the cmdlet runs. The cmdlet is not run.</maml:para>
</maml:Description>
<command:parameterValue required="false" variableLength="false">SwitchParameter</command:parameterValue>
<dev:type>
<maml:name>SwitchParameter</maml:name>
<maml:uri />
</dev:type>
<dev:defaultValue>False</dev:defaultValue>
</command:parameter>
</command:parameters>
<command:inputTypes />
<command:returnValues />
<maml:alertSet>
<maml:alert>
<maml:para></maml:para>
</maml:alert>
</maml:alertSet>
<command:examples>
<command:example>
<maml:title>-------------------------- Example 1 --------------------------</maml:title>
<dev:code>PS C:\&gt; Copy-ZertoVpg -SourceVpgName 'MyVpg' -NewVpgName 'MyNewVpg' -VMs 'VmToAdd01'</dev:code>
<dev:remarks>
<maml:para>Copies the settings of 'MyVpg' into a new VPG 'MyNewVpg' adding one VM, 'VmToAdd01'</maml:para>
</dev:remarks>
</command:example>
<command:example>
<maml:title>-------------------------- Example 2 --------------------------</maml:title>
<dev:code>PS C:\&gt; Copy-ZertoVpg -SourceVpgName 'MyVpg' -NewVpgName 'MyNewVpg' -VMs 'VmToAdd01', 'VmToAdd02'</dev:code>
<dev:remarks>
<maml:para>Copies the settings of 'MyVpg' into a new VPG 'MyNewVpg' adding two VMs, 'VmToAdd01' and 'VmToAdd02'</maml:para>
</dev:remarks>
</command:example>
<command:example>
<maml:title>-------------------------- Example 3 --------------------------</maml:title>
<dev:code>PS C:\&gt; Copy-ZertoVpg -SourceVpgName 'MyVpg' -NewVpgName 'MyNewVpg' -VMs 'VmToAdd01' -StoragePolicyIdentifier 'urn:vcloud:vdcstorageProfile:00000000-0000-0000-0000-000000000000'</dev:code>
<dev:remarks>
<maml:para>Copies the settings of 'MyVpg' into a new VPG 'MyNewVpg' adding one VM, 'VmToAdd01', that recovers to VCD with the StoragePolicyIdentifier, 'urn:vcloud:vdcstorageProfile:00000000-0000-0000-0000-000000000000'</maml:para>
</dev:remarks>
</command:example>
</command:examples>
<command:relatedLinks>
<maml:navigationLink>
<maml:linkText>Online Version:</maml:linkText>
<maml:uri>https://github.com/ZertoPublic/ZertoApiWrapper/blob/master/docs/Copy-ZertoVpg.md</maml:uri>
</maml:navigationLink>
<maml:navigationLink>
<maml:linkText>Zerto Clone VPG API Endpoint Documentation</maml:linkText>
<maml:uri>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.119.html%23</maml:uri>
</maml:navigationLink>
</command:relatedLinks>
</command:command>
<command:command xmlns:maml="http://schemas.microsoft.com/maml/2004/10" xmlns:command="http://schemas.microsoft.com/maml/dev/command/2004/10" xmlns:dev="http://schemas.microsoft.com/maml/dev/2004/10" xmlns:MSHelp="http://msdn.microsoft.com/mshelp">
<command:details>
<command:name>Disconnect-ZertoServer</command:name>
Expand Down