Script - Restore VM Using NetApp Snapshot (SnapRestore)

by on ‎2013-03-13 02:33 PM - edited on ‎2014-09-25 03:50 PM by allison Former NetApp Employee

This script will use the NetApp SnapRestore feature to restore a VM to a snapshot.  This script requires the VM to be on an NFS datastore.  The snapshot directory must be visible.  We use SolarWinds Orion to monitor our servers.  This script will also unmanage the server in Orion and remanage it once the restore is complete.  I hope you find it useful.

 

UPDATE:  I combined some of the forms and functions to make the flow of the script run better.

 

Here are some notes to consider:

 

1 - The Unmanage and Remanage functions are for integration with SolarWinds Orion Network Performance Monitor (so that we don't get alerts while the VM is down).  Update as needed for your environment.

2 - The Get_RestoreVM Function allows you to chose from multiple vCenter instances (e.g. Production, Test, etc.).  There is a also a step in the function to get a list of Filers to select from a text file.  Edit as needed for your environment

2 - If your VM uses more than 1 datastore, the script will fail out

4 - The script will allow you restore either a single -flat.vmdk or an entire VM

5 - If you restore the entire VM, it will be removed and re-added to vCenter to pick up any changes (such as VMware snapshot differences, VMX file changes, etc)

6 - The script will give you the option to overwrite the current VM or to move the required files if you need to keep the current files for root cause analysis

7 - The scirpt assumes the NetApp Volume and Qtree names are the same.  Edit as needed for your environment (search for Restore-NaSnapshotFile cmdlet)

8 - Since SnapRestore returns instantly, the script does some file size comparison to know when it is safe to move on

9 - If the VM was powered on before the restore, it will give you the option to power it back on after the restore

 

 

###############################################################################

## Volume Creation Script - Created by Stephen Kiser - 3/1/13                ##

## Use NetApp SnapRestore to restore a VM on an NFS datastore to a snapshot  ##

###############################################################################

## Necessary System Calls and Variables

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")

[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")

Function Load_Module($name) {

    If (!(Get-Module -Name $name)) {

            If (Get-Module -ListAvailable | Where { $_.name -eq $name })

            {Import-Module $name;Return $true}

        Else

            {Return $false;$global:x="2"}

    }

    Else

    {Return $true}

}

$moduleName = "DataONTAP"

$VMwareLoaded=$False

$SwisLoaded=$False

$snapIn1 = "VMware*"

$snapIn2 = "SwisSnapin"

Try {

      If (Load_Module $moduleName) {Write-Host "Loaded Module: $moduleName";$OnTAPLoaded=$true}

    Else {

            Write-Host "Failed to load $moduleName."

            Write-Host "You can install it from G:\IS_Infrastructure\Private\Systems Team\Virtualization\Scripts\PowerShellAddIns"

            Write-Host "Unzip the DataONTAP.zip file to C:\Windows\System32\WindowsPowerShell\v1.0\Modules"

            Write-Host "Aborting script."}

}

Catch {Write-Host "Exception caught: $_"}

Add-PSSnapin $snapIn1 -ErrorAction SilentlyContinue

If ((Get-PSSnapin $snapIn1) -eq $null) {

      Write-Host "This script requires VMware PowerCLI, but it was not found on this system."

      Write-Host "You can install it from G:\IS_Infrastructure\Private\Systems Team\Virtualization\Scripts\PowerShellAddIns"

      Write-Host "Run the latest version of the VMware-PowerCLI executable"

      Write-Host "Aborting script."

      $global:x = "2"

}

Else {

      $vmware = $snapIn1.substring(0,(($snapIn1.length)-1))+" PowerCLI"

      Write-Host "Loaded SnapIn: $vmware"

      $VMwareLoaded=$true

}

Add-PSSnapin $snapIn2 -ErrorAction SilentlyContinue

If ((Get-PSSnapin $snapIn2) -eq $null) {

      Write-Host "This script requires SolarWinds SDK, but it was not found on this system."

      Write-Host "You can install it from G:\IS_Infrastructure\Private\Systems Team\Virtualization\Scripts\PowerShellAddIns"

      Write-Host "Extract the MSI and install, then follow the Technical Guide on how to register with PowerShell"

      Write-Host "Aborting script."

      $global:x = "2"

}

Else {

      Write-Host "Loaded SnapIn: $snapIn2"

      $SwisLoaded=$true

}

 

If ($OnTAPLoaded -and $VMwareLoaded -and $SwisLoaded) {

      ## FUNCTIONS

      Function Description(){

            #Describe the script to the user

            $form = New-Object System.Windows.Forms.Form

            $l1 = New-Object System.Windows.Forms.Label

            $l2 = New-Object System.Windows.Forms.Label

            $l3 = New-Object System.Windows.Forms.Label

            $OK = New-Object System.Windows.Forms.Button

            $Can = New-Object System.Windows.Forms.Button

           

            $form.Text = "Script Description"

            $form.Size = New-Object System.Drawing.Size(650,150)

            $form.StartPosition = "CenterScreen"

            $form.MaximizeBox = $False

            $form.MinimizeBox = $False

            $form.AcceptButton = $OK

            $form.CancelButton = $Can

            $form.Controls.Add($l1)

            $form.Controls.Add($l2)

            $form.Controls.Add($l3)

            $form.Controls.Add($OK)

            $form.Controls.Add($Can)

            $form.KeyPreview = $True

 

            $l1.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.5)

            $l1.Location = New-Object System.Drawing.Point (0,10)

            $l1.Size = New-Object System.Drawing.Size (634,20)

            $l1.TextAlign = 2

            $l1.Text = "*** This script only works for VMs on NFS datastores ***"

 

            $l2.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.5)

            $l2.Location = New-Object System.Drawing.Point (0,30)

            $l2.Size = New-Object System.Drawing.Size (634,20)

            $l2.TextAlign = 2

            $l2.Text = "This script will restore a VM from a local snapshot (on the same Filer as the VM)."

 

            $l3.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.5)

            $l3.Location = New-Object System.Drawing.Point (0,50)

            $l3.Size = New-Object System.Drawing.Size (634,20)

            $l3.TextAlign = 2

            $l3.Text = "You will need to know which Filer and Filer Volume the VM is on."

 

            $OK.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.75)

            $OK.Location = New-Object System.Drawing.Point (250,75)

            $OK.Size = New-Object System.Drawing.Size (75, 25)

            $OK.TextAlign = 2

            $OK.Text = "OK"

            $OK.Add_Click({$global:x="0";$form.Close()})

 

            $Can.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.75)

            $Can.Location = New-Object System.Drawing.Point (325,75)

            $Can.Size = New-Object System.Drawing.Size (75, 25)

            $Can.TextAlign = 2

            $Can.Text = "Cancel"

            $Can.Add_Click({$global:x="2";$form.Close()})

 

            $form.Add_KeyDown({if ($_.KeyCode -eq "Escape")

{$global:x="2";$form.Close()}})

            $form.Add_KeyDown({if ($_.KeyCode -eq "Enter")

                  {$global:x="0";$form.Close()}})

            $form.Topmost = $True

            $form.Add_Shown({$form.Activate()})

            [void] $form.ShowDialog()

      }

 

      Function Aborted () {

            #Restore Aborted From

            $form = New-Object System.Windows.Forms.Form

            $l1 = New-Object System.Windows.Forms.Label

            $OK = New-Object System.Windows.Forms.Button

           

            $form.Controls.Add($l1)

            $form.Controls.Add($OK)

            $form.MaximizeBox = $False

            $form.MinimizeBox = $False

            $form.AcceptButton = $OK

            $form.Text = "Script Aborted"

            $form.Size = New-Object System.Drawing.Size(220,110)

            $form.StartPosition = "CenterScreen"

 

            $l1.Location = New-Object System.Drawing.Point(0,10)

            $l1.Size = New-Object System.Drawing.Size(220,20)

            $l1.TextAlign = 2

            $l1.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.5)

            $l1.Text = "The script was aborted!"

 

            $OK.Location = New-Object System.Drawing.Point(75,40)

            $OK.Size = New-Object System.Drawing.Size(72.5,25)

            $OK.Text = "OK"

            $OK.Add_Click({$form.Close()})

 

            $form.Topmost = $True

            $form.Add_Shown({$form.Activate()})

            [void] $form.ShowDialog()

      }

 

      Function Complete () {

            #Restore Complete Form

            $form = New-Object System.Windows.Forms.Form

            $l1 = New-Object System.Windows.Forms.Label

            $OK = New-Object System.Windows.Forms.Button

           

            $form.Text = "Script Complete"

            $form.Size = New-Object System.Drawing.Size(250,120)

            $form.StartPosition = "CenterScreen"

            $form.AcceptButton = $OK

            $form.Controls.Add($l1)

            $form.Controls.Add($OK)

            $l1.Location = New-Object System.Drawing.Size(15,20)

            $l1.Size = New-Object System.Drawing.Size(200,20)

            $l1.TextAlign = "2"

            $l1.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.5)

            $l1.Text = "The restore has completed!"

 

            $OK.Location = New-Object System.Drawing.Size(75,50)

            $OK.Size = New-Object System.Drawing.Size(87.5,25)

            $OK.Text = "OK"

            $OK.Add_Click({$form.Close()})

 

            $form.Topmost = $True

            $form.Add_Shown({$form.Activate()})

            [void] $form.ShowDialog()

      }

 

      Function Unmanage ($vm2restore) {

            #Unmanage server in Orion

            $orion = "orion.domain.corp"

            $node = $vm2restore+".domain.corp"

            $user = "swis_user"

            $pw = "swis_pass"

            $pass = $pw | ConvertTo-SecureString -AsPlainText -Force

            $cred = New-Object System.Management.Automation.PSCredential($user,$pass)

 

            $swis = Connect-Swis -Credential $cred -Hostname $orion

 

            $nodeid = Get-SwisData $swis "SELECT NodeID FROM Orion.Nodes WHERE DNS like '$node'"

            $global:mynode = "N:"+$nodeid

            $now = [DateTime]::Now

            $later = ($now).AddDays(1)

 

            Invoke-SwisVerb $swis Orion.Nodes Unmanage @($mynode,$now,$later,"false") | Out-Null

      }

 

      Function Remanage ($vm2restore) {

            #Remanage server in Orion

            $node = $vm2restore+".domain.corp"

            $orion = "orion.domain.corp"

            $user = "swis_user"

            $pw = "swis_pass"

            $pass = $pw | ConvertTo-SecureString -AsPlainText -Force

            $cred = New-Object System.Management.Automation.PSCredential($user,$pass)

 

            $form = New-Object System.Windows.Forms.Form

            $form.Text = "Sleeping"

            $form.Size = New-Object System.Drawing.Size(460,130)

            $form.StartPosition = "CenterScreen"

 

            $l1 = New-Object System.Windows.Forms.Label

            $l1.Location = New-Object System.Drawing.Size(0,10)

            $l1.Size = New-Object System.Drawing.Size(440,20)

            $l1.TextAlign = 2

            $l1.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.5)

            $l1.Text = "$vm2restore has been powered on."

            $form.Controls.Add($l1)

 

            $l2 = New-Object System.Windows.Forms.Label

            $l2.Location = New-Object System.Drawing.Size(0,30)

            $l2.Size = New-Object System.Drawing.Size(440,20)

            $l2.TextAlign = 2

            $l2.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.5)

            $l2.Text = "Sleeping for 60 seconds before attempting to remanage server in Orion."

            $form.Controls.Add($l2)

 

            $OK = New-Object System.Windows.Forms.Button

            $OK.Location = New-Object System.Drawing.Size(194,60)

            $OK.Size = New-Object System.Drawing.Size(72.5,25)

            $OK.Text = "OK"

            $OK.Add_Click({$form.Close()})

            $form.Controls.Add($OK)

 

            $form.Topmost = $True

            $form.Add_Shown({$form.Activate()})

            [void] $form.ShowDialog()

 

            $swis1 = Connect-Swis -Credential $cred -Hostname $orion

 

            $nodeid = Get-SwisData $swis1 "SELECT NodeID FROM Orion.Nodes WHERE DNS like '$node'"

            $mynode = "N:"+$nodeid

 

            Start-Sleep -Seconds 60

            Invoke-SwisVerb $swis1 Orion.Nodes Remanage @($mynode) | Out-Null

 

            $global:x="1"

      }

 

      Function Get_Restore_VM () {

      # Get vCenter, VM to restore, Filer and Volume information

      # Create Form Elements

      [System.Windows.Forms.Application]::EnableVisualStyles()

      $frm_restore = New-Object System.Windows.Forms.Form

      $l_norm = New-Object System.Windows.Forms.Label

      $gb_vcen = New-Object System.Windows.Forms.GroupBox

      $l_vcen = New-Object System.Windows.Forms.Label

      $cmb_vcen = New-Object System.Windows.Forms.ComboBox

      $b_vcenSelect = New-Object System.Windows.Forms.Button

      $gb_restoreVM = New-Object System.Windows.Forms.GroupBox

      $l_RestoreVM = New-Object System.Windows.Forms.Label

      $cmb_restoreVM = New-Object System.Windows.Forms.ComboBox

      $b_restoreSelect = New-Object System.Windows.Forms.Button

      $gb_Filer = New-Object System.Windows.Forms.GroupBox

      $cmb_filer = New-Object System.Windows.Forms.ComboBox

      $l_Filer = New-Object System.Windows.Forms.Label

      $b_filerSelect = New-Object System.Windows.Forms.Button

      $gb_vol = New-Object System.Windows.Forms.GroupBox

      $l_volume = New-Object System.Windows.Forms.Label

      $cmb_volume = New-Object System.Windows.Forms.ComboBox

      $b_volumeSelect = New-Object System.Windows.Forms.Button

      $gb_snapshot = New-Object System.Windows.Forms.GroupBox

      $l_snapshot = New-Object System.Windows.Forms.Label

      $cmb_snapshot = New-Object System.Windows.Forms.ComboBox

      $gb_snaplist = New-Object System.Windows.Forms.GroupBox

      $rtb_snaplist = New-Object System.Windows.Forms.RichTextBox

      $b_snapSelect = New-Object System.Windows.Forms.Button

      $b_OK = New-Object System.Windows.Forms.Button

      $b_Cancel = New-Object System.Windows.Forms.Button

      $InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState

      # Create Form Functionality

      $b_vcenSelect_Click = {

            $vc1=$cmb_vcen.SelectedItem.ToString()

            $cmb_vcen.Enabled=$false

            $b_vcenSelect.Visible=$false

            $gb_restoreVM.Visible=$true

            Start-Sleep -Seconds 1

            If ($vc1 -eq "VCENTER1 (Production)") {$global:MyVC = "vcenter1"}

            If ($vc1 -eq "VCENTER2 (View)") {$global:MyVC = "vcenter2"}

            If ($vc1 -eq "VCENTER3 (Test)") {$global:MyVC = "vcenter3"}

            Connect-VIServer $MyVC | Out-Null

            $VMList = Get-VM | Select-Object Name | Sort Name | ForEach{$_.Name}

            ForEach ($vm in $VMList) {$cmb_restoreVM.Items.Add($vm)}

            $l_RestoreVM.Visible=$true

            $cmb_restoreVM.Visible=$true

            $b_restoreSelect.Visible=$true

      }

     

      $b_restoreSelect_Click = {

            $global:vm2restore=$cmb_restoreVM.SelectedItem.ToString()

            $b_restoreSelect.Visible=$false

            $cmb_restoreVM.Enabled=$false

            Start-Sleep -Seconds 1

            $global:vmDatastore = Get-Datastore -VM $vm2restore

            $global:esxhost = Get-VMHost -VM $vm2restore

            $global:vm1 = Get-VM $vm2restore | Get-View

 

            $dsCount = ($vmDatastore).Count

            If ($dsCount -gt 1) {

                  # Create Subform Elements

                  $s_form = New-Object System.Windows.Forms.Form

                  $l_1 = New-Object System.Windows.Forms.Label

                  $l_2 = New-Object System.Windows.Forms.Label

                  $l_3 = New-Object System.Windows.Forms.Label

                  $b_OK2 = New-Object System.Windows.Forms.Button

                  # Form Element Definitions

                  $s_form.Controls.Add($l_1)

                  $s_form.Controls.Add($l_2)

                  $s_form.Controls.Add($l_3)

                  $s_form.Controls.Add($b_OK2)

                  $s_form.ClientSize = New-Object System.Drawing.Size(270,150)

                  $s_form.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

                  $s_form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog

                  $s_form.MaximizeBox = $False

                  $s_form.MinimizeBox = $False

                  $s_form.StartPosition = "CenterScreen"

                  $s_form.Name = "frm_restore"

                  $s_form.Text = "Datastore Conflict"

                 

                  $l_1.Location = New-Object System.Drawing.Size(0,20)

                  $l_1.Size = New-Object System.Drawing.Size(270,20)

                  $l_1.Font = $font2

                  $l_1.TextAlign = 2

                  $l_1.Text = "*** VM has more than one Datastore ***"

 

                  $l_2.Location = New-Object System.Drawing.Size(0,50)

                  $l_2.Size = New-Object System.Drawing.Size(270,20)

                  $l_2.Font = $font2

                  $l_2.TextAlign = 2

                  $l_2.Text = "$vmDatastore"

                 

                  $l_3.Location = New-Object System.Drawing.Size(0,80)

                  $l_3.Size = New-Object System.Drawing.Size(270,20)

                  $l_3.Font = $font2

                  $l_3.TextAlign = 2

                  $l_3.Text = "--Please correct and retry script--"

 

                  $b_OK2.Location = New-Object System.Drawing.Size(98,110)

                  $b_OK2.Size = New-Object System.Drawing.Size(75,25)

                  $b_OK2.Text = "OK"

                  $b_OK2.Add_Click({$s_form.Close()})

 

                  $s_form.Topmost = $True

                  $s_form.Add_Shown({$s_form.Activate()})

                  [void] $s_form.ShowDialog()

                 

                  # Abort Script

                  $global:x="2"

                  $frm_restore.Close()

            }

            $gb_Filer.Visible=$true

            $l_Filer.Text = "What Filer is the "+$vmDatastore+" datastore on?"

            $l_Filer.Visible=$true

            $Filers = GC "\\filer1\Virtualization\Scripts\restore\filers.txt"

            ForEach ($filer in $Filers) {$cmb_filer.Items.Add($filer)}

            $cmb_filer.Visible=$true

            $b_filerSelect.Visible=$true

      }

     

      $b_filerSelect_Click = {

            $b_filerSelect.Visible=$false

            $gb_vol.Visible=$true

            $cmb_filer.Enabled=$false

            Start-Sleep -Seconds 1

            $global:MyFiler=$cmb_filer.SelectedItem.ToString()

            $l_volume.Text = "What volume is the "+$vmDatastore+" datastore on?"

            $l_volume.Visible=$true

            $filer1 = Connect-NaController $MyFiler | Out-Null

            $vols = Get-NaVol | Select-Object Name | Sort Name | ForEach {$_}

            $volList=$vols

            ForEach ($v in $volList | Sort Name) {$cmb_volume.Items.Add($v.Name)}

            $cmb_volume.Visible=$true

            $b_volumeSelect.Visible=$true

           

      }

     

      $b_volumeSelect_Click = {

            $b_volumeSelect.Visible=$false

            $gb_snapshot.Visible=$true

            $cmb_volume.Enabled=$false

            Start-Sleep -Seconds 1

            $global:MyVol=$cmb_volume.SelectedItem.ToString()

            $snapList = Get-NaSnapshot -TargetName $MyVol -TargetType volume

            $l_snapshot.Visible=$true

            $gb_snaplist.Visible=$true

            ForEach ($snap in $snapList) {

                  $len = $snap.Name

                  If ($len.Length -le 8) {

                        $rtb_snaplist.AppendText($snap.Name+"`t`t`t`t"+$snap.AccessTimeDT+"`n")

                  }

                  If ($len.Length -gt 8 -and $len.Length -le 12) {

                        $rtb_snaplist.AppendText($snap.Name+"`t`t`t"+$snap.AccessTimeDT+"`n")

                  }

            }    

            $rtb_snaplist.Visible=$true

            Foreach ($CHKVM in $vm1){

                  $global:Folder = ((($CHKVM.Summary.Config.VmPathName).Split(']')[1]).Split('/'))[0].TrimStart(' ')

                  $global:Path = ($CHKVM.Summary.Config.VmPathName).Split('/')[0]

            }

            New-PSDrive -Name "ds" -Root \ -PSProvider VimDatastore -Datastore $vmDatastore

            cd ds:

 

            $snaps = ls ".snapshot" | Select-Object Name | Sort Name

            ForEach ($ss in $snaps) {

                  $s_len = $ss.Name

                  If ($s_len.Length -le 12) {$cmb_snapshot.Items.Add($ss.Name)}

            }

            $cmb_snapshot.Visible=$true

            $b_snapSelect.Visible=$true

      }

     

      $b_snapSelect_Click = {

            $b_snapSelect.Visible=$false

            $cmb_snapshot.Enabled=$false

            $b_Cancel.Location = New-Object System.Drawing.Point(425,360)

            $b_OK.Visible=$true

            Start-Sleep -Seconds 1

            $global:snapshot1=$cmb_snapshot.SelectedItem.ToString()

      }

     

      $b_OK_Click = {$global:x="0";$frm_restore.Close()}

     

      $b_Cancel_Click = {$global:x="2";$frm_restore.Close()}

     

      $Form_StateCorrection_Load = {$frm_restore.WindowState = $InitialFormWindowState}  

      # Form Element Definitions

      $font1 = New-Object System.Drawing.Font("Microsoft Sans Serif",9)

      $font2 = New-Object System.Drawing.Font("Microsoft Sans Serif",9.5)

      $frm_restore.Controls.Add($l_norm)

      $frm_restore.Controls.Add($gb_vcen)

      $frm_restore.Controls.Add($gb_restoreVM)

      $frm_restore.Controls.Add($gb_Filer)

      $frm_restore.Controls.Add($gb_vol)

      $frm_restore.Controls.Add($gb_snapshot)

      $frm_restore.Controls.Add($b_OK)

      $frm_restore.Controls.Add($b_Cancel)

      $frm_restore.AcceptButton = $b_OK

      $frm_restore.CancelButton = $b_Cancel

      $frm_restore.ClientSize = New-Object System.Drawing.Size(825,410)

      $frm_restore.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $frm_restore.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog

      $frm_restore.MaximizeBox = $False

      $frm_restore.MinimizeBox = $False

      $frm_restore.StartPosition = "CenterScreen"

      $frm_restore.Name = "frm_restore"

      $frm_restore.Text = "Restore a VM using SnapRestore"

      $frm_restore.Font = $font2

     

      $l_norm.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $l_norm.Location = New-Object System.Drawing.Point(45,9)

      $l_norm.Name = "l_norm"

      $l_norm.Size = New-Object System.Drawing.Size(330,32)

      $l_norm.Tabstop = $false

      $l_norm.Font = $font2

      $l_norm.Text = "(some lag while loading form sections is normal`nas script functions are ran in the background)"

      $l_norm.TextAlign = 2

 

      $gb_vcen.Controls.Add($b_vcenSelect)

      $gb_vcen.Controls.Add($cmb_vcen)

      $gb_vcen.Controls.Add($l_vcen)

      $gb_vcen.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $gb_vcen.Font = $font2

      $gb_vcen.Location = New-Object System.Drawing.Point(12,53)

      $gb_vcen.Name = "gb_vcen"

      $gb_vcen.Size = New-Object System.Drawing.Size(185,135)

      $gb_vcen.TabStop = $False

      $gb_vcen.Text = "vCenter Selection"

     

      $l_vcen.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $l_vcen.Location = New-Object System.Drawing.Point(5,20)

      $l_vcen.Name = "l_vcen"

      $l_vcen.Size = New-Object System.Drawing.Size(175,42)

      $l_vcen.TabStop = $false

      $l_vcen.Font = $font2

      $l_vcen.Text = "What vCenter is the VM you want to restore attached to?"

      $l_vcen.TextAlign = 2

     

      $cmb_vcen.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $cmb_vcen.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList

      $cmb_vcen.FormattingEnabled = $True

      [void]$cmb_vcen.Items.Add("VCENTER1 (Production)")

      [void]$cmb_vcen.Items.Add("VCENTER2 (View)")

      [void]$cmb_vcen.Items.Add("VCENTER3 (Test)")

      $cmb_vcen.Location = New-Object System.Drawing.Point(8,60)

      $cmb_vcen.Name = "cmb_vcen"

      $cmb_vcen.Size = New-Object System.Drawing.Size(171,23)

      $cmb_vcen.Font = $font1

      $cmb_vcen.TabIndex = 1

     

      $b_vcenSelect.AutoSize = $True

      $b_vcenSelect.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $b_vcenSelect.Location = New-Object System.Drawing.Point(55,95)

      $b_vcenSelect.Name = "b_vcenSelect"

      $b_vcenSelect.Size = New-Object System.Drawing.Size(75,25)

      $b_vcenSelect.TabIndex = 2

      $b_vcenSelect.Text = "Select"

      $b_vcenSelect.UseVisualStyleBackColor = $True

      $b_vcenSelect.Add_Click($b_vcenSelect_Click)

     

      $gb_restoreVM.Controls.Add($b_restoreSelect)

      $gb_restoreVM.Controls.Add($cmb_restoreVM)

      $gb_restoreVM.Controls.Add($l_RestoreVM)

      $gb_restoreVM.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $gb_restoreVM.Font = $font2

      $gb_restoreVM.Location = New-Object System.Drawing.Point(222,53)

      $gb_restoreVM.Name = "gb_restoreVM"

      $gb_restoreVM.Size = New-Object System.Drawing.Size(185,135)

      $gb_restoreVM.TabStop = $False

      $gb_restoreVM.Text = "VM to Restore"

      $gb_restoreVM.Visible = $False

     

      $l_RestoreVM.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $l_RestoreVM.Location = New-Object System.Drawing.Point(5,20)

      $l_RestoreVM.Name = "l_RestoreVM"

      $l_RestoreVM.Size = New-Object System.Drawing.Size(175,42)

      $l_RestoreVM.TabStop = $false

      $l_RestoreVM.Font = $font2

      $l_RestoreVM.Text = "Which VM do you want to restore?"

      $l_RestoreVM.TextAlign = 2

      $l_RestoreVM.Visible = $False

     

      $cmb_restoreVM.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $cmb_restoreVM.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList

      $cmb_restoreVM.FormattingEnabled = $True

      $cmb_restoreVM.Location = New-Object System.Drawing.Point(8,60)

      $cmb_restoreVM.Name = "cmb_restoreVM"

      $cmb_restoreVM.Size = New-Object System.Drawing.Size(171,23)

      $cmb_restoreVM.Font = $font1

      $cmb_restoreVM.TabIndex = 3

      $cmb_restoreVM.Visible = $False

     

      $b_restoreSelect.AutoSize = $True

      $b_restoreSelect.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $b_restoreSelect.Location = New-Object System.Drawing.Point(55,95)

      $b_restoreSelect.Name = "b_restoreSelect"

      $b_restoreSelect.Size = New-Object System.Drawing.Size(75,25)

      $b_restoreSelect.TabIndex = 4

      $b_restoreSelect.Text = "Select"

      $b_restoreSelect.UseVisualStyleBackColor = $True

      $b_restoreSelect.Visible = $False

      $b_restoreSelect.Add_Click($b_restoreSelect_Click)

     

      $gb_Filer.Controls.Add($b_filerSelect)

      $gb_Filer.Controls.Add($cmb_filer)

      $gb_Filer.Controls.Add($l_Filer)

      $gb_Filer.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $gb_Filer.Font = $font2

      $gb_Filer.Location = New-Object System.Drawing.Point(12,206)

      $gb_Filer.Name = "gb_Filer"

      $gb_Filer.Size = New-Object System.Drawing.Size(185,135)

      $gb_Filer.TabStop = $False

      $gb_Filer.Text = "Filer Selection"

      $gb_Filer.Visible = $False

     

      $l_Filer.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $l_Filer.Location = New-Object System.Drawing.Point(5,20)

      $l_Filer.Name = "l_Filer"

      $l_Filer.Size = New-Object System.Drawing.Size(175,42)

      $l_Filer.TabStop = $false

      $l_Filer.Font = $font2

      $l_Filer.TextAlign = 2

      $l_Filer.Visible = $False

     

      $cmb_filer.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $cmb_filer.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList

      $cmb_filer.FormattingEnabled = $True

      $cmb_filer.Location = New-Object System.Drawing.Point(8,60)

      $cmb_filer.Name = "cmb_filer"

      $cmb_filer.Size = New-Object System.Drawing.Size(171,23)

      $cmb_filer.Font = $font1

      $cmb_filer.TabIndex = 5

      $cmb_filer.Visible = $False

     

      $b_filerSelect.AutoSize = $True

      $b_filerSelect.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $b_filerSelect.Location = New-Object System.Drawing.Point(55,95)

      $b_filerSelect.Name = "b_filerSelect"

      $b_filerSelect.Size = New-Object System.Drawing.Size(75,25)

      $b_filerSelect.TabIndex = 6

      $b_filerSelect.Text = "Select"

      $b_filerSelect.UseVisualStyleBackColor = $True

      $b_filerSelect.Visible = $False

      $b_filerSelect.Add_Click($b_filerSelect_Click)

     

      $gb_vol.Controls.Add($b_volumeSelect)

      $gb_vol.Controls.Add($cmb_volume)

      $gb_vol.Controls.Add($l_volume)

      $gb_vol.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $gb_vol.Font = $font2

      $gb_vol.Location = New-Object System.Drawing.Point(222,206)

      $gb_vol.Name = "gb_vol"

      $gb_vol.Size = New-Object System.Drawing.Size(185,135)

      $gb_vol.TabStop = $False

      $gb_vol.Text = "Volume Selection"

      $gb_vol.Visible = $False

     

      $l_volume.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $l_volume.Location = New-Object System.Drawing.Point(5,20)

      $l_volume.Name = "l_volume"

      $l_volume.Size = New-Object System.Drawing.Size(175,42)

      $l_volume.TabStop = $false

      $l_volume.Font = $font2

      $l_volume.TextAlign = 2

      $l_volume.Visible = $False

     

      $cmb_volume.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $cmb_volume.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList

      $cmb_volume.FormattingEnabled = $True

      $cmb_volume.Location = New-Object System.Drawing.Point(8,60)

      $cmb_volume.Name = "cmb_volume"

      $cmb_volume.Size = New-Object System.Drawing.Size(171,23)

      $cmb_volume.Font = $font1

      $cmb_volume.TabIndex = 7

      $cmb_volume.Visible = $False

     

      $b_volumeSelect.AutoSize = $True

      $b_volumeSelect.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $b_volumeSelect.Location = New-Object System.Drawing.Point(55,95)

      $b_volumeSelect.Name = "b_volumeSelect"

      $b_volumeSelect.Size = New-Object System.Drawing.Size(75,25)

      $b_volumeSelect.TabIndex = 8

      $b_volumeSelect.Text = "Select"

      $b_volumeSelect.UseVisualStyleBackColor = $True

      $b_volumeSelect.Visible = $False

      $b_volumeSelect.Add_Click($b_volumeSelect_Click)

 

      $gb_snapshot.Controls.Add($l_snapshot)

      $gb_snapshot.Controls.Add($cmb_snapshot)

      $gb_snapshot.Controls.Add($gb_snaplist)

      $gb_snapshot.Controls.Add($b_snapSelect)

      $gb_snapshot.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $gb_snapshot.Font = $font2

      $gb_snapshot.Location = New-Object System.Drawing.Point(435,9)

      $gb_snapshot.Name = "gb_snapshot"

      $gb_snapshot.Size = New-Object System.Drawing.Size(380,332)

      $gb_snapshot.TabStop = $False

      $gb_snapshot.Text = "Snapshot Selection"

      $gb_snapshot.Visible = $False

 

      $l_snapshot.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $l_snapshot.Location = New-Object System.Drawing.Point(5,20)

      $l_snapshot.Name = "l_snapshot"

      $l_snapshot.Size = New-Object System.Drawing.Size(370,20)

      $l_snapshot.TabStop = $false

      $l_snapshot.Font = $font2

      $l_snapshot.Text = "Which snapshot do you want to restore from?"

      $l_snapshot.Visible = $False

     

      $cmb_snapshot.AutoSize = $true

      $cmb_snapshot.Location = New-Object System.Drawing.Point(5, 40)

      $cmb_snapshot.Name = "cb_snapshot"

      $cmb_snapshot.DropDownStyle = "DropDownList"

      $cmb_snapshot.Size = New-Object System.Drawing.Size(200, 20)

      $cmb_snapshot.TabIndex = 9

      $cmb_snapshot.Visible = $False

 

      $gb_snaplist.Controls.Add($rtb_snaplist)

      $gb_snaplist.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $gb_snaplist.Font = $font2

      $gb_snaplist.Location = New-Object System.Drawing.Point(5,70)

      $gb_snaplist.Name = "gb_snaplist"

      $gb_snaplist.Size = New-Object System.Drawing.Size(370,230)

      $gb_snaplist.TabStop = $False

      $gb_snaplist.Text = "Snapshot List"

      $gb_snaplist.Visible = $False

     

      $rtb_snaplist.Location = New-Object System.Drawing.Point(5, 5)

      $rtb_snaplist.Dock = [System.Windows.Forms.DockStyle]::Fill

      $rtb_snaplist.Name = "rtb_snaplist"

      $rtb_snaplist.Font = New-Object System.Drawing.Font("Lucadia Console",9.5)

      $rtb_snaplist.Size = New-Object System.Drawing.Size(290,210)

      $rtb_snaplist.TabStop = $false

      $rtb_snaplist.ReadOnly = $true

      $rtb_snaplist.Visible = $False

      $rtb_snaplist.AppendText("Here is a list of snapshots and when they were taken:")

      $rtb_snaplist.AppendText("`n`nSnapshot Name`t`tDate/Time Taken`n")

     

      $b_snapSelect.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $b_snapSelect.Location  = New-Object System.Drawing.Point(168,300)

      $b_snapSelect.Name = "b_snapSelect"

      $b_snapSelect.Size = New-Object System.Drawing.Size(75,25)

      $b_snapSelect.TabIndex = 10

      $b_snapSelect.Text = "Select"

      $b_snapSelect.UseVisualStyleBackColor = $True

      $b_snapSelect.Visible = $False

      $b_snapSelect.Add_Click($b_snapSelect_Click)

     

      $b_OK.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $b_OK.Location = New-Object System.Drawing.Point(345,360)

      $b_OK.Name = "b_OK"

      $b_OK.Size = New-Object System.Drawing.Size(75,25)

      $b_OK.TabIndex = 11

      $b_OK.Text = "OK"

      $b_OK.UseVisualStyleBackColor = $True

      $b_OK.Visible = $false

      $b_OK.Add_Click($b_OK_Click)

     

      $b_Cancel.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

      $b_Cancel.Location = New-Object System.Drawing.Point(375,360)

      $b_Cancel.Name = "b_Cancel"

      $b_Cancel.Size = New-Object System.Drawing.Size(75,25)

      $b_Cancel.TabIndex = 12

      $b_Cancel.Text = "Cancel"

      $b_Cancel.UseVisualStyleBackColor = $True

      $b_Cancel.Add_Click($b_Cancel_Click)

     

      # Save the initial state of the form

      $InitialFormWindowState = $frm_restore.WindowState

      # Init the OnLoad event to correct the initial state of the form

      $frm_restore.add_Load($Form_StateCorrection_Load)

      # Show the Form

      return $frm_restore.ShowDialog()

      }

 

      Function Compare_VMDK($Folder, $snapshot1, $vm2restore) {

            $global:compare1 = @()

            $global:compare2 = @()

           

            $global:compare1 = Get-ChildItem $Folder -Force | Where-Object {$_.Name -like "*vmdk*" -and $_.ItemType -eq "File"} | Sort Name | Foreach {$_.Name}

            $global:compare2 = Get-ChildItem ".snapshot/$snapshot1/$Folder" -Force | Where-Object {$_.Name -like "*vmdk*" -and $_.ItemType -eq "File"} | Sort Name | Foreach {$_.Name}

           

            # Create Form Elements

            [System.Windows.Forms.Application]::EnableVisualStyles()

            $frm_compare = New-Object System.Windows.Forms.Form

            $gb_compare = New-Object System.Windows.Forms.GroupBox

            $l_CurrVMDK = New-Object System.Windows.Forms.Label

            $l_SSVMDK = New-Object System.Windows.Forms.Label

            $rtb_curr = New-Object System.Windows.Forms.RichTextBox

            $rtb_ss = New-Object System.Windows.Forms.RichTextBox

            $l_note = New-Object System.Windows.Forms.Label

            $rtb_note = New-Object System.Windows.Forms.RichTextBox

            $gb_restoreType = New-Object System.Windows.Forms.GroupBox

            $l_restoreType = New-Object System.Windows.Forms.Label

            $b_vmdk = New-Object System.Windows.Forms.Button

            $b_entire = New-Object System.Windows.Forms.Button

            $b_cancel = New-Object System.Windows.Forms.Button

            $InitialFormWindowState = New-Object System.Windows.Forms.FormWindowState

            $Form_StateCorrection_Load = {$frm_compare.WindowState = $InitialFormWindowState}     

 

            # Form Element Definitions

            $font1 = New-Object System.Drawing.Font("Microsoft Sans Serif",9)

            $font2 = New-Object System.Drawing.Font("Microsoft Sans Serif",9.5)

            $font3 = New-Object System.Drawing.Font("Lucadia Console",9)

            $frm_compare.Controls.Add($gb_compare)

            $frm_compare.Controls.Add($gb_restoreType)

            $frm_compare.Controls.Add($b_cancel)

            $frm_compare.CancelButton = $b_cancel

            $frm_compare.ClientSize = New-Object System.Drawing.Size(760,350)

            $frm_compare.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

            $frm_compare.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog

            $frm_compare.MaximizeBox = $False

            $frm_compare.MinimizeBox = $False

            $frm_compare.StartPosition = "CenterScreen"

            $frm_compare.Name = "frm_compare"

            $frm_compare.Text = "Restore Type Selection"

            $frm_compare.Font = $font2

     

            $gb_compare.Controls.Add($l_CurrVMDK)

            $gb_compare.Controls.Add($l_SSVMDK)

            $gb_compare.Controls.Add($rtb_curr)

            $gb_compare.Controls.Add($rtb_ss)

            $gb_compare.Controls.Add($l_note)

            $gb_compare.Controls.Add($rtb_note)

            $gb_compare.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

            $gb_compare.Font = $font2

            $gb_compare.Location = New-Object System.Drawing.Point(5,10)

            $gb_compare.Name = "gb_compare"

            $gb_compare.Size = New-Object System.Drawing.Size(460,300)

            $gb_compare.TabStop = $false

            $gb_compare.Text = "VMDK Comparison"

           

            $l_CurrVMDK.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

            $l_CurrVMDK.Location = New-Object System.Drawing.Point(12,25)

            $l_CurrVMDK.Name = "l_CurrVMDK"

            $l_CurrVMDK.Size = New-Object System.Drawing.Size(190,40)

            $l_CurrVMDK.TabStop = $false

            $l_CurrVMDK.Font = $font2

            $l_CurrVMDK.Text = "Here are the current VMDKs for $vm2restore :"

           

            $l_SSVMDK.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

            $l_SSVMDK.Location = New-Object System.Drawing.Point(243,25)

            $l_SSVMDK.Name = "l_SSVMDK"

            $l_SSVMDK.Size = New-Object System.Drawing.Size(190,40)

            $l_SSVMDK.TabStop = $false

            $l_SSVMDK.Font = $font2

            $l_SSVMDK.Text = "Here are the VMDKs for $vm2restore from the snapshot:"

           

            $rtb_curr.Location = New-Object System.Drawing.Point(12,65)

            $rtb_curr.Name = "rtb_curr"

            $rtb_curr.Font = $font3

            $rtb_curr.Size = New-Object System.Drawing.Size(190,90)

            $rtb_curr.TabStop = $false

            $rtb_curr.ReadOnly = $true

            ForEach ($vmdk in $compare1) {$rtb_curr.AppendText("$vmdk`n")}

 

            $rtb_ss.Location = New-Object System.Drawing.Point(243,65)

            $rtb_ss.Name = "rtb_ss"

            $rtb_ss.Font = $font3

            $rtb_ss.Size = New-Object System.Drawing.Size(190,90)

            $rtb_ss.TabStop = $false

            $rtb_ss.ReadOnly = $true

            ForEach ($ssvmdk in $compare2) {$rtb_ss.AppendText("$ssvmdk`n")}

           

            $l_note.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

            $l_note.Location = New-Object System.Drawing.Point(12,170)

            $l_note.Name = "l_note"

            $l_note.Size = New-Object System.Drawing.Size(420,15)

            $l_note.TabStop = $false

            $l_note.Font = $font2

            $l_note.Text = "NOTE(S):"

           

            $rtb_note.Location = New-Object System.Drawing.Point(12,195)

            $rtb_note.Name = "rtb_note"

            $rtb_note.Font = $font3

            $rtb_note.Size = New-Object System.Drawing.Size(420,90)

            $rtb_note.TabStop = $false

            $rtb_note.ReadOnly = $true

            If ($compare1.length -ne $compare2.length) {

                  $rtb_note.AppendText("-The VMDKs do not appear to match, please select the option to restore the entire VM.")

            }

            Else {

                  $rtb_note.AppendText("- The VMDKs appear to match.`n")

                  $rtb_note.AppendText("- If the VM only has 1 -flat.vmdk, select the option to restore`n     the VMDK only.`n")

                  $rtb_note.AppendText("- If the VM has more than 1 -flat.vmdk OR any -delta.vmdk(s), select`n     the option to restore the entire VM")

            }

 

            $gb_restoreType.Controls.Add($l_restoreType)

            $gb_restoreType.Controls.Add($b_vmdk)

            $gb_restoreType.Controls.Add($b_entire)

            $gb_restoreType.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

            $gb_restoreType.Font = $font2

            $gb_restoreType.Location = New-Object System.Drawing.Point(480,10)

            $gb_restoreType.Name = "gb_restoreType"

            $gb_restoreType.Size = New-Object System.Drawing.Size(270,300)

            $gb_restoreType.TabStop = $false

            $gb_restoreType.Text = "Restore Type Selection"

           

            $l_restoreType.DataBindings.DefaultDataSourceUpdateMode = [System.Windows.Forms.DataSourceUpdateMode]::OnValidation

            $l_restoreType.Location = New-Object System.Drawing.Point(10,30)

            $l_restoreType.Name = "l_restoreType"

            $l_restoreType.Size = New-Object System.Drawing.Size(250,40)

            $l_restoreType.TabStop = $false

            $l_restoreType.Font = $font2

            $l_restoreType.TextAlign = 2

            $l_restoreType.Text = "Which restore type do you want to perform?"

 

            $b_vmdk.Location = New-Object System.Drawing.Point (10,85)

            $b_vmdk.Size = New-Object System.Drawing.Size (250,70)

            $b_vmdk.TextAlign = "MiddleCenter"

            $b_vmdk.Name = "b_vmdk"

            $b_vmdk.TabStop = 1

            $b_vmdk.Font = $font2

            $b_vmdk.Text = "Restore VMDK only`n(Select this if there are no VMDK conflicts)"

            $b_vmdk.Add_Click({$global:x="0";$global:VMDKonly="1";$frm_compare.Close()})

           

            $b_entire.Location = New-Object System.Drawing.Point (10,190)

            $b_entire.Size = New-Object System.Drawing.Size (250,80)

            $b_entire.TextAlign = "MiddleCenter"

            $b_entire.Name = "b_enitre"

            $b_entire.Font = $font2

            $b_entire.TabStop = 2

            $b_entire.Text = "Restore Entire VM`n(Select this if there are more than 1 -flat.vmdk files OR any -delta.vmdk files)"

            $b_entire.Add_Click({$global:x="0";$global:EntireVM="1";$frm_compare.Close()})

 

            $b_cancel.Location = New-Object System.Drawing.Point(343,320)

            $b_cancel.Size = New-Object System.Drawing.Size(75,25)

            $b_cancel.TextAlign = 2

            $b_cancel.Name = "b_cancel"

            $b_cancel.TabStop = 3

            $b_cancel.Text = "Cancel"

            $b_cancel.Add_Click({$global:x="2";$frm_compare.Close()})  

 

            # Save the initial state of the form

            $InitialFormWindowState = $frm_compare.WindowState

            # Init the OnLoad event to correct the initial state of the form

            $frm_compare.add_Load($Form_StateCorrection_Load)

            # Show the Form

            return $frm_compare.ShowDialog()

      }

 

      Function Check_Power($vm2restore, $orion) {

            #Get power state of VM and turn off if it is on

            C:

            $power = get-vm $vm2restore | select-object "PowerState" | foreach{$_.PowerState}

            If ($power -match "on") {

 

                  $form = New-Object System.Windows.Forms.Form

                  $l1 = New-Object System.Windows.Forms.Label

                  $l2 = New-Object System.Windows.Forms.Label

                  $l3 = New-Object System.Windows.Forms.Label

                  $OK = New-Object System.Windows.Forms.Button

                  $Can = New-Object System.Windows.Forms.Button

 

                  $font = New-Object System.Drawing.Font("Microsoft Sans Serif",9.5)

                  $form.Controls.Add($l1)

                  $form.Controls.Add($l2)

                  $form.Controls.Add($l3)

                  $form.Controls.Add($OK)

                  $form.Controls.Add($Can)

                  $form.AcceptButton = $OK

                  $form.CancelButton = $Cancel

                  $form.Text = "VM Powered On"

                  $form.ClientSize = New-Object System.Drawing.Size(500,105)

                  $form.MaximizeBox = $false

                  $form.MinimizeBox = $false

                  $form.StartPosition = "CenterScreen"

 

                  $l1.Location = New-Object System.Drawing.Size (10,10)

                  $l1.Size = New-Object System.Drawing.Size (480,20)

                  $l1.Font = $font

                  $l1.TextAlign = 2

                  $l1.Text = "*** $vm2restore is currently on ***"

 

                  $l2.Location = New-Object System.Drawing.Size (10,30)

                  $l2.Size = New-Object System.Drawing.Size (480,20)

                  $l2.Font = $font

                  $l2.TextAlign = 2

                  $l2.Text = "Click OK to immediately power off $vm2restore and continue the restore."

 

                  $l3.Location = New-Object System.Drawing.Size (10,50)

                  $l3.Size = New-Object System.Drawing.Size (480,20)

                  $l3.Font = $font

                  $l3.TextAlign = 2

                  $l3.Text = "Click Cancel to abort the script."

 

                  $OK.Location = New-Object System.Drawing.Size (175,75)

                  $OK.Size = New-Object System.Drawing.Size (75, 25)

                  $OK.TextAlign = "MiddleCenter"

                  $OK.Text = "OK"

                  $OK.Add_Click({$cont="y";$global:x="0";$form.Close()})

 

                  $Can.Location = New-Object System.Drawing.Size (250,75)

                  $Can.Size = New-Object System.Drawing.Size (75, 25)

                  $Can.TextAlign = "MiddleCenter"

                  $Can.Text = "Cancel"

                  $Can.Add_Click({$global:x="2";$form.Close()})

 

                  $form.KeyPreview = $True

                  $form.Add_KeyDown({if ($_.KeyCode -eq "Escape")

                      {$global:x="2";$form.Close()}})

                  $form.Add_KeyDown({if ($_.KeyCode -eq "Enter")

                        {$cont="y";$global:x="0";$form.Close()}})

 

                  $form.Topmost = $True

                  $form.Add_Shown({$form.Activate()})

                  [void] $form.ShowDialog()

 

                  If ($cont -eq "y") {

                        Unmanage ($vm2restore)

                        Get-VM $vm2restore | Stop-VM -Confirm:$false

                  }

                  Else {$global:x="2"}

            }

      }

 

      Function Overwrite () {

            #Ask whether or not to overwrite current state of the VM

            $form = New-Object System.Windows.Forms.Form

            $form.Text = "Overwrite?"

            $form.Size = New-Object System.Drawing.Size(550,200)

            $form.StartPosition = "CenterScreen"

 

            $l1 = New-Object System.Windows.Forms.Label

            $l1.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.5)

            $l1.Location = New-Object System.Drawing.Size (0,10)

            $l1.Size = New-Object System.Drawing.Size (550,20)

            $l1.TextAlign = 2

            $l1.Text = "Do you want to overwrite the current state of the VM?"

            $form.Controls.Add($l1)

 

            $bover = New-Object System.Windows.Forms.Button

            $bover.Location = New-Object System.Drawing.Size (10,35)

            $bover.Size = New-Object System.Drawing.Size (230,80)

            $bover.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.5)

            $bover.TextAlign = "MiddleCenter"

            $bover.Text = "OK`nto`nOVERWRITE`ncurrent state"

            $bover.Add_Click({$global:x="0";$global:overwrite="1";$form.Close()})

            $form.Controls.Add($bover)

 

            $bleave = New-Object System.Windows.Forms.Button

            $bleave.Location = New-Object System.Drawing.Size (255,35)

            $bleave.Size = New-Object System.Drawing.Size (270,80)

            $bleave.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.5)

            $bleave.TextAlign = "MiddleCenter"

            $bleave.Text = "Rename VMDK`n(if restore VMDK only option was chosen)`nOR Copy current state to temp folder`n(if entier VM option was chosen)"

            $bleave.Add_Click({$global:x="0";$global:leave="1";$form.Close()})

            $form.Controls.Add($bleave)

 

            $Can = New-Object System.Windows.Forms.Button

            $Can.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.5)

            $Can.Location = New-Object System.Drawing.Size (238, 125)

            $Can.Size = New-Object System.Drawing.Size (75, 25)

            $Can.TextAlign = 2

            $Can.Text = "Cancel"

            $Can.Add_Click({$global:x="2";$form.Close()})

            $form.Controls.Add($Can)

 

            $form.KeyPreview = $True

            $form.Add_KeyDown({if ($_.KeyCode -eq "Escape")

{$global:x="2";$form.Close()}})

 

            $form.Topmost = $True

            $form.Add_Shown({$form.Activate()})

            [void] $form.ShowDialog()

      }

 

      Function Restore_VMDK ($vm2restore, $vmDatastore, $Folder, $myVol, $snapshot1) {

            #SnapRestore of VMDK(s)

            $form = New-Object System.Windows.Forms.Form

            $form.Text = "About to restore..."

            $form.Size = New-Object System.Drawing.Size(350,120)

            $form.StartPosition = "CenterScreen"

 

            $l1 = New-Object System.Windows.Forms.Label

            $l1.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.5)

            $l1.Location = New-Object System.Drawing.Size (0,10)

            $l1.Size = New-Object System.Drawing.Size (330,20)

            $l1.TextAlign = 2

            $l1.Text = "Click OK to restore $vm2restore from $snapshot1 snapshot."

            $form.Controls.Add($l1)

 

            $l2 = New-Object System.Windows.Forms.Label

            $l2.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.5)

            $l2.Location = New-Object System.Drawing.Size (10,30)

            $l2.Size = New-Object System.Drawing.Size (330,20)

            $l2.TextAlign = 2

            $l2.Text = "This will take some time to complete."

            $form.Controls.Add($l2)

 

            $OK = New-Object System.Windows.Forms.Button

            $OK.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.5)

            $OK.Location = New-Object System.Drawing.Size (100,50)

            $OK.Size = New-Object System.Drawing.Size (75, 25)

            $OK.TextAlign = 2

            $OK.Text = "OK"

            $OK.Add_Click({$go="1";$global:x="0";$form.Close()})

            $form.Controls.Add($OK)

 

            $Can = New-Object System.Windows.Forms.Button

            $Can.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.5)

            $Can.Location = New-Object System.Drawing.Size (175,50)

            $Can.Size = New-Object System.Drawing.Size (75, 25)

            $Can.TextAlign = 2

            $Can.Text = "Cancel"

            $Can.Add_Click({$go="0";$global:x="2";$form.Close()})

            $form.Controls.Add($Can)

 

            $form.KeyPreview = $True

            $form.Add_KeyDown({if ($_.KeyCode -eq "Escape")

{$go="0";$global:x="2";$form.Close()}})

            $form.Add_KeyDown({if ($_.KeyCode -eq "Enter")

                  {$go="1";$global:x="0";$form.Close()}})

 

            $form.Topmost = $True

            $form.Add_Shown({$form.Activate()})

            [void] $form.ShowDialog()

 

            If ($go -eq "1") {

                  If ($overwrite -eq "1") {

                        Restore-NaSnapshotFile -Path "/vol/$myVol/$myVol/$Folder/$vm2restore-flat.vmdk" -SnapName $snapshot1 -Confirm:$false

                       

                        #Do vmdk size comparison to know when to move on

                        New-PSDrive -Name "ds1" -Root \ -PSProvider VimDatastore -Datastore $vmDatastore

                        $disks_ss = Get-ChildItem ds1:\.snapshot\$snapshot1\$vm2restore | Where-Object {($_.Name -notcontains "*old") -and ($_.Name -like "*vmdk") -and ($_.ItemType -eq "File")} | Sort-Object Name

                        $disks_act = Get-ChildItem ds1:\$vm2restore | Where-Object {($_.Name -notcontains "*old") -and ($_.Name -like "*vmdk") -and ($_.ItemType -eq "File")} | Sort-Object Name

                        $diff = @(compare-object -referenceObject $disks_ss -differenceObject $disks_act -Property Length)

                        Do {

                              $disks_act = Get-ChildItem ds1:\$vm2restore | Where-Object {($_.Name -notcontains "*old") -and ($_.Name -like "*vmdk") -and ($_.ItemType -eq "File")} | Sort-Object Name

                              $diff = @(compare-object -referenceObject $disks_ss -differenceObject $disks_act -Property Length)

                        }

                        While (!($diff.Count -eq 0))

                  }

                  If ($leave -eq "1") {

                        New-PSDrive -Name "ds1" -Root \ -PSProvider VimDatastore -Datastore $vmDatastore

                        cd ds1:\$vm2restore

                        $oldvmdk = $vm2restore += "-flat.vmdk"

                        $oldvmdk1 = $vm2restore += ".old"

                        Rename-Item $oldvmdk $oldvmdk1

                        c:

                        Restore-NaSnapshotFile -Path "/vol/$myVol/$myVol/$Folder/$oldvmdk" -SnapName $snapshot1 -Confirm:$false

                       

                        #Do vmdk size comparison to know when to move on

                        New-PSDrive -Name "ds2" -Root \ -PSProvider VimDatastore -Datastore $vmDatastore

                        $disks_ss = Get-ChildItem ds2:\.snapshot\$snapshot1\$vm2restore | Where-Object {($_.Name -notcontains "*old") -and ($_.Name -like "*vmdk") -and ($_.ItemType -eq "File")} | Sort-Object Name

                        $disks_act = Get-ChildItem ds2:\$vm2restore | Where-Object {($_.Name -notcontains "*old") -and ($_.Name -like "*vmdk") -and ($_.ItemType -eq "File")} | Sort-Object Name

                        $diff = @(compare-object -referenceObject $disks_ss -differenceObject $disks_act -Property Length)

                        Do {

                              $disks_act = Get-ChildItem ds2:\$vm2restore | Where-Object {($_.Name -notcontains "*old") -and ($_.Name -like "*vmdk") -and ($_.ItemType -eq "File")} | Sort-Object Name

                              $diff = @(compare-object -referenceObject $disks_ss -differenceObject $disks_act -Property Length)

                        }

                        While (!($diff.Count -eq 0))

                  }

            }

      }

 

      Function Restore_All ($vm2restore, $vmDatastore, $Folder, $myVol, $snapshot1) {

            #SnapRestore of VMDK(s)

            $form = New-Object System.Windows.Forms.Form

            $form.Text = "About to restore..."

            $form.Size = New-Object System.Drawing.Size(350,120)

            $form.StartPosition = "CenterScreen"

 

            $l1 = New-Object System.Windows.Forms.Label

            $l1.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.75)

            $l1.Location = New-Object System.Drawing.Size (0,10)

            $l1.Size = New-Object System.Drawing.Size (330,20)

            $l1.TextAlign = 2

            $l1.Text = "Click OK to restore $vm2restore from $snapshot1 snapshot."

            $form.Controls.Add($l1)

 

            $l2 = New-Object System.Windows.Forms.Label

            $l2.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.75)

            $l2.Location = New-Object System.Drawing.Size (10,30)

            $l2.Size = New-Object System.Drawing.Size (330,20)

            $l2.TextAlign = 2

            $l2.Text = "This will take some time to complete."

            $form.Controls.Add($l2)

 

            $OK = New-Object System.Windows.Forms.Button

            $OK.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.75)

            $OK.Location = New-Object System.Drawing.Size (100,50)

            $OK.Size = New-Object System.Drawing.Size (75, 25)

            $OK.TextAlign = 2

            $OK.Text = "OK"

            $OK.Add_Click({$go="1";$global:x="0";$form.Close()})

            $form.Controls.Add($OK)

 

            $Can = New-Object System.Windows.Forms.Button

            $Can.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif",9.75)

            $Can.Location = New-Object System.Drawing.Size (175,50)

            $Can.Size = New-Object System.Drawing.Size (75, 25)

            $Can.TextAlign = 2

            $Can.Text = "Cancel"

            $Can.Add_Click({$go="0";$global:x="2";$form.Close()})

            $form.Controls.Add($Can)

 

            $form.KeyPreview = $True

            $form.Add_KeyDown({if ($_.KeyCode -eq "Escape")

{$go="'0";$global:x="2";$form.Close()}})

            $form.Add_KeyDown({if ($_.KeyCode -eq "Enter")

                  {$go="1";$global:x="0";$form.Close()}})

 

            $form.Topmost = $True

            $form.Add_Shown({$form.Activate()})

            [void] $form.ShowDialog()

           

            If ($go -eq "1") {

                  If ($overwrite -eq "1") {

                        New-PSDrive -Name "ds1" -Root \ -PSProvider VimDatastore -Datastore $vmDatastore

                        cd ds1:\$vm2restore

                        $fileList = Get-ChildItem -Name

                        c:

                        ForEach ($file in $fileList) {

                              If ($file -notcontains "*.log") {

                                    Restore-NaSnapshotFile -Path "/vol/$myVol/$myVol/$Folder/$file" -SnapName $snapshot1 -Confirm:$false

                              }

                        }

 

                        #Do vmdk size comparison to know when to move on

                        New-PSDrive -Name "ds2" -Root \ -PSProvider VimDatastore -Datastore $vmDatastore

                        $disks_ss = Get-ChildItem ds2:\.snapshot\$snapshot1\$vm2restore | Where-Object {($_.Name -notcontains "*old") -and ($_.Name -like "*vmdk") -and ($_.ItemType -eq "File")} | Sort-Object Name

                        $disks_act = Get-ChildItem ds2:\$vm2restore | Where-Object {($_.Name -notcontains "*old") -and ($_.Name -like "*vmdk") -and ($_.ItemType -eq "File")} | Sort-Object Name

                        $diff = @(compare-object -referenceObject $disks_ss -differenceObject $disks_act -Property Length -PassThru)

                        Do {

                              $disks_act = Get-ChildItem ds2:\$vm2restore | Where-Object {($_.Name -notcontains "*old") -and ($_.Name -like "*vmdk") -and ($_.ItemType -eq "File")} | Sort-Object Name

                              $diff = @(compare-object -referenceObject $disks_ss -differenceObject $disks_act -Property Length -PassThru)

                              Write-Host $diff

                        }

                        While (!($diff.Count -eq 0))

                       

                        #Remove and re-add VM to pick up changes

                        Remove-VM -VM $vm2restore -Confirm:$false

                        New-PSDrive -Name "ds3" -Root \ -PSProvider VimDatastore -Datastore $vmDatastore

                        cd ds3:\$vm2restore

                        $vmxFile = Get-Item *.vmx

                        New-VM -VMHost $esxhost -VMFilePath $vmxFile.DatastoreFullPath

                        c:

                  }

                  If ($leave -eq "1") {

                        New-PSDrive -Name "ds1" -Root \ -PSProvider VimDatastore -Datastore $vmDatastore

                        cd ds1:\$vm2restore

                        $fileList = Get-ChildItem -Name

                        mkdir temp

                        Move-Item *.* temp

                        ForEach ($file in $fileList) {

                              If ($file -notcontains "*.log") {

                                    Restore-NaSnapshotFile -Path "/vol/$myVol/$myVol/$Folder/$file" -SnapName $snapshot1 -Confirm:$false

                              }

                        }

                       

                        #Do vmdk size comparison to know when to move on

                        New-PSDrive -Name "ds2" -Root \ -PSProvider VimDatastore -Datastore $vmDatastore

                        $disks_ss = Get-ChildItem ds2:\.snapshot\$snapshot1\$vm2restore | Where-Object {($_.Name -notcontains "*old") -and ($_.Name -like "*vmdk") -and ($_.ItemType -eq "File")} | Sort-Object Name

                        $disks_act = Get-ChildItem ds2:\$vm2restore | Where-Object {($_.Name -notcontains "*old") -and ($_.Name -like "*vmdk") -and ($_.ItemType -eq "File")} | Sort-Object Name

                        $diff = @(compare-object -referenceObject $disks_ss -differenceObject $disks_act -Property Length -PassThru)

                        Do {

                              $disks_act = Get-ChildItem ds2:\$vm2restore | Where-Object {($_.Name -notcontains "*old") -and ($_.Name -like "*vmdk") -and ($_.ItemType -eq "File")} | Sort-Object Name

                              $diff = @(compare-object -referenceObject $disks_ss -differenceObject $disks_act -Property Length -PassThru)

                              Write-Host $diff

                        }

                        While (!($diff.Count -eq 0))

                       

                        #Remove and re-add VM to pick up changes

                        Remove-VM -VM $vm2restore -Confirm:$false

                        New-PSDrive -Name "ds3" -Root \ -PSProvider VimDatastore -Datastore $vmDatastore

                        cd ds3:\$vm2restore

                        $vmxFile = Get-Item *.vmx

                        New-VM -VMHost $esxhost -VMFilePath $vmxFile.DatastoreFullPath

                        c:

                  }

            }

      }

 

      Function Power_On ($vm2restore) {

            #Give option to Power VM back on

            $form = New-Object System.Windows.Forms.Form

            $form.Text = "Power VM on?"

            $form.Size = New-Object System.Drawing.Size(400,100)

            $form.StartPosition = "CenterScreen"

 

            $L_Power = New-Object System.Windows.Forms.Label

            $L_Power.Location = New-Object System.Drawing.Size(10,10)

            $L_Power.Size = New-Object System.Drawing.Size(380,20)

            $L_Power.Font = New-Object System.Drawing.Font ("Microsoft Sans Serif", 9)

            $L_Power.TextAlign = "2"

            $L_Power.Text = "Do you want to power $vm2Restore back on?"

            $form.Controls.Add($L_Power)

 

            $OK = New-Object System.Windows.Forms.Button

            $OK.Location = New-Object System.Drawing.Size(125,30)

            $OK.Size = New-Object System.Drawing.Size(75,23)

            $OK.Text = "Yes"

            $OK.Add_Click({$PowerOn="0";$global:x="3";$form.Close()})

            $form.Controls.Add($OK)

 

            $Cancel = New-Object System.Windows.Forms.Button

            $Cancel.Location = New-Object System.Drawing.Size(200,30)

            $Cancel.Size = New-Object System.Drawing.Size(75,23)

            $Cancel.Text = "No"

            $Cancel.Add_Click({$PowerOn="1";$gloabal:x="1";$form.Close()})

            $form.Controls.Add($Cancel)

 

            $form.KeyPreview = $True

            $form.Add_KeyDown({if ($_.KeyCode -eq "Enter")

{$PowerOn="0";$global:x="3";$form.Close()}})

            $form.Add_KeyDown({if ($_.KeyCode -eq "Escape")

{$PowerOn="1";$gloabal:x="1";$form.Close()}})

 

            $form.Topmost = $True

            $form.Add_Shown({$form.Activate()})

            [void] $form.ShowDialog()

            If ($PowerOn -eq "0") {

                  Start-VM $vm2restore1 -Confirm:$false

                  $Error | where { $_.Exception -is [VMware.VimAutomation.ViCore.Types.V1.ErrorHandling.VmBlockedByQuestionException] }`

                  | % { Get-VM -Id $_.Exception.VmId | Get-VMQuestion | Set-VMQuestion -Option "I copied it" -Confirm:$false}

            }

      }

 

      ## SCRIPT

      Description | Out-Null

      If ($x -eq "0") {Get_Restore_VM | Out-Null}

      If ($x -eq "0") {Compare_VMDK $Folder $snapshot1 $vm2restore | Out-Null}

      If ($x -eq "0") {Check_Power $vm2restore $orion | Out-Null}

      If ($x -eq "0") {Overwrite | Out-Null}

      If ($x -eq "0") {

            If ($VMDKonly -eq "1") {Restore_VMDK $vm2restore $vmDatastore $Folder $myVol $snapshot1 | Out-Null}

            If ($EntireVM -eq "1") {Restore_All $vm2restore $vmDatastore $Folder $myVol $snapshot1 | Out-Null}

      }

      If ($x -eq "0") {Power_On $vm2restore | Out-Null}

      If ($x -eq "3") {Remanage $vm2restore| Out-Null}

      If ($x -eq "1") {Complete | Out-Null}

      If ($x -eq "2") {Aborted}

}

Warning!

This NetApp Community is public and open website that is indexed by search engines such as Google. Participation in the NetApp Community is voluntary. All content posted on the NetApp Community is publicly viewable and available. This includes the rich text editor which is not encrypted for https.

In accordance to our Code of Conduct and Community Terms of Use DO NOT post or attach the following:

  • Software files (compressed or uncompressed)
  • Files that require an End User License Agreement (EULA)
  • Confidential information
  • Personal data you do not want publicly available
  • Another’s personally identifiable information
  • Copyrighted materials without the permission of the copyright owner

Files and content that do not abide by the Community Terms of Use or Code of Conduct will be removed. Continued non-compliance may result in NetApp Community account restrictions or termination.