Scripted modification of vRA reservations with powerVRA.

Recently, a customer of mine needed to modify a large number of vRA reservations to facilitate a migration, and because there's nothing wrong with being lazy, using powershell is always one of my go-to options. Using PowerVRA and some magic, instead of clicking through 200 reservations, we can reduce this process from a full day of work and running the risk of mistakes to a 10 minutes automated process.

Because Kyle Ruddy's Beard told me so, and so i don't forget, here's the script in case someone can use it. With a bit of playing around, you could modify this to your own tastes, to use network reservations, add storage paths, etc. Note that there's no serious error handling, the names have all been anonymized, and the script makes some assumptions about the names of the reservations, but with a bit of powershell knowledge you should be able to adjust it to your own environment.

In this case we've used a hashtable containing arrays of network names for each individual site, but obviously you can use whatever you want to store this info; CSV, JSON, plain text, XML (if you're a heathen). The rest of the script is fairly straightforward. It loops over the hashtable, finds all reservations that contain the element key, loops over the reservations and then loops over the array contained in the hashtable to add each of them individually (if not already present).

##Configure networks as an array for each individual site. To add new sites, add another element to the hashtable containing an array. To add networks to a site, expand the array. 
##Assumption is that the reservations for a site have a name that contains siteNetworks.keys
$siteNetworks = @{}
$siteNetworks.SITE1 = @("PGNAME1","PGNAME2","PGNAME3","PGNAME4")
$siteNetworks.SITE2 = @("PGNAME5","PGNAME6","PGNAME7","PGNAME8")
$siteNetworks.SITE3 = @("PGNAME9","PGNAME10")

##Modify to suit your own environment. 
$vraTenantName = "tenant"
$vraServerName = "vrava.domain.tld"

##Do not modify below here. 

## Required for connectivity as powershell security is from the past. 
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

connect-vraserver -server  $vraServerName -tenant $vraTenantName
## Loop over site elements
$siteNetworks.keys |% {
              $site = $_
              $networkArr = $siteNetworks.Item($site)
              write-host "processing $site"
              ## Get all reservations matching *$site*
              $reservations = get-vrareservation |? {$ -like "*$site*" } |% {
                             $reservation = $_
                             ## Magic sauce to get all networks already configured in this reservation
                             $reservationNetworks = (($reservation.ExtensionData.entries |? {$_.key -eq "reservationNetworks"}).value.items.values.entries |? {$_.key -eq "networkPath"}).value.label
                             write-host "modifying $($reservation.Name)"
                             ## Loop over all networks in site hashtable elements
                             $networkArr |% {
                                           $networkPath = $_
                                            #check if reservation already has the specified network
                                           if ($reservationNetworks -notcontains $networkPath) {
                                                          write-host "adding $networkPath"
                                                          $reservation | add-vrareservationnetwork -NetworkPath $networkPath
                                           else {
                                                          write-host "$networkPath already exists in $($reservation.Name), skipping"