Public/New-AGMLibGCVEfailover.ps1
# Copyright 2022 Google Inc. All Rights Reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. Function New-AGMLibGCVEfailover ([string]$filename,[int]$phase,[string]$vcenterid) { <# .SYNOPSIS Uses a pre-prepared CSV list of VMware VM Names to run mount jobs in phases .EXAMPLE New-AGMLibGCVEfailover -filename recoverylist.csv -vcenterid XXXXXX This will load the contents of the file recoverylist.csv and use it to run multiple New-AGMLibVM jobs .DESCRIPTION This routine needs a well formatted CSV file. Here is an example of such a file: phase,sourcevmname,targetvmname,label,targetnetworkname,poweronvm,targetmacaddress,onvault,perfoption 1,WinSrv2019-2,WinSrv2019-2-rec,phase1,avtest,true,,true,StorageOptimized 1,WinSrv2019-3,WinSrv2019-3-rec,phase1,avtest,false,01:50:56:81:11:6b,true,StorageOptimized 2,Centos1,centos1-rec,phase2,avtest,true,,true,StorageOptimized 2,Centos2,centos2-red,phase2,avtest,false,,true,StorageOptimized #> if ( (!($AGMSESSIONID)) -or (!($AGMIP)) ) { Get-AGMErrorMessage -messagetoprint "Not logged in or session expired. Please login using Connect-AGM" return } $sessiontest = Get-AGMVersion if ($sessiontest.errormessage) { Get-AGMErrorMessage -messagetoprint "AGM session has expired. Please login again using Connect-AGM" return } if (!($filename)) { Get-AGMErrorMessage -messagetoprint "Please supply a csv file correctly formatted as per the help for this function using: -filename xxxx.csv" return; } if ( Test-Path $filename ) { $recoverylist = Import-Csv -Path $filename if (!($recoverylist.phase)) { Get-AGMErrorMessage -messagetoprint "Could not find the phase column in the CSV file, which is mandatory"; return } if (!($recoverylist.sourcevmname)) { Get-AGMErrorMessage -messagetoprint "Could not find the sourcevmname column in the CSV file, which is mandatory"; return } } else { Get-AGMErrorMessage -messagetoprint "VM list: $filename could not be opened." return; } # The user can give us a vcenter ID, but given this is GCVE, we expect we will have only one vCenter. If we find more than one then we need to know which one if (!($vcenterid)) { $vcentergrab = Get-AGMHost -filtervalue isvcenterhost=true if ($vcentergrab.id.count -lt 1) { Get-AGMErrorMessage -messagetoprint "Could not find any vCenters" return; } if ($vcentergrab.id.count -eq 1) { $vcenterid = $vcentergrab.id $srcid = $vcentergrab.srcid $vcentername = $vcentergrab.name } if ($vcentergrab.id.count -gt 1) { Write-host "" write-host "vCenter selection menu - which vCenter will be used for this mount" Write-host "" $i = 1 foreach ($vc in $vcentergrab) { Write-Host -Object "$i`: $($vc.name) ($($vc.id))" $i++ } While ($true) { Write-host "" $listmax = $vcentergrab.name.count [int]$vcselection = Read-Host "Please select the vCenter to work with from (1-$listmax)" if ($vcselection -lt 1 -or $vcselection -gt $listmax) { Write-Host -Object "Invalid selection. Please enter a number in range [1-$($listmax)]" } else { break } } $vcenterid = $vcentergrab.id[($vcselection - 1)] $srcid = $vcentergrab.srcid[($vcselection - 1)] $vcentername = $vcentergrab.name[($vcselection - 1)] } write-host "" write-host "Using the following vCenter:" write-host "Name: $vcentername vCenterID: $vcenterid" } # we now create a round robin list of ESX hosts. We are going to treat them equally # firstly we need a srcid from our vcenter if (!($srcid)) { $vcentergrab = Get-AGMHost $vcenterid if ($vcentergrab.srcid) { $srcid = $vcentergrab.srcid $vcentername = $vcentergrab.name write-host "" write-host "Using vCenter named $vcentername with vCenterID $vcenterid" } else { Get-AGMErrorMessage -messagetoprint "Could not find vCenters with ID $vcenterid" return; } } $esxgrab = Get-AGMHost -filtervalue "vcenterhostid=$srcid&isesxhost=true&originalhostid=0" if ($esxgrab.count -lt 1) { Get-AGMErrorMessage -messagetoprint "Could not find ESX hosts for vCenter with ID $vcenterid" return; } # we count the number of ESX hosts $esxhostcount = $esxgrab.id.count # we start with ESX host index 0 $esxroundrobin = 0 write-host "" write-host "Using the following ESXi hosts" $esxtable = $esxgrab | Select-Object id,name | Format-Table $esxtable # Our assumption is that GCVE has one datastore and that all ESX hosts have access to that datastore $datastoregrab = (((Get-AGMHost $esxgrab.id[0]).sources.datastorelist) | select-object name| sort-object name | Get-Unique -asstring).name if ($datastoregrab.count -lt 1) { Get-AGMErrorMessage -messagetoprint "Could not find any datastores" return; } if ($datastoregrab.count -gt 1) { Get-AGMErrorMessage -messagetoprint "Found too many datastores" return; } $datastore = $datastoregrab write-host "" write-host "Using the following Datastore:" write-host "$datastore" write-host "" write-host "Starting Mounts now for phase $phase" # we are now ready to go through our list foreach ($app in $recoverylist) { if ($app.phase -eq $phase) { # so this is the our esxhostid. Starting with index 0 $esxhostid = $esxgrab.id[$esxroundrobin] if ($app.targetvmname.length -gt 0) { $mountvmname = $app.targetvmname } else { $mountvmname = $app.sourcevmname } $mountcommand = 'New-AGMLibVM -appname ' +$app.sourcevmname +' -vmname ' +$mountvmname +' -datastore ' +$datastore +' -vcenterid ' +$vcenterid +' -esxhostid ' +$esxhostid +' -mountmode nfs' if ($app.label) { $mountcommand = $mountcommand + ' -label "' +$app.Label +'"' } if ($app.onvault) { $mountcommand = $mountcommand + ' -onvault "' +$app.onvault +'"' } if ($app.perfoption) { $mountcommand = $mountcommand + ' -perfoption "' +$app.perfoption +'"' } # if user asked for a MAC address, then we better keep power off the VM if ($app.targetmacaddress.length -gt 0) { $mountcommand = $mountcommand + ' -poweronvm "false"' } elseif ($app.poweronvm.length -gt 0) { $mountcommand = $mountcommand + ' -poweronvm "' +$app.poweronvm +'"' } write-host "Running $mountcommand" Invoke-Expression $mountcommand # we add one to our ESX round robin. If we hit the hostcount we have gone too far, so 3 hosts means index 0,1,2 so when we get to 3 then we go back to 0 $esxroundrobin += 1 if ($esxroundrobin -eq $esxhostcount ) { $esxroundrobin = 0 } } } } |