https://zvm-ip:zvm-port/v1 |
zvm-ip | The IP address of the Zerto Virtual Manager where the API is run. |
zvm-port | The port to access the Zerto Virtual Manager. The default port is 9669. |
https://zvm-ip:zvm-port/v1/session/add |
$baseURL = "https://" + $strZVMIP + ":"+$strZVMPort | |
5 | $xZertoSessionURL = $baseURL +"/v1/session/add" |
1 | $authInfo = ("{0}:{1}" -f $userName,$password) |
2 | $authInfo = [System.Text.Encoding]::UTF8.GetBytes($authInfo) |
3 | $authInfo = [System.Convert]::ToBase64String($authInfo) |
4 | $headers = @{Authorization=("Basic {0}" -f $authInfo)} |
6 | $contentType = "application/json" |
7 | $xZertoSessionResponse = Invoke-WebRequest -Uri $xZertoSessionURL -Headers $headers -Method POST -Body $body -ContentType $contentType |
8 | return $xZertoSessionResponse.headers.get_item("x-zerto-session") |
$authInfo = ("{0}:{1}" -f $userName,$password) |
$authInfo = [System.Text.Encoding]::UTF8.GetBytes($authInfo) |
$authInfo = [System.Convert]::ToBase64String($authInfo) |
$headers = @{Authorization=("Basic {0}" -f $authInfo)} |
$xZertoSessionURL = $baseURL +"/v1/session/add" |
$xZertoSessionResponse = Invoke-WebRequest -Uri $xZertoSessionURL -Headers $headers -Method POST -Body $body -ContentType $contentType |
$xZertoSessionResponse.headers.get_item("x-zerto-session") |
$zertSessionHeader = @{"x-zerto-session"=$xZertoSession} |
$vpgListApiUrl = "https://" + $strZVMIP + ":"+$strZVMPort+"/v1/vpgs" Invoke-RestMethod -Uri $vpgListApiUrl -Headers $zertSessionHeader |
$strZVMIP = "{ZVM IP}" $strZVMPort = "{ZVM HTTPS port}" $strZVMUser = "{ZVM user}" $strZVMPwd = "{ZVM user password}" ## Perform authentication so that Zerto APIs can run. Return a session identifier that needs to be inserted in the header for subsequent requests. ## For more details, see Zerto Virtual Replication RESTful API Reference Guide. function getxZertoSession ($userName, $password){ $baseURL = "https://" + $strZVMIP + ":"+$strZVMPort $xZertoSessionURI = $baseURL +"/v1/session/add" $authInfo = ("{0}:{1}" -f $userName,$password) $authInfo = [System.Text.Encoding]::UTF8.GetBytes($authInfo) $authInfo = [System.Convert]::ToBase64String($authInfo) $headers = @{Authorization=("Basic {0}" -f $authInfo)} $contentType = "application/json" $xZertoSessionResponse = Invoke-WebRequest -Uri $xZertoSessionURI -Headers $headers -Method POST -Body $body -ContentType $contentType #$xZertoSessionResponse = Invoke-WebRequest -Uri $xZertoSessionURI -Headers $headers -Body $body -Method POST return $xZertoSessionResponse.headers.get_item("x-zerto-session") } |
#Extract x-zerto-session from the response, and add it to the actual API: $xZertoSession = getxZertoSession $strZVMUser $strZVMPwd $zertoSessionHeader = @{"x-zerto-session"=$xZertoSession} #Invoke the Zerto API: $vpgListApiUrl = "https://" + $strZVMIP + ":"+$strZVMPort+"/v1/vpgs" $VPGNAME = "MyApp" #Iterate with XML: $vpgListXML = Invoke-RestMethod -Uri $vpgListApiUrl -Headers $zertoSessionHeader -ContentType "application/xml" foreach ($vpg in $vpgListXML.ArrayOfVpgApi.VpgApi){ if ($vpg.VpgName -eq $VPGNAME){ $tmpVpgIdentifier = $vpg.VpgIdentifier break } } #Iterate with JSON: $vpgListJSON = Invoke-RestMethod -Uri $vpgListApiUrl -Headers $zertoSessionHeader -ContentType "application/json" foreach ($vpg in $vpgListJSON){ if ($vpg.VpgName -eq $VPGNAME){ $tmpVpgIdentifier = $vpg.VpgIdentifier break } } write-host $tmpVpgIdentifier ##End of script |
#Parameters Section $strZVMIP = "{Zerto Virtual Manager IP}" $strZVMPort = "{Zerto Virtual Manager HTTPS port}" $strZVMUser = "{Zerto Virtual Manager user}" $strZVMPw = "{Zerto Virtual Manager user password}" $sourceSiteName = "{protected site name}" $targetSiteName = "{recovery site name}" $targetDataStoreName = "{recovery storage name in the recovery site for the VPG}" $vpgName = "{name of the VPG you want to create}" $unProtectedVMsCSVFile = "name of the file that has the names of the VMs to add to the VPG. The file must not have headers, and the VM names must be separated with commas, without spaces between the names. For example, the first row in the file would look like this: vm1,vm2,vm3}" $BASEURL = "https://" + $strZVMIP + ":"+$strZVMPort+"/v1/" #base URL for all APIs |
$zertoSessionHeader_xml = @{"Accept"="application/xml" "x-zerto-session"=$xZertoSession} ##Function Definitions #Get a site identifier by invoking Zerto APIs, given a Zerto API session and a site name: function getSiteIdentifierByName ($sessionHeader, $siteName){ $url = $BASEURL + "virtualizationsites" $response = Invoke-RestMethod -Uri $url -Headers $zertoSessionHeader_xml ForEach ($site in $response.ArrayOfVirtualizationSiteApi.VirtualizationSiteApi) { if ($site.VirtualizationSiteName -eq $siteName){ return $site.SiteIdentifier } } } |
#Get a storage identifier by invoking Zerto APIs, given a Zerto Virtual Replication API session and a storage name: function getDatastoreIdentifierByName ($sessionHeader, $siteIdentfier, $datastoreName){ $url = $BASEURL + "virtualizationsites/"+$siteIdentfier + "/datastores" $response = Invoke-RestMethod -Uri $url -Headers $zertoSessionHeader_xml ForEach ($datastore in $response.ArrayOfDatastoreNativeApi.DatastoreNativeApi) { if ($datastore.DatastoreName -eq $datastoreName){ return $datastore.DatastoreIdentifier } } } |
#Get unprotected VM identifiers by invoking Zerto APIs, given a Zerto API session, a site identifier, and a list of VMs to add to the VPG: function getUnprotectedVMsIdentifiers($sessionHeader, $siteIdentfier, $VMNames){ $url = $BASEURL + "virtualizationsites/"+$siteIdentfier + "/vms" $unprotectedVMsIdentifiers = @() $response = Invoke-RestMethod -Uri $url -Headers $zertoSessionHeader_xml ForEach ($vm in $response.ArrayOfVmNativeApi.VmNativeApi) { if ($VMNames.IndexOf($vm.VmName) -gt -1){ $unprotectedVMsIdentifiers+=($vm.VmIdentifier) } } return $unprotectedVMsIdentifiers } |
#Authenticate with Zerto APIs: create a Zerto API session and return it, to be used in other APIs function getZertoXSession (){ #Authenticate with Zerto APIs: $xZertoSessionURL = "https://" + $strZVMIP + ":"+$strZVMPort+"/v1/session/add" $authInfo = ("{0}:{1}" -f $strZVMUser,$strZVMPw) $authInfo = [System.Text.Encoding]::UTF8.GetBytes($authInfo) $authInfo = [System.Convert]::ToBase64String($authInfo) $headers = @{Authorization=("Basic {0}" -f $authInfo)} $xZertoSessionResponse = Invoke-WebRequest -Uri $xZertoSessionURL -Headers $headers -Method POST #Extract x-zerto-session from the response and add it to the actual API: $xZertoSession = $xZertoSessionResponse.headers.get_item("x-zerto-session") return $xZertoSession } |
#Build VM elements to be added to the VPGs API, based on a list of VM identifiers function buildVMsElement ($VMs) { $response = "<VmsIdentifiers>" ForEach ($vm in $VMs) { $response+="<string xmlns="+'"http://schemas.microsoft.com/2003/10/Serialization/Arrays"'+">"+$vm+"</string>" } $response += "</VmsIdentifiers>" return $response } |
#Script starts here: $xZertoSession = getZertoXSession $zertoSessionHeader = @{"x-zerto-session"=$xZertoSession} $sourceSiteIdentifier = getSiteIdentifierByName $zertoSessionHeader $sourceSiteName $targetSiteIdentifier = getSiteIdentifierByName $zertoSessionHeader $targetSiteName $dataStoreIdentifier = getDatastoreIdentifierByName $zertoSessionHeader $targetSiteIdentifier $targetDataStoreName $unprotectedVMNames = Get-Content $unProtectedVMsCSVFile | %{$_.Split(",")} $vmsIdentifiers = getUnprotectedVMsIdentifiers $zertoSessionHeader $sourceSiteIdentifier $unprotectedVMNames $vmsIdentifiersElement = buildVMsElement $vmsIdentifiers #Create the URL and body of the VPGs request: $createVPGUrl = $BASEURL+"vpgs" $vpgsRequestBody = "<VpgCreateDataApi xmlns="+'"http://schemas.zerto.com/zvm/api"'+">" +"<DatastoreIdentifier>"+$dataStoreIdentifier +"</DatastoreIdentifier> <SourceSiteIdentifier>"+$sourceSiteIdentifier+"</SourceSiteIdentifier> <TargetSiteIdentifier>"+$targetSiteIdentifier+"</TargetSiteIdentifier>" +$vmsIdentifiersElement+"<VpgName>"+$vpgName+"</VpgName> </VpgCreateDataApi>" #Invoke the Zerto API: Invoke-RestMethod -Uri $createVPGUrl -Headers $zertoSessionHeader -Body $vpgsRequestBody -ContentType "application/xml" -method POST ##End of script |