From b076942d26bd25d2f1bc6bcbba2beb35c2971fb3 Mon Sep 17 00:00:00 2001 From: Wes Carroll Date: Mon, 11 Mar 2019 19:17:33 -0400 Subject: [PATCH 1/4] Add Journal Default Settings in MB functionality --- ZertoApiWrapper/Public/New-ZertoVpg.ps1 | 28 ++++++++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/ZertoApiWrapper/Public/New-ZertoVpg.ps1 b/ZertoApiWrapper/Public/New-ZertoVpg.ps1 index 783a9a7..b8666ae 100644 --- a/ZertoApiWrapper/Public/New-ZertoVpg.ps1 +++ b/ZertoApiWrapper/Public/New-ZertoVpg.ps1 @@ -126,7 +126,22 @@ function New-ZertoVpg { HelpMessage = "Name of the network to use during a Failover Test operation", Mandatory = $true )] - [string]$testNetwork + [string]$testNetwork, + [Parameter( + HelpMessage = "Name of the datastore to utilize to store Journal data. If not specified, the default datastore will be used.", + Mandatory = $false + )] + [string]$journalDatastore, + [Parameter( + HelpMessage = "Default journal hard limit in megabytes. Default set to 150MB.", + Mandatory = $false + )] + [int]$journalHardLimitInMb = 150, + [Parameter( + HelpMessage = "Default journal warning threshold in megabytes. If unset, will be set to 75% of the journal hard limit.", + Mandatory = $false + )] + [int]$journalWarningThresholdInMb = 0 ) begin { @@ -142,6 +157,9 @@ function New-ZertoVpg { if ($PSBoundParameters.ContainsKey("serviceProfile")) { $identifiersTable['serviceProfileIdentifier'] = $(Get-ZertoServiceProfile -siteIdentifier $identifiersTable['recoverySiteIdentifier'] | Where-Object {$_.ServiceProfileName -like $serviceProfile}).serviceProfileIdentifier } + if ($PSBoundParameters.ContainsKey('journalDatastore')) { + $identifiersTable['journalDatastore'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -datastores | Where-Object {$_.DatastoreName -like $journalDatastore}).DatastoreIdentifier + } switch ($PSCmdlet.ParameterSetName) { "recoveryClusterDatastoreCluster" { $identifiersTable['clusterIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -hostclusters | Where-Object {$_.VirtualizationClusterName -like $recoveryCluster}).ClusterIdentifier @@ -194,6 +212,9 @@ function New-ZertoVpg { $returnObject | Add-Member -MemberType NoteProperty -Name "VmIdentifier" -Value $vmIdentifier $returnObject } + if (($journalWarningThresholdInMb -eq 0) -or ($journalWarningThresholdInMb -gt $journalHardLimitInMb)) { + $journalWarningThresholdInMb = $journalHardLimitInMb * .75 + } } process { @@ -253,6 +274,11 @@ function New-ZertoVpg { } else { $baseSettings.Vms = $vmIdentifiers } + if ($identifiersTable.ContainsKey('journalDatastore')) { + $baseSettings.Journal.DatastoreIdentifier = $identifiersTable['journalDatastore'] + } + $baseSettings.Journal.Limitation.HardLimitInMB = $journalHardLimitInMb + $baseSettings.Journal.Limitation.WarningThresholdInMB = $journalWarningThresholdInMb $settingsURI = "{0}/{1}" -f $baseUri, $vpgSettingsIdentifier Invoke-ZertoRestRequest -uri $settingsURI -body $($baseSettings | ConvertTo-Json -Depth 10) -method "PUT" | Out-Null } From 96b797b4c870077aa5913331ff7b07f4c5fe307a Mon Sep 17 00:00:00 2001 From: Wes Carroll Date: Mon, 11 Mar 2019 20:04:06 -0400 Subject: [PATCH 2/4] Add comments to understand what the code is doing --- ZertoApiWrapper/Public/New-ZertoVpg.ps1 | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/ZertoApiWrapper/Public/New-ZertoVpg.ps1 b/ZertoApiWrapper/Public/New-ZertoVpg.ps1 index b8666ae..6cc6150 100644 --- a/ZertoApiWrapper/Public/New-ZertoVpg.ps1 +++ b/ZertoApiWrapper/Public/New-ZertoVpg.ps1 @@ -133,18 +133,19 @@ function New-ZertoVpg { )] [string]$journalDatastore, [Parameter( - HelpMessage = "Default journal hard limit in megabytes. Default set to 150MB.", + HelpMessage = "Default journal hard limit in megabytes. Default set to 150MB. Set to 0 to set the journal to unlimited", Mandatory = $false )] - [int]$journalHardLimitInMb = 150, + [int]$journalHardLimitInMb = 153600, [Parameter( - HelpMessage = "Default journal warning threshold in megabytes. If unset, will be set to 75% of the journal hard limit.", + HelpMessage = "Default journal warning threshold in megabytes. If unset or greater than the hard limit, will be set to 75% of the journal hard limit.", Mandatory = $false )] [int]$journalWarningThresholdInMb = 0 ) begin { + # Create an identifiers table, and start converting names to identifiers. $identifiersTable = @{} $identifiersTable['recoverySiteIdentifier'] = $(Get-ZertoPeerSite -peerName $recoverySite).siteIdentifier $peerSiteNetworks = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -networks) @@ -160,6 +161,7 @@ function New-ZertoVpg { if ($PSBoundParameters.ContainsKey('journalDatastore')) { $identifiersTable['journalDatastore'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -datastores | Where-Object {$_.DatastoreName -like $journalDatastore}).DatastoreIdentifier } + # Get identifiers based on parameter set name switch ($PSCmdlet.ParameterSetName) { "recoveryClusterDatastoreCluster" { $identifiersTable['clusterIdentifier'] = $(Get-ZertoVirtualizationSite -siteIdentifier $identifiersTable['recoverySiteIdentifier'] -hostclusters | Where-Object {$_.VirtualizationClusterName -like $recoveryCluster}).ClusterIdentifier @@ -193,11 +195,16 @@ function New-ZertoVpg { } $unprotectedVms = Get-ZertoUnprotectedVm $protectedVms = Get-ZertoProtectedVm + # Create array of VM identifiers $vmIdentifiers = @() $vmIdentifiers = foreach ($vm in $protectedVm) { + # If the VM is unprotected, get the identifier $vmIdentifier = $unprotectedVms | Where-Object {$_.vmName -like $vm} | 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 $vm} | Select-Object -ExpandProperty vmIdentifier + # If VM is currently a member of 3 VPGs, skip it. If it cannot be found, skip it. Otherwise, set the identifier if ($results.count -eq 3) { Write-Warning "$vm is already a part of 3 VPGs and cannot be part of an additional VPG. Skipping $vm" continue @@ -208,6 +215,7 @@ function New-ZertoVpg { $vmIdentifier = $results | Select-Object -First 1 } } + # Create a custom object to store the information to easily convert to JSON. Return to vmIdentifiers array. $returnObject = New-Object PSObject $returnObject | Add-Member -MemberType NoteProperty -Name "VmIdentifier" -Value $vmIdentifier $returnObject @@ -219,8 +227,11 @@ function New-ZertoVpg { process { $baseUri = "vpgsettings" + # Create a VPG Settings Identifier $vpgSettingsIdentifier = Invoke-ZertoRestRequest -uri $baseUri -body "{}" -method "POST" + # Put base settings into an object easy to manipulate $baseSettings = Get-ZertoVpgSetting -vpgSettingsIdentifier $vpgSettingsIdentifier + # Set settings equal to passed and default parameters $baseSettings.basic.name = $vpgName $baseSettings.basic.journalHistoryInHours = $journalHistoryInHours $baseSettings.basic.Priority = $vpgPriority @@ -268,6 +279,7 @@ function New-ZertoVpg { $baseSettings.Recovery.DefaultDatastoreIdentifier = $identifiersTable['datastoreIdentifier'] } } + # If only 1 VM is selected, force VMs settings to be an array. If ($vmIdentifiers.count -eq 1) { $basesettings.Vms = @() $baseSettings.Vms += $vmIdentifiers @@ -284,6 +296,7 @@ function New-ZertoVpg { } end { + # Return vpgSettings Identifier as a string to pass into Save function. return $vpgSettingsIdentifier.toString() } } \ No newline at end of file From 9308353807e16ff68543344b13a75b49e7201883 Mon Sep 17 00:00:00 2001 From: Wes Carroll Date: Mon, 11 Mar 2019 20:18:18 -0400 Subject: [PATCH 3/4] Update Journal Hard Limit HelpMessage --- ZertoApiWrapper/Public/New-ZertoVpg.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/ZertoApiWrapper/Public/New-ZertoVpg.ps1 b/ZertoApiWrapper/Public/New-ZertoVpg.ps1 index 6cc6150..1ea7fe8 100644 --- a/ZertoApiWrapper/Public/New-ZertoVpg.ps1 +++ b/ZertoApiWrapper/Public/New-ZertoVpg.ps1 @@ -133,7 +133,7 @@ function New-ZertoVpg { )] [string]$journalDatastore, [Parameter( - HelpMessage = "Default journal hard limit in megabytes. Default set to 150MB. Set to 0 to set the journal to unlimited", + HelpMessage = "Default journal hard limit in megabytes. Default set to 153600 MB (150 GB). Set to 0 to set the journal to unlimited", Mandatory = $false )] [int]$journalHardLimitInMb = 153600, From 4f9f5e26ae60655a42dfd1e24ba7f7f6db0c9742 Mon Sep 17 00:00:00 2001 From: Wes Carroll Date: Mon, 11 Mar 2019 20:38:51 -0400 Subject: [PATCH 4/4] Add help information for default journal settings --- .../Public/en-us/ZertoApiWrapper-help.xml | 254 +++++++++++++++++- docs/New-ZertoVpg.md | 55 +++- 2 files changed, 307 insertions(+), 2 deletions(-) diff --git a/ZertoApiWrapper/Public/en-us/ZertoApiWrapper-help.xml b/ZertoApiWrapper/Public/en-us/ZertoApiWrapper-help.xml index b2cf3fb..64a1bf9 100644 --- a/ZertoApiWrapper/Public/en-us/ZertoApiWrapper-help.xml +++ b/ZertoApiWrapper/Public/en-us/ZertoApiWrapper-help.xml @@ -7894,6 +7894,30 @@ None + + journalDatastore + + Name of the datastore to utilize to store Journal data. If not specified, the default datastore will be used. + + String + + String + + + None + + + journalHardLimitInMb + + Default journal hard limit in megabytes. Default set to 153600 MB (150 GB). Set to 0 to set the journal to unlimited + + Int32 + + Int32 + + + 153600 + journalHistoryInHours @@ -7906,6 +7930,18 @@ 24 + + journalWarningThresholdInMb + + Default journal warning threshold in megabytes. If unset or greater than the hard limit, will be set to 75% of the journal hard limit. If the journalHardLimitInMB is set to 0 (unlimited), this will be set to unlimited as well. + + Int32 + + Int32 + + + None + protectedVm @@ -8090,6 +8126,30 @@ None + + journalDatastore + + Name of the datastore to utilize to store Journal data. If not specified, the default datastore will be used. + + String + + String + + + None + + + journalHardLimitInMb + + Default journal hard limit in megabytes. Default set to 153600 MB (150 GB). Set to 0 to set the journal to unlimited + + Int32 + + Int32 + + + 153600 + journalHistoryInHours @@ -8102,6 +8162,18 @@ 24 + + journalWarningThresholdInMb + + Default journal warning threshold in megabytes. If unset or greater than the hard limit, will be set to 75% of the journal hard limit. If the journalHardLimitInMB is set to 0 (unlimited), this will be set to unlimited as well. + + Int32 + + Int32 + + + None + protectedVm @@ -8286,6 +8358,30 @@ None + + journalDatastore + + Name of the datastore to utilize to store Journal data. If not specified, the default datastore will be used. + + String + + String + + + None + + + journalHardLimitInMb + + Default journal hard limit in megabytes. Default set to 153600 MB (150 GB). Set to 0 to set the journal to unlimited + + Int32 + + Int32 + + + 153600 + journalHistoryInHours @@ -8298,6 +8394,18 @@ 24 + + journalWarningThresholdInMb + + Default journal warning threshold in megabytes. If unset or greater than the hard limit, will be set to 75% of the journal hard limit. If the journalHardLimitInMB is set to 0 (unlimited), this will be set to unlimited as well. + + Int32 + + Int32 + + + None + protectedVm @@ -8482,6 +8590,30 @@ None + + journalDatastore + + Name of the datastore to utilize to store Journal data. If not specified, the default datastore will be used. + + String + + String + + + None + + + journalHardLimitInMb + + Default journal hard limit in megabytes. Default set to 153600 MB (150 GB). Set to 0 to set the journal to unlimited + + Int32 + + Int32 + + + 153600 + journalHistoryInHours @@ -8494,6 +8626,18 @@ 24 + + journalWarningThresholdInMb + + Default journal warning threshold in megabytes. If unset or greater than the hard limit, will be set to 75% of the journal hard limit. If the journalHardLimitInMB is set to 0 (unlimited), this will be set to unlimited as well. + + Int32 + + Int32 + + + None + protectedVm @@ -8678,6 +8822,30 @@ None + + journalDatastore + + Name of the datastore to utilize to store Journal data. If not specified, the default datastore will be used. + + String + + String + + + None + + + journalHardLimitInMb + + Default journal hard limit in megabytes. Default set to 153600 MB (150 GB). Set to 0 to set the journal to unlimited + + Int32 + + Int32 + + + 153600 + journalHistoryInHours @@ -8690,6 +8858,18 @@ 24 + + journalWarningThresholdInMb + + Default journal warning threshold in megabytes. If unset or greater than the hard limit, will be set to 75% of the journal hard limit. If the journalHardLimitInMB is set to 0 (unlimited), this will be set to unlimited as well. + + Int32 + + Int32 + + + None + protectedVm @@ -8874,6 +9054,30 @@ None + + journalDatastore + + Name of the datastore to utilize to store Journal data. If not specified, the default datastore will be used. + + String + + String + + + None + + + journalHardLimitInMb + + Default journal hard limit in megabytes. Default set to 153600 MB (150 GB). Set to 0 to set the journal to unlimited + + Int32 + + Int32 + + + 153600 + journalHistoryInHours @@ -8886,6 +9090,18 @@ 24 + + journalWarningThresholdInMb + + Default journal warning threshold in megabytes. If unset or greater than the hard limit, will be set to 75% of the journal hard limit. If the journalHardLimitInMB is set to 0 (unlimited), this will be set to unlimited as well. + + Int32 + + Int32 + + + None + protectedVm @@ -9082,6 +9298,30 @@ None + + journalDatastore + + Name of the datastore to utilize to store Journal data. If not specified, the default datastore will be used. + + String + + String + + + None + + + journalHardLimitInMb + + Default journal hard limit in megabytes. Default set to 153600 MB (150 GB). Set to 0 to set the journal to unlimited + + Int32 + + Int32 + + + 153600 + journalHistoryInHours @@ -9094,6 +9334,18 @@ 24 + + journalWarningThresholdInMb + + Default journal warning threshold in megabytes. If unset or greater than the hard limit, will be set to 75% of the journal hard limit. If the journalHardLimitInMB is set to 0 (unlimited), this will be set to unlimited as well. + + Int32 + + Int32 + + + None + protectedVm @@ -9372,7 +9624,7 @@ - -------------------------- Example 5 -------------------------- + -------------------------- Example 6 -------------------------- PS C:> New-ZertoVpg -vpgName "MyVpg" -protectedVm "WebServer01", "AppServer01", "DatabaseServer01" -recoverySite "Recovery Site" -recoveryFolder "Recovered VMs" -recoveryResourcePool "Recovery Resource Pool Name" -recoveryDatastoreCluster "Datastore Cluster Name" -testNetwork "Test Bubble Network" -recoveryNetwork "VM Network" Creates a VPG Settings Object for a VPG called "MyVpg" and protecting Virtual Machines "WebServer01", "AppServer01", and "DatabaseServer01" targeting site "Recovery Site." The Virtual machines will be placed on the resource pool "Recovery Resource Pool Name" on the datastore cluster named "Datastore Cluster Name." When the virtual machines are created at the recovery site, they will be created in the folder "Recovered VMs." Finally, the network to be used during a live event will be "VM Network" and during a test operation will be "VM Network." Other values set will be the defaults, such as: diff --git a/docs/New-ZertoVpg.md b/docs/New-ZertoVpg.md index 1ceb1fb..46aea84 100644 --- a/docs/New-ZertoVpg.md +++ b/docs/New-ZertoVpg.md @@ -18,6 +18,7 @@ New-ZertoVpg -vpgName [-vpgPriority ] [-journalHistoryInHours < -recoverySite -recoveryCluster -datastoreCluster -recoveryFolder [-rpoInSeconds ] [-testIntervalInMinutes ] [-serviceProfile ] [-useWanCompression ] [-zorg ] -recoveryNetwork -testNetwork + [-journalDatastore ] [-journalHardLimitInMb ] [-journalWarningThresholdInMb ] [] ``` @@ -27,6 +28,7 @@ New-ZertoVpg -vpgName [-vpgPriority ] [-journalHistoryInHours < -recoverySite -recoveryCluster -datastore -recoveryFolder [-rpoInSeconds ] [-testIntervalInMinutes ] [-serviceProfile ] [-useWanCompression ] [-zorg ] -recoveryNetwork -testNetwork + [-journalDatastore ] [-journalHardLimitInMb ] [-journalWarningThresholdInMb ] [] ``` @@ -36,6 +38,7 @@ New-ZertoVpg -vpgName [-vpgPriority ] [-journalHistoryInHours < -recoverySite -recoveryHost -datastoreCluster -recoveryFolder [-rpoInSeconds ] [-testIntervalInMinutes ] [-serviceProfile ] [-useWanCompression ] [-zorg ] -recoveryNetwork -testNetwork + [-journalDatastore ] [-journalHardLimitInMb ] [-journalWarningThresholdInMb ] [] ``` @@ -45,6 +48,7 @@ New-ZertoVpg -vpgName [-vpgPriority ] [-journalHistoryInHours < -recoverySite -recoveryHost -datastore -recoveryFolder [-rpoInSeconds ] [-testIntervalInMinutes ] [-serviceProfile ] [-useWanCompression ] [-zorg ] -recoveryNetwork -testNetwork + [-journalDatastore ] [-journalHardLimitInMb ] [-journalWarningThresholdInMb ] [] ``` @@ -54,6 +58,7 @@ New-ZertoVpg -vpgName [-vpgPriority ] [-journalHistoryInHours < -recoverySite -recoveryResourcePool -datastoreCluster -recoveryFolder [-rpoInSeconds ] [-testIntervalInMinutes ] [-serviceProfile ] [-useWanCompression ] [-zorg ] -recoveryNetwork -testNetwork + [-journalDatastore ] [-journalHardLimitInMb ] [-journalWarningThresholdInMb ] [] ``` @@ -63,6 +68,7 @@ New-ZertoVpg -vpgName [-vpgPriority ] [-journalHistoryInHours < -recoverySite -recoveryResourcePool -datastore -recoveryFolder [-rpoInSeconds ] [-testIntervalInMinutes ] [-serviceProfile ] [-useWanCompression ] [-zorg ] -recoveryNetwork -testNetwork + [-journalDatastore ] [-journalHardLimitInMb ] [-journalWarningThresholdInMb ] [] ``` @@ -148,7 +154,7 @@ Creates a VPG Settings Object for a VPG called "MyVpg" and protecting Virtual Ma - ServiceProfile: Null - Zorg: Null -### Example 5 +### Example 6 ```powershell PS C:> New-ZertoVpg -vpgName "MyVpg" -protectedVm "WebServer01", "AppServer01", "DatabaseServer01" -recoverySite "Recovery Site" -recoveryFolder "Recovered VMs" -recoveryResourcePool "Recovery Resource Pool Name" -recoveryDatastoreCluster "Datastore Cluster Name" -testNetwork "Test Bubble Network" -recoveryNetwork "VM Network" ``` @@ -195,6 +201,36 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -journalDatastore +Name of the datastore to utilize to store Journal data. If not specified, the default datastore will be used. + +```yaml +Type: String +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + +### -journalHardLimitInMb +Default journal hard limit in megabytes. Default set to 153600 MB (150 GB). Set to 0 to set the journal to unlimited + +```yaml +Type: Int32 +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: 153600 +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -journalHistoryInHours Journal History in Hours. Min 1 hour, Max 720 Hours (30 days) @@ -211,6 +247,21 @@ Accept pipeline input: False Accept wildcard characters: False ``` +### -journalWarningThresholdInMb +Default journal warning threshold in megabytes. If unset or greater than the hard limit, will be set to 75% of the journal hard limit. If the journalHardLimitInMB is set to 0 (unlimited), this will be set to unlimited as well. + +```yaml +Type: Int32 +Parameter Sets: (All) +Aliases: + +Required: False +Position: Named +Default value: None +Accept pipeline input: False +Accept wildcard characters: False +``` + ### -protectedVm Name(s) of the VM(s) to be protected. @@ -451,7 +502,9 @@ This cmdlet supports the common parameters: -Debug, -ErrorAction, -ErrorVariable ### System.String Vpg Settings Identifier + ## NOTES ## RELATED LINKS + [Zerto REST API VPG Settings End Point Documentation](http://s3.amazonaws.com/zertodownload_docs/Latest/Zerto%20Virtual%20Replication%20Zerto%20Virtual%20Manager%20%28ZVM%29%20-%20vSphere%20Online%20Help/RestfulAPIs/StatusAPIs.5.108.html#) \ No newline at end of file