{"id":304,"date":"2015-11-11T14:25:45","date_gmt":"2015-11-11T21:25:45","guid":{"rendered":"http:\/\/blog.gptnet.net\/?p=304"},"modified":"2017-03-16T08:28:17","modified_gmt":"2017-03-16T15:28:17","slug":"304","status":"publish","type":"post","link":"https:\/\/blog.gptnet.net\/?p=304","title":{"rendered":"3PAR WSAPI via Powershell"},"content":{"rendered":"<p>Earlier I&#8217;ve demonstrated how to use 3PAR CLI with Powershell. In this example I will show how to work with 3PAR&#8217;s WSAPI via Powershell and poll last time remote copy group was synchronized (i use Last Sync date from first volume in the remote copy group).<\/p>\n<p>I was asked to create solution to monitor replication via Recovery Manager for SQL as it sometimes fails for whichever reason and we don&#8217;t get notification that our SQL server wasn&#8217;t synchronizing to DR side for a while. I have special place for this product from HP (read my earlier posts).<\/p>\n<p>If you&#8217;re using WSAPI to only read information, i recommend you create brand new account with limited privileges, as oppose to using 3paradm. <\/p>\n<p><!--more--><br \/>\nFirst check if WSAIP is enabled. By default it is disabled, but can be easily enabled.<br \/>\n<code>cli% showwsapi<br \/>\n-Service- -State- -HTTP_State- HTTP_Port -HTTPS_State- HTTPS_Port -Version-<br \/>\nEnabled   Active  Disabled          8008 Enabled             8080 1.4.2<\/code><\/p>\n<p>If service shows as Disabled, run the following command:<br \/>\n<code>cli% startwsapi<\/code><br \/>\nOptional, you can configure either http or https. I suggest only use https (in my example i use SSL and have code to deal with self signed certs)<br \/>\n<code>cli% setwsapi -http enable<br \/>\ncli% setwsapi -https enable<\/code><\/p>\n<p>Now to Powershell example:<\/p>\n<pre class=\"brush:powershell\">\r\n# Name: 3PAR_RC_Check.ps1\r\n# Author: Naz Snidanko\r\n# Date Created: Nov 11, 2015\r\n# Date Modified: \r\n# Version: 0.1\r\n# Description: uses WSAPI to poll last sync of the 3par group. Checks if last sync is older than X days and sends email alert.\r\n# Credit: http:\/\/setspn.blogspot.ca\/2014\/11\/3par-connect-to-webapi-using-powershell.html\r\n############# START EDIT ##############\r\n#Credentials  \r\n$username = \"uname\"  \r\n$password = \"****\"  \r\n#IP of the 3PAR device  \r\n$IP = \"10.10.10.10\"\r\n#name of the RC group\r\n$RCGroup = \"TEST.r12345\"\r\n#Alert when older than X minutes\r\n$oldThanMinutes = 10\r\n#SMTP Server\r\n$smtp = \"mail.domain.com\"\r\n#Sender of Alerts\r\n$FromEm = \"noreply@domaincom\"\r\n#Recipient for alerts\r\n$ToEm = \"nsnidanko@domain.com\"\r\n#API URL  \r\n$APIurl = \"https:\/\/$($IP):8080\/api\/v1\"  \r\n############# END EDIT ##############\r\n\r\n#avoid issues with an invalid (self-signed) certificate, try avoid tabs\/spaces as this might mess up the string block  \r\n#http:\/\/stackoverflow.com\/questions\/11696944\/powershell-v3-invoke-webrequest-https-error  \r\nadd-type @\" \r\n    using System.Net; \r\n    using System.Security.Cryptography.X509Certificates; \r\n    public class TrustAllCertsPolicy : ICertificatePolicy { \r\n        public bool CheckValidationResult( \r\n            ServicePoint srvPoint, X509Certificate certificate, \r\n            WebRequest request, int certificateProblem) { \r\n            return true; \r\n        } \r\n    } \r\n\"@  \r\n[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy\r\n\r\n#connect to 3PAR WSAPI\r\n$postParams = @{user=$username;password=$password} | ConvertTo-Json  \r\n$headers = @{}  \r\n$headers[\"Accept\"] = \"application\/json\"  \r\n$credentialdata = Invoke-WebRequest -Uri \"$APIurl\/credentials\" -Body $postParams -ContentType \"application\/json\" -Headers $headers -Method POST -UseBasicParsing  \r\n$key = ($credentialdata.Content | ConvertFrom-Json).key\r\n\r\n#Poll 3PAR Remote Copy data\r\n$headers = @{} \r\n$headers[\"Accept\"] = \"application\/json\" \r\n$headers[\"Accept-Language\"] = \"en\"\r\n$headers[\"X-HP3PAR-WSAPI-SessionKey\"] = $key\r\n$WSAPIdata = Invoke-WebRequest -Uri \"$APIurl\/remotecopygroups\/$RCGroup\" -ContentType \"application\/json\" -Headers $headers -Method GET -UseBasicParsing  \r\n\r\n#get last sync time of the first volume in Remote Copy group as string in ISO 8601 and cast it\r\n[DateTime]$volLastSync = ( $WSAPIdata.content | Convertfrom-Json ).volumes[0].remoteVolumes.volumeLastSyncTime\r\n\r\n#close 3PAR WSAPI connection\r\nInvoke-WebRequest -Uri \"$APIurl\/credentials\/$key\" -ContentType \"application\/json\" -Method DELETE -UseBasicParsing \r\n\r\n# get current date in ISO 8601 Format\r\n$date = Get-Date -format \"s\"\r\n#compare how much time since last sync\r\n$Diff = new-timespan -Start $volLastSync -end $date\r\n\r\n#logic to compare timespan\r\nif ( $diff.TotalMinutes -ge $oldThanMinutes ) {\r\n#send email\r\nSend-MailMessage -From $FromEm -To $ToEm -SmtpServer $smtp -Subject \"3PAR Replication Alert for $RCGroup\" -Body \"Last sync happened at $volLastSync\"\r\n}\r\n<\/pre>\n","protected":false},"excerpt":{"rendered":"<p>Earlier I&#8217;ve demonstrated how to use 3PAR CLI with Powershell. In this example I will show how to work with 3PAR&#8217;s WSAPI via Powershell and poll last time remote copy group was synchronized (i use Last Sync date from first &hellip; <a href=\"https:\/\/blog.gptnet.net\/?p=304\">Continue reading <span class=\"meta-nav\">&rarr;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[72,44,1],"tags":[61,82,83,45,81],"class_list":["post-304","post","type-post","status-publish","format-standard","hentry","category-3par","category-powershell","category-random-stuff","tag-3par","tag-3par-api","tag-3par-powershell","tag-powershell-2","tag-wsapi"],"_links":{"self":[{"href":"https:\/\/blog.gptnet.net\/index.php?rest_route=\/wp\/v2\/posts\/304","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/blog.gptnet.net\/index.php?rest_route=\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/blog.gptnet.net\/index.php?rest_route=\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/blog.gptnet.net\/index.php?rest_route=\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/blog.gptnet.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcomments&post=304"}],"version-history":[{"count":2,"href":"https:\/\/blog.gptnet.net\/index.php?rest_route=\/wp\/v2\/posts\/304\/revisions"}],"predecessor-version":[{"id":306,"href":"https:\/\/blog.gptnet.net\/index.php?rest_route=\/wp\/v2\/posts\/304\/revisions\/306"}],"wp:attachment":[{"href":"https:\/\/blog.gptnet.net\/index.php?rest_route=%2Fwp%2Fv2%2Fmedia&parent=304"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/blog.gptnet.net\/index.php?rest_route=%2Fwp%2Fv2%2Fcategories&post=304"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/blog.gptnet.net\/index.php?rest_route=%2Fwp%2Fv2%2Ftags&post=304"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}