{"id":749,"date":"2022-02-15T00:00:18","date_gmt":"2022-02-15T00:00:18","guid":{"rendered":"http:\/\/192.168.8.14\/?p=749"},"modified":"2022-02-15T00:00:25","modified_gmt":"2022-02-15T00:00:25","slug":"get-info-out-of-the-zerto-analytic-portal","status":"publish","type":"post","link":"https:\/\/www.jasonstreet.com\/?p=749","title":{"rendered":"Get info out of the Zerto analytic portal"},"content":{"rendered":"\n<p>This is a part of a script I have been using for about 2 years to pull basic data out of the Zerto analytic portal. I have really only just scratched the surface of what I can get.<\/p>\n\n\n\n<p>When I first wrote this all I needed was the number of green\/yellow\/red VPGs but there is so much more.<\/p>\n\n\n\n<p>Below is the code needed to connect to the portal and pull out a VPG list, alerts, VM info.<br>once connected, each section will pull put an object array. how you use that is up to you.<\/p>\n\n\n<div class=\"wp-block-syntaxhighlighter-code \"><pre class=\"brush: powershell; title: ; notranslate\" title=\"\">\n## User Prefs\n## load credentials from file\n# to create cred file open a powershell window as the user that will be running the script\n# run\n#   $credential = Get-Credential\n# enter the userID and password in the dialog box.\n# run\n#   $credential | Export-CliXml -Path &#039;&#x5B;Path]\\&#x5B;filename].xml&#039;\n# done!\n$Credentials = Import-CliXml -Path &#039;&#x5B;Path]\\&#x5B;filename].xml&#039;\n# putting creds in variables is not good but the HTTPS $body need them in that format.\n$zaUsername = $Credentials.GetNetworkCredential().username\n$zaPassword = $Credentials.GetNetworkCredential().password\n\n$zaUsername = &quot;user ID&quot;   # best to use a credential object and delete these 2 lines.\n$zaPassword = &quot;password&quot;   # best to use a credential object and delete these 2 lines.\n\n\n\n## functions\n\n# I copied this function from StackOverflow.com I have no idea what this function does except make the invoke web request work, I had to use this in early 2021 as Zerto changed something on there site.\nfunction Set-UseUnsafeHeaderParsing\n{\n    param(\n        &#x5B;Parameter(Mandatory,ParameterSetName=&#039;Enable&#039;)]\n        &#x5B;switch]$Enable,\n\n        &#x5B;Parameter(Mandatory,ParameterSetName=&#039;Disable&#039;)]\n        &#x5B;switch]$Disable\n    )\n\n    $ShouldEnable = $PSCmdlet.ParameterSetName -eq &#039;Enable&#039;\n\n    $netAssembly = &#x5B;Reflection.Assembly]::GetAssembly(&#x5B;System.Net.Configuration.SettingsSection])\n\n    if($netAssembly)\n    {\n        $bindingFlags = &#x5B;Reflection.BindingFlags] &#039;Static,GetProperty,NonPublic&#039;\n        $settingsType = $netAssembly.GetType(&#039;System.Net.Configuration.SettingsSectionInternal&#039;)\n\n        $instance = $settingsType.InvokeMember(&#039;Section&#039;, $bindingFlags, $null, $null, @())\n\n        if($instance)\n        {\n            $bindingFlags = &#039;NonPublic&#039;,&#039;Instance&#039;\n            $useUnsafeHeaderParsingField = $settingsType.GetField(&#039;useUnsafeHeaderParsing&#039;, $bindingFlags)\n\n            if($useUnsafeHeaderParsingField)\n            {\n              $useUnsafeHeaderParsingField.SetValue($instance, $ShouldEnable)\n            }\n        }\n    }\n}\n\n## end of functions\n\n\n\n\n\n\n&#x5B;System.Net.ServicePointManager]::SecurityProtocol = &#x5B;System.Net.SecurityProtocolType]::Tls12 -bor &#x5B;System.Net.SecurityProtocolType]::Tls11\n\n\n\n#Getting Zerto Analytics Token\n$body = &#039;{&quot;username&quot;: &quot;&#039; + $zaUsername + &#039;&quot;,&quot;password&quot;:&quot;&#039; + $zaPassword + &#039;&quot;}&#039;\n$contentType = &#039;application\/json&#039;\n\nSet-UseUnsafeHeaderParsing -Enable\n\n$xZertoAnalyticsToken = Invoke-RestMethod -Uri &quot;https:\/\/analytics.api.zerto.com\/v2\/auth\/token&quot; -Method POST -Body $body -ContentType $contentType \n\n#Build authorization header\n$authHeaders = @{&quot;Authorization&quot; = &quot;Bearer &quot; + $xZertoAnalyticsToken.token}\n\n\n#Get RPO statistics for VPG\n#Set the vpgIdentifier of the VPG you want to pull statistics for\n$vpgIdentifier = &quot;VPGID&quot;\n\n#Get the current time\n$CurrentDateTime = Get-Date\n\n#Get current time -5 minutes to pull statistics from last 5 minutes\n$ts = New-TimeSpan -Minutes 5\n$FiveMinutseAgo = Get-Date($CurrentDateTime-$ts) -Format O\n\n#URL Encode time\n$FiveMinutesAgo = &#x5B;System.Web.HttpUtility]::UrlEncode($FiveMinutesAgo) \n\n$getRpoStatsUrl = &quot;https:\/\/analytics.api.zerto.com\/v2\/reports\/stats-rpo?startDate=&quot; + $FiveMinutesAgo + &quot;&amp;vpgIdentifier=&quot; + $vpgIdentifier\n\n\n\n## get VMs\n$getRpoStatsUrl = &quot;https:\/\/analytics.api.zerto.com\/v2\/monitoring\/protected-vms&quot;\n$ZertoVMs = Invoke-RestMethod -Uri $getRpoStatsUrl -Headers $authHeaders \n\n\n## get Sites\n$getRpoStatsUrl = &quot;https:\/\/analytics.api.zerto.com\/v2\/reports\/sites-list&quot;\n$ZertoSites = Invoke-RestMethod -Uri $getRpoStatsUrl -Headers $authHeaders \n\n\n## Get alerts\n$getRpoStatsUrl = &quot;https:\/\/analytics.api.zerto.com\/v2\/monitoring\/alerts&quot;\n$ZertoAlerts = Invoke-RestMethod -Uri $getRpoStatsUrl -Headers $authHeaders \n\n\n## Get VPGs\n$getRpoStatsUrl = &quot;https:\/\/analytics.api.zerto.com\/v2\/monitoring\/vpgs&quot;\n$ResZertoVPGs = Invoke-RestMethod -Uri $getRpoStatsUrl -Headers $authHeaders \n$ZertoVPGs = $ResZertoVPGs.vpgs\n\n\n## Get journel info\n$getJournalsUrl = &quot;https:\/\/analytics.api.zerto.com\/v2\/reports\/stats-journal-storage?endDate=(YYYY)-(MM)-(DD)T(hh)%3A(mm)%3A(ss)Z&amp;vpgIdentifier=(VPG GUID)&quot;\n$ResJournals = Invoke-RestMethod -Uri $getJournalsUrl -Headers $authHeaders \n$ZertoJstat = $ResJournals\n\n# get all VPGs in protected site\n$sitevpgs = $ZertoVPGs | where{$_.protectedSite&#x5B;0].name -eq &quot;(Site name)&quot;}\n\n<\/pre><\/div>","protected":false},"excerpt":{"rendered":"<p>This is a part of a script I have been using for about 2 years to pull basic data out of the Zerto analytic portal. I have really only just scratched the surface of what I can get. When I first wrote this all I needed was the number of green\/yellow\/red VPGs but there is&#8230;<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_monsterinsights_skip_tracking":false,"_monsterinsights_sitenote_active":false,"_monsterinsights_sitenote_note":"","_monsterinsights_sitenote_category":0,"footnotes":""},"categories":[4,27,155],"tags":[158,17,13,10,22,8,157,156],"class_list":["post-749","post","type-post","status-publish","format-standard","hentry","category-powershell","category-tutorial","category-zerto","tag-analytic-portal","tag-function","tag-powershell","tag-report","tag-tutorial","tag-vm","tag-vpg","tag-zerto"],"_links":{"self":[{"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=\/wp\/v2\/posts\/749","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=749"}],"version-history":[{"count":1,"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=\/wp\/v2\/posts\/749\/revisions"}],"predecessor-version":[{"id":750,"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=\/wp\/v2\/posts\/749\/revisions\/750"}],"wp:attachment":[{"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=749"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=749"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.jasonstreet.com\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=749"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}