Public/Move-RubrikMountVMDK.ps1
#Requires -Version 2 function Move-RubrikMountVMDK { <# .SYNOPSIS Moves the VMDKs from a Live Mount to another VM .DESCRIPTION The Move-RubrikMountVMDK cmdlet is used to attach VMDKs from a Live Mount to another VM, typically for restore or testing purposes. .NOTES Written by Chris Wahl for community usage Twitter: @ChrisWahl GitHub: chriswahl .LINK https://github.com/rubrikinc/PowerShell-Module .EXAMPLE Move-RubrikMountVMDK -SourceVM 'SourceVM' -TargetVM 'TargetVM' -vCenter '192.168.1.1' This will create a Live Mount using the latest snapshot of the VM named SourceVM, power it off, and attach the VMDKs to the production version of the VM named SourceVM. .EXAMPLE Move-RubrikMountVMDK -SourceVM 'SourceVM' -TargetVM 'TargetVM' -vCenter '192.168.1.1' This will create a Live Mount using the latest snapshot of the VM named SourceVM, power it off, and attach the VMDKs to the production version of a different VM named TargetVM. .EXAMPLE Move-RubrikMountVMDK -SourceVM 'SourceVM' -TargetVM 'TargetVM' -Date '01/30/2016 08:00' -vCenter '192.168.1.1' This will create a Live Mount using the snapshot at or before 08:00am on Jan 30th 2016 of the VM named SourceVM, power it off, and attach the VMDKs to the production version of a different VM named TargetVM. Note that the data parameter will start at the time specified (in this case, 08:00am) and work backwards in time until it finds a snapshot. Precise timing is not required. .EXAMPLE Move-RubrikMountVMDK -SourceVM 'SourceVM' -TargetVM 'TargetVM' -vCenter '192.168.1.1' -ExcludeDisk @(0,1) This will create a Live Mount using the latest snapshot of the VM named SourceVM, power it off, and attach all but the first two VMDKs to the production version of the VM named SourceVM. Note that for the "ExcludeDisk" array, 0 is the first disk and 1 is the second disk. To exclude the first and third disks, the value would be @(0,2). To exclude just the first disk, use @(0). #> [CmdletBinding()] Param( [Parameter(Mandatory = $true,Position = 0,HelpMessage = 'Source Virtual Machine',ValueFromPipeline = $true)] [Alias('Name')] [ValidateNotNullorEmpty()] [String]$SourceVM, [Parameter(Mandatory = $false,Position = 1,HelpMessage = 'Target Virtual Machine',ValueFromPipeline = $true)] [ValidateNotNullorEmpty()] [String]$TargetVM, [Parameter(Mandatory = $true,Position = 2,HelpMessage = 'vCenter FQDN or IP address')] [ValidateNotNullorEmpty()] [String]$vCenter, [Parameter(Mandatory = $false,Position = 3,HelpMessage = 'Backup date in your local clock format format',ValueFromPipeline = $true)] [ValidateNotNullorEmpty()] [String]$Date, [Parameter(Mandatory = $false,Position = 4,HelpMessage = 'An array of disks to exclude',ValueFromPipeline = $true)] [ValidateNotNullorEmpty()] [Array]$ExcludeDisk, [Parameter(Mandatory = $false,Position = 5,HelpMessage = 'Rubrik FQDN or IP address')] [ValidateNotNullorEmpty()] [String]$Server = $global:RubrikConnection.server ) Process { TestRubrikConnection ConnectTovCenter -vCenter $vCenter if (!$Date) { Write-Verbose -Message 'No date entered. Taking current time.' $Date = Get-Date } Write-Verbose -Message 'Creating an Instant Mount (clone) of the Source VM' New-RubrikMount -VM $SourceVM -Date $Date Start-Sleep -Seconds 2 [array]$mounts = Get-RubrikMount -VM $SourceVM $i = 0 Write-Verbose -Message 'Checking for quantity of mounts in the system' if ($mounts -ne $null) { Write-Verbose -Message 'Finding the correct mount' foreach ($_ in $mounts.MountName) { if ($_ -eq $null) { break } $i++ } While ($mounts[$i].MountName -eq $null) { [array]$mounts = Get-RubrikMount -VM $SourceVM Start-Sleep -Seconds 2 } } else { Write-Verbose -Message 'No other mounts found, waiting for new mount to load' While ($mounts.MountName -eq $null) { [array]$mounts = Get-RubrikMount -VM $SourceVM Start-Sleep -Seconds 2 } } Write-Verbose -Message 'Mount is online. vSphere data loaded into the system.' Write-Verbose -Message 'Gathering details on the Instant Mount' $MountVM = $null While ($MountVM.PowerState -ne 'PoweredOn') { $MountVM = Get-VM -Name $mounts[$i].MountName Start-Sleep -Seconds 2 } Write-Verbose -Message 'Powering off the Instant Mount' $moref = $MountVM.Id.Substring($MountVM.Id.IndexOf('-')+1) $vmid = $mounts[$i].vCenterId + '-' + $moref Stop-RubrikVM -ID $vmid Write-Verbose -Message 'Gathering details on the Target VM' if (!$TargetVM) { $TargetVM = $SourceVM } $TargetHost = Get-VMHost -VM $TargetVM Write-Verbose -Message 'Mounting Rubrik datastore to the Target Host' $MountDatastore = Get-VM $MountVM | Get-Datastore if (!(Get-VMHost $TargetHost | Get-Datastore -Name $MountDatastore)) { $null = New-Datastore -Name $MountDatastore.Name -VMHost $TargetHost -NfsHost $MountDatastore.RemoteHost -Path $MountDatastore.RemotePath -Nfs } Write-Verbose -Message 'Migrating the Mount VMDKs to VM' [array]$MountVMdisk = Get-HardDisk $MountVM $MountedVMdiskFileNames = @() [int]$j = 0 foreach ($_ in $MountVMdisk) { if ($ExcludeDisk -contains $j) { Write-Verbose -Message "Skipping Disk $j" -Verbose } else { try { $null = Remove-HardDisk -HardDisk $_ -DeletePermanently:$false -Confirm:$false $null = New-HardDisk -VM $TargetVM -DiskPath $_.Filename $MountedVMdiskFileNames += $_.Filename Write-Verbose -Message "Migrated $($_.Filename) to $TargetVM" } catch { throw 'Unable to attach VMDKs to the TargetVM' } } $j++ } Write-Verbose -Message 'Offering cleanup options' $title = 'Setup is complete!' $message = "A Mount of $SourceVM has been created, and all VMDKs associated with the mount have been attached.`rYou may now start testing.`r`rWhen finished:`rSelect YES to automatically cleanup the attached VMDKs and mount`rSelect NO to leave the mount and VMDKs intact." $yes = New-Object -TypeName System.Management.Automation.Host.ChoiceDescription -ArgumentList '&Yes', ` 'Automated Removal: This script will detatch the VMDK(s) and discard the Mount VM' $no = New-Object -TypeName System.Management.Automation.Host.ChoiceDescription -ArgumentList '&No', ` 'Manual Removal: VMDK(s) will remain attached and Mount VM will remain in vCenter' $options = [System.Management.Automation.Host.ChoiceDescription[]]($yes, $no) $result = $host.ui.PromptForChoice($title, $message, $options, 0) switch ($result) { 0 { Write-Verbose -Message 'Removing VMDKs from the VM' [array]$SourceVMdisk = Get-HardDisk $TargetVM foreach ($_ in $SourceVMdisk) { if ($MountedVMdiskFileNames -contains $_.Filename) { Write-Verbose -Message "Removing $_ from $TargetVM" Remove-HardDisk -HardDisk $_ -DeletePermanently:$false -Confirm:$false } } Write-Verbose -Message "Deleting the Instant Mount for $($mounts[$i].RubrikID)" Remove-RubrikMount -RubrikID $($mounts[$i].RubrikID) } 1 { Write-Verbose -Message 'You selected No. Exiting script' } } } # End of process } # End of function |