• This topic has 9 replies, 1 voice, and was last updated December 17, 2022 by jason.corbett@westernsouthern.com.

Change VPG/VM/Volume datastore via API

  • <p style=”padding-left: 30px;”>Due to a storage change at our Recovery site, we are migrating all recovery and journal volumes to new datastores (VMware). I have a working script that will change the VPG recovery and journal datastore and the recovery and journal datastore for each VM in the VPG. I’m now stuck trying to update the Volume datastore for each volume on each VM.  I found how to GET the data I need, but when I try to PUT the changes (as I do for VPG and VM settings), it returns an error 405 Method Not Allowed.  Here is the code snippet I’m stuck on…

    $VolumeList = Invoke-RestMethod -Uri $VMSettingsURL"/volumes" -Method GET -TimeoutSec 100 -Headers $ZertosessionHeader -ContentType $TypeJSON

    foreach ($volume in $VolumeList){
    $ChangeVolumeLocationBody = '{"Datastore":{"DatastoreIdentifier":"'+ $newVMDS.DatastoreIdentifier + '"}}'
    $ChangeVolumeLocationRequest = Invoke-RestMethod -Uri $VMSettingsURL -Method PUT -TimeoutSec 100 -Headers $ZertosessionHeader -ContentType $TypeJSON -Body $ChangeVolumeLocationBody
    } #Close Volume Loop</p>
    I know this must be possible because we can do it through the GUI.  I’m fairly new to using APIs with PowerShell, so I hope this is something easy I’m overlooking.  Thanks!

    Hi Jason – Currently the volumes API only supports GET methods. Having said that, a PUT to the VPGSettings API can be used to update a recovery volume or journal locations. We also have a specific section of the API docs that covers how to work with the VPGSettings API here. The section for updating a vpg should be the most helpful. — Justin

    Thanks for the reply Justin. That is very discouraging to hear and seems contrary to what the documentation says.  Looking at the “Zerto Virtual Replication RESTful APIs” document for version 6.5 (which is what we run), see pages 205 and 228 which directly mentions editing volume settings with the PUT method (also available here).

    Let me know if you have any other suggestions, or if I must update these manually using the GUI.  Thanks!

    Hi Jason,

    Just looking at the code snippit you have provided, it seems that you are attempting to only PUT the volume information for one volume at a time. I believe you need to be updating your URI to something along the lines of:

    $ChangeVolumeLocationRequest = Invoke-RestMethod -Uri $VMSettingsURL/volumes/{volumeId} -Method PUT -TimeoutSec 100 -Headers $ZertosessionHeader -ContentType $TypeJSON -Body $ChangeVolumeLocationBody

    I have not tested this in my lab, but according to the documentation it should work this way.


    Thinking about this a bit more, I think I would approach the loop as I have outlined here in this Gist. I’ve included the linked code below, but believe the gist will have better readability.

    foreach ($volume in $VolumeList){
    $volumeUri = "$VMSettingsUrl/volumes/$($volume.volumeIdentifier)"
    $currentVolume = Invoke-RestMethod -Uri $volumeUri -Method GET -TimeoutSec 100 -Headers $ZertosessionHeader -ContentType $TypeJSON
    $currentVolume.Datastore.DatastoreIdentifier = $newVMDS.DatastoreIdentifier
    $body = $currentVolume | Convertto-Json -depth 10
    $ChangeVolumeLocationRequest = Invoke-RestMethod -Uri $volumeUri -Method PUT -TimeoutSec 100 -Headers $ZertosessionHeader -ContentType $TypeJSON -Body $body
    } #Close Volume Loop

    You, sir, are awesome!  I would have sworn I had tried that already but I obviously had something wrong.  I went back this morning with your suggestion and it worked perfectly.  Thank you!!!

    I think where I got tripped up was using different URIs to PUT each volume change and VM change.  Using a different URI for each PUT statement, then a final POST Commit worked exactly as I hoped it would.

    Hi Jason – Apologies for the confusion here – the Volumes API ( https://zvm_ip:port/v1/volumes) only supports GET methods. The VPGSettings API (starting here  https://zvm_ip:port/v1/vpgSettings) absolutely supports GET, POST, PUT, and DELETE methods. Sorry for the lack of clarity on my end!

    Having said that, our team had considered before making changing recovery datastores or journals via the API or cmdlets easier (so for example, a future  “Change-RecoveryDiskDatastoreLocation” cmdlet or ../v1/volumes API expanded to support PUTs) instead of relying on the VPGSettings API. Right now this is not in plan, however if this is of interest please do be sure to note your feedback in our Feature Request section here on MyZerto (MyZerto –> Support & Downloads –> Feature Request) — Justin

    Thanks, Justin. I guess I misunderstood which API you were referring to. Knowing that these changes are possible with current APIs is sufficient for us for now. Now that I see how it works and how to correctly use the VPGSettings object, it’s really not that bad.  Thanks again!

    Great stuff, thanks Jason! I should practice what I preach as I have been big on trying to get assets (like our release notes) to be much clearer too. For example, instead of saying somethign like “this new thing is available in the API” we will be outlining the specific URL to the new API or where the addition is made (so folks know exactly where to look). Definitely do feel free to check out our feature request area though for this or any other ideas or problems you’d like to see us solve in the software! — Justin

You must be logged in to create new topics. Click here to login