Solved

Powershell Script of detailed Protection Domain configuration

  • 29 July 2019
  • 3 replies
  • 2874 views

Userlevel 2
Badge +1
I have lots of Protection Domains. I need to keep their schedules straight, prevent overlap, and report the schedules to management. I am not the only admin, so I cannot track the configuration manually.

Is there a powershell cmdlet that presents this information? I cannot find it. I want to know the schedule and the replication information(sites and how many to retain). I'm not using protection policies, just old school PD.

Thanks,
Bill Beavis
icon

Best answer by bbeavis 1 August 2019, 17:57

So based on Support's answer and no one reporting here, I concluded that there is no cmdlet and I need to use REST API calls to get to the data.

Here is what I have cobbled together thus far (this isn't the actual code, I've anonymized it a little)

code:
Add-PSSnapin -Name NutanixCmdletsPSSnapin 
. "c:\scripts\Update-Wiki.ps1"

$nxUser = 'wiki'
$nxPassword = convertto-securestring ""
$FullReport=@()

$password = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR( $nxPassword ))
$secpassword = $nxPassword
$RemoteSites = @{"Cluster1" = "RemoteSite2";"Cluster2" = "RemoteSite1"}
$Weekdays = @{1 = "Sun";2 = "Mon";3 = "Tue";4 = "Wed";5 = "Thu";6 = "Fri";7 = "Sat"}

$strCurrentTimeZone = (Get-WmiObject win32_timezone).StandardName
$TZ = [System.TimeZoneInfo]::FindSystemTimeZoneById($strCurrentTimeZone)
$origin = New-Object -Type DateTime -ArgumentList 1970, 1, 1, 0, 0, 0, 0
$Header = @{"Authorization" = "Basic "+[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($nxUser+":"+$password ))}
$ProgressPreference = 'SilentlyContinue'


foreach ($Cluster in $RemoteSites.keys) {
Connect-NutanixCluster -Server $cluster -UserName $nxUser -Password $secpassword -AcceptInvalidSSLCerts -ForcedConnection | Out-Null
$pdlist = Get-NTNXProtectionDomain | Where {$_.Active -eq $true}

foreach ($pd in $pdlist) {
$URL = "https://"+$Cluster+":9440/PrismGateway/services/rest/v1/protection_domains/"+$pd.name+"/schedules"
try { $output = Invoke-RestMethod -Method Get -Uri $URL -Headers $Header -UseBasicParsing } catch { $output = '' }

foreach ($schedule in $output) {
$whatIWant = $origin.AddSeconds(($schedule.userStartTimeInUsecs + 0 ) / 1000000)
$LocalTime = [System.TimeZoneInfo]::ConvertTimeFromUtc($whatIWant, $TZ)

$scheduledtime = $LocalTime.Hour.ToString() + ":" + $LocalTime.Minute.ToString("00")
$weeklyobj = @()
foreach ($val in $schedule.values) { $weeklyobj += $weekdays[$val] }
Switch ($schedule.type) {
"DAILY" { $values = ""}
"WEEKLY" { $values = $weeklyobj -join ','}
"MONTHLY" { $values = $schedule.values }
}

$ClusterAbbrev = $Cluster.ToUpper().Substring(0,2)

$props=[ordered]@{
"Name" = $pd.name
"Type" = $schedule.type
"Values" = $values
"Nth" = $schedule.everyNth
"Time" = $scheduledtime
"Local_Copies" = $schedule.retentionpolicy.localMaxSnapshots
"Remote_Copies" = $schedule.retentionpolicy.remoteMaxSnapshots.$($remotesites[$cluster])
"Cluster" = $ClusterAbbrev
"#VMs" = $pd.vms.count
"VMs" = $pd.vms.vmname -join ']][['
"VGs" = $pd.volumegroups.name -join ']][['
}
$Reportobject= New-Object PSObject -Property $props
$fullreport += $Reportobject
}
}
Disconnect-NutanixCluster -Servers $Cluster
}

$FullReport = $FullReport | sort Cluster, Name

#####################

$linkedheaders = @("Name", "VMs", "VGs")

Update-Wiki "https:///" "Nutanix PDs" "Nutanix PDs" (Convert-PSObject-Wiki ($fullreport) $linkedheaders)
View original

This topic has been closed for comments

3 replies

Userlevel 2
Badge +1
So based on Support's answer and no one reporting here, I concluded that there is no cmdlet and I need to use REST API calls to get to the data.

Here is what I have cobbled together thus far (this isn't the actual code, I've anonymized it a little)

code:
Add-PSSnapin -Name NutanixCmdletsPSSnapin 
. "c:\scripts\Update-Wiki.ps1"

$nxUser = 'wiki'
$nxPassword = convertto-securestring ""
$FullReport=@()

$password = [Runtime.InteropServices.Marshal]::PtrToStringAuto([Runtime.InteropServices.Marshal]::SecureStringToBSTR( $nxPassword ))
$secpassword = $nxPassword
$RemoteSites = @{"Cluster1" = "RemoteSite2";"Cluster2" = "RemoteSite1"}
$Weekdays = @{1 = "Sun";2 = "Mon";3 = "Tue";4 = "Wed";5 = "Thu";6 = "Fri";7 = "Sat"}

$strCurrentTimeZone = (Get-WmiObject win32_timezone).StandardName
$TZ = [System.TimeZoneInfo]::FindSystemTimeZoneById($strCurrentTimeZone)
$origin = New-Object -Type DateTime -ArgumentList 1970, 1, 1, 0, 0, 0, 0
$Header = @{"Authorization" = "Basic "+[System.Convert]::ToBase64String([System.Text.Encoding]::UTF8.GetBytes($nxUser+":"+$password ))}
$ProgressPreference = 'SilentlyContinue'


foreach ($Cluster in $RemoteSites.keys) {
Connect-NutanixCluster -Server $cluster -UserName $nxUser -Password $secpassword -AcceptInvalidSSLCerts -ForcedConnection | Out-Null
$pdlist = Get-NTNXProtectionDomain | Where {$_.Active -eq $true}

foreach ($pd in $pdlist) {
$URL = "https://"+$Cluster+":9440/PrismGateway/services/rest/v1/protection_domains/"+$pd.name+"/schedules"
try { $output = Invoke-RestMethod -Method Get -Uri $URL -Headers $Header -UseBasicParsing } catch { $output = '' }

foreach ($schedule in $output) {
$whatIWant = $origin.AddSeconds(($schedule.userStartTimeInUsecs + 0 ) / 1000000)
$LocalTime = [System.TimeZoneInfo]::ConvertTimeFromUtc($whatIWant, $TZ)

$scheduledtime = $LocalTime.Hour.ToString() + ":" + $LocalTime.Minute.ToString("00")
$weeklyobj = @()
foreach ($val in $schedule.values) { $weeklyobj += $weekdays[$val] }
Switch ($schedule.type) {
"DAILY" { $values = ""}
"WEEKLY" { $values = $weeklyobj -join ','}
"MONTHLY" { $values = $schedule.values }
}

$ClusterAbbrev = $Cluster.ToUpper().Substring(0,2)

$props=[ordered]@{
"Name" = $pd.name
"Type" = $schedule.type
"Values" = $values
"Nth" = $schedule.everyNth
"Time" = $scheduledtime
"Local_Copies" = $schedule.retentionpolicy.localMaxSnapshots
"Remote_Copies" = $schedule.retentionpolicy.remoteMaxSnapshots.$($remotesites[$cluster])
"Cluster" = $ClusterAbbrev
"#VMs" = $pd.vms.count
"VMs" = $pd.vms.vmname -join ']][['
"VGs" = $pd.volumegroups.name -join ']][['
}
$Reportobject= New-Object PSObject -Property $props
$fullreport += $Reportobject
}
}
Disconnect-NutanixCluster -Servers $Cluster
}

$FullReport = $FullReport | sort Cluster, Name

#####################

$linkedheaders = @("Name", "VMs", "VGs")

Update-Wiki "https:///" "Nutanix PDs" "Nutanix PDs" (Convert-PSObject-Wiki ($fullreport) $linkedheaders)
Userlevel 3
Badge +2
You can use NIACtool v2.3.1, have protection domain and snap on protection.

https://github.com/dlira2/Nutanix-tools-for-AHV/raw/master/NIACtool%20v2.3.1.zip
Userlevel 7
Badge +35
Thanks for sharing @bbeavis