Public/New-AGMLibMultiMount.ps1
Function New-AGMLibMultiMount ([array]$imagelist,[array]$hostlist,[string]$hostid,[string]$mountpoint,[switch][alias("a")]$appnamesuffix, [switch][alias("h")]$hostnamesuffix,[switch][alias("c")]$condatesuffix,[switch][alias("i")]$imagesuffix,[string]$label,[int]$startindex) { <# .SYNOPSIS Mounts a number of FileSystems to a group of hosts .EXAMPLE New-AGMLibMultiMount -imagelist $imagelist -hostlist $hostlist -mountpoint /tmp/imagecheck This command likes to use the output of Get-AGMLibImageRange as $imagelist So we could create a list like this: $imagelist = Get-AGMLibImageRange -fuzzyappname demo-sql -olderlimit 3 We could get a list of hosts to mount to with a command like this: $hostlist = Get-AGMHost -filtervalue "hostname~scanhost*" | select id,hostname The logic to handle mount points is simple. The user must supply a starter mount point with a trailing slash. For linux hosts this would be: -mountpoint /tmp/testmount/ For Windows hosts this would be: -mountpoint C:\temp\ The suffix is optional but recommended. This basically adds an extra foldername to the mount point. There are four mechanisms to get unique mount names: 1) You can specify -h and the Host Name will be used as part of the mount point 2) You can specify -a and the App Name will be used as part of the mount point 3) You can specify -i and the Image Name will be used as part of the mount point 4) You can specify -c and the Consistency Date will be used as part of the mountpoint The point point will always end in a unique number to guarantee uniqueness. If you want to control the starting number of that number use -startindex By default it will use a label of "MultiFS Recovery" to make the mounts easier to find. you can changes this with -label xxxx to set your own unique label. .EXAMPLE New-AGMLibMultiMount -imagelist $imagelist -hostid $hostid -mountpoint "/tmp/testmount/" If you only have a single host you can specify it singly using -hostid All your mounts will go to that single Host #> if ( (!($AGMSESSIONID)) -or (!($AGMIP)) ) { Get-AGMErrorMessage -messagetoprint "Not logged in or session expired. Please login using Connect-AGM" return } else { $sessiontest = (Get-AGMSession).session_id if ($sessiontest -ne $AGMSESSIONID) { Get-AGMErrorMessage -messagetoprint "Not logged in or session expired. Please login using Connect-AGM" return } } # handle hostlist vs hostid if ($hostlist.id) { $hostlist = ($hostlist).id } if ( (!($hostlist)) -and ($hostid) ) { $hostlist = $hostid } # guided menu if ((!($mountpoint)) -and (!($imagelist))) { Write-host "This function is used to start a large number of file system mounts in a single command. This is done by supplying:" Write-host "-- A list of images to mount, normally created with New-AGMLibImageRange and then put into a variable" Write-Host "-- A host list or a host ID which will be our target hosts. We learn these with Get-AGMHost" Write-host "-- A mount point with parameters" Write-host "" Write-host "We require an imagelist. This needs to be created with Get-AGMLibImageRange. If you have not created it, then quit out, run that command first and then come back here when done" [array]$imagelist = Read-Host "Supply the image list array name (or quit out now)" if (!($imagelist.imagename)) { Get-AGMErrorMessage -messagetoprint "Imagelist needs to be created with Get-AGMLibImageRange" return } # host ID list Write-host "" Write-Host "You now need to supply a list of host IDs to mount to. These hosts need to have the same OS (only Windows or only Linux)" Write-Host "Make sure the hosts are on the same appliance name as the images" Write-Host 'To get this list, run this command: Get-AGMHost -sort hostname:asc | select id,hostname,ostype,{$_.appliance.name}' Write-host "" Write-Host "1`: I have the host IDs, let me enter them" Write-Host "2`: I need to learn them. " $userchoice = Read-Host "Please select from this list (1-2)" if ($userchoice -eq 1) { While ($true) { if ($hostgrab.length -eq 0) { [string]$hostgrab = Read-Host "Please supply host IDs, comma separated, like: 1234,5467,9012" } else { break } } $hostlist = @($hostgrab) } else { return } write-host "" While ($true) { if ($fieldsep.length -eq 0) { [string]$mountpoint = Read-Host "Please supply a mount point such as /tmp/testmount/ or C:\Temp\ making sure to add the trailing slash as shown" if ($mountpoint -match '\\$') { $fieldsep = "\" } if ($mountpoint -match '/$') { $fieldsep = "/" } } else { break } } } if (!($mountpoint)) { Get-AGMErrorMessage -messagetoprint "Please supply a starter mountpoint such as /tmp/testmount/ or C:\Temp\" return } if ($mountpoint -match '\\$') { $fieldsep = "\" } if ($mountpoint -match '/$') { $fieldsep = "/" } if (!($fieldsep)) { Get-AGMErrorMessage -messagetoprint "Last character of $mountpoint needs to be forward slash for Linux such as /tmp/testmount/ or backslash for Windows such C:\Temp\" return } if (!($imagelist)) { Get-AGMErrorMessage -messagetoprint "Please supply an imagelist" return } if (!($hostlist)) { Get-AGMErrorMessage -messagetoprint "Please supply an array of Host IDs using -hostlist or a single Host ID using -hostid" return } if (!($startindex)) { $startindex = 1 } if (!($label)) { $label = "MultiFS Recovery" } $hostcount = $hostlist.count $hostroundrobin = 0 $lastappid = "" $lastcondate = "" # The user can specify the starting number or we will start at 1 if (!($startindex)) { $startindex = 1 } foreach ($image in $imagelist) { # start the moint point $imagemountpoint = $mountpoint if (($lastappid -eq $image.appid) -and ($lastcondate -eq $image.consistencydate)) { Write-Host "Not mounting AppName:" $image.appname "AppID:" $image.appid " Jobclass:" $image.jobclass " ImageName:" $image.backupname " ConsistencyDate:" $image.consistencydate "because the previous mount had the same appid and consistency date" } else { if ($hostnamesuffix) { # for linux mount points starting with / we need to trim the leading / to avoid // in the mount point if ($image.hostname.Substring(0,1) -match "[/]") { $image.hostname = $image.hostname.substring(1) } # we also remove spaces in app names and full colon, so they dont make strange mount points $imagemountpoint = $imagemountpoint + $image.hostname -replace '\s','' -replace ':','' $imagemountpoint = $imagemountpoint + $fieldsep } if ($appnamesuffix) { # for linux mount points starting with / we need to trim the leading / to avoid // in the mount point if ($image.appname.Substring(0,1) -match "[/]") { $image.appname = $image.appname.substring(1) } # we also remove spaces in app names and full colon, so they dont make strange mount points $imagemountpoint = $imagemountpoint + $image.appname -replace '\s','' -replace ':','' $imagemountpoint = $imagemountpoint + $fieldsep } if ($imagesuffix) { $imagemountpoint = $imagemountpoint + $image.backupname + $fieldsep } if ($condatesuffix) { # we need to make the date just numbers $imagemountpoint = $imagemountpoint + $image.consistencydate -replace '\s','' -replace '-','' -replace ':','' $imagemountpoint = $imagemountpoint + $fieldsep } # we always end on a number to guarantee uniqueness $imagemountpoint = $imagemountpoint + $startindex $startindex += 1 # we can now set the values needed for the mount $hostid = $hostlist[$hostroundrobin] $body = [ordered]@{ label = "$label"; image = $image.backupname; host = @{id=$hostid} migratevm = "false"; restoreoptions = @( @{ name = 'mountpointperimage' value = "$imagemountpoint" } ) } $json = $body | ConvertTo-Json -depth 4 Write-Host " Mounting AppName:" $image.appname " AppID:" $image.appid " Jobclass:" $image.jobclass " ImageName:" $image.backupname " ConsistencyDate:" $image.consistencydate "to Host ID" $hostid "with mount point" $imagemountpoint $imageid = $image.id Post-AGMAPIData -endpoint /backup/$imageid/mount -body $json $hostroundrobin += 1 if ($hostroundrobin -eq $hostcount ) { $hostroundrobin = 0 } $lastappid = $image.appid $lastcondate = $image.consistencydate } } } |