Instant VM restore
This script is used to instantly restore a virtual machine from a netapp flexcloned volume
###################################################
#$filercreds is defined in profile.ps1 if you dont have it in your profile.ps1 - uncomment the following
##Run this part once
#read-host -AsSecureString | ConvertFrom-SecureString | out-file c:\filerpassword.txt
##Add this part to your profile.ps1
#$filerpassword = cat C:\filerpassword.txt | ConvertTo-SecureString
#$Filercreds = New-Object -TypeName System.Management.Automation.PScredential -argumentlist "admin" , $filerpassword
#################################################
Connect-VIServer vserver1,vserver2
$RecoveryVM = read-host "Enter the name of the VM that you want to do an instant restore"
$sanityCheck = read-host "By proceeding you will be removing" $RecoveryVM "from the invenotry and then mounting and running the VM from a flexclone - the script will then migrate the VM from the flexclone and overwrite the old production volume and dismount the flexclone - Proceed (Y/N)"
If ($sanityCheck -like "*N*")
{write-host "exiting"
pause
exit }
$recoveryVM = get-vm | Where-Object {$_.name -like $RecoveryVM}
$recoveryhost = get-vm $recoveryvm | get-vmhost
$RecoveryVMParentStorage = get-vm $RecoveryVM | get-datastore | Where-object {($_.name -notlike "*swap*") -and ($_.name -notlike "*srm*") -and ($_.name -notlike "*page*")}
If ($RecoveryVMParentStorage.count -gt 1)
{ Write-host "Attached disks span more than 1 netapp volume - you'll have to do a manual restore using SMVI"
Pause
exit
}
get-vm $recoveryvm | Shutdown-VMGuest -Confirm:$false
$i = 0
do{
$i++
Write-host "waiting for shutdown to complete"
sleep 1
$powerstate = get-vm $RecoveryVM
if ($i -gt 120){
write-host "VM is not shutting down gracefully - performing power off"
get-vm $RecoveryVM | stop-vm -Confirm:$false
}
}until($powerstate.powerstate -like "*off*")
remove-vm $recoveryvm -Confirm:$false
# Connect to the appropriate filer
if ($RecoveryVMParentStorage -like "*filera*"){
Connect-NcController namefilera -Credential $Filercreds -Vserver filera1
}
if ($RecoveryVMParentStorage -like "*filerb*"){
Connect-NcController namefilerb -Credential $Filercreds -Vserver filerb1
}
$NetappVols = get-ncvol $RecoveryVMParentStorage.name
foreach ($netappvol in $NetappVols){
$AllNetavols = get-ncvol $netappvol | Get-NcSnapshot
}
# Create a list box containing all snapshots from the volume - Partially plagerised from https://technet.microsoft.com/en-us/library/ff730949.aspx
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Windows.Forms")
[void] [System.Reflection.Assembly]::LoadWithPartialName("System.Drawing")
$objForm = New-Object System.Windows.Forms.Form
$objForm.Text = "Select a snapshot to clone"
$objForm.Size = New-Object System.Drawing.Size(300,200)
$objForm.StartPosition = "CenterScreen"
$objForm.KeyPreview = $True
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Enter")
{$x=$objListBox.SelectedItem;$objForm.Close()}})
$objForm.Add_KeyDown({if ($_.KeyCode -eq "Escape")
{$objForm.Close()}})
$OKButton = New-Object System.Windows.Forms.Button
$OKButton.Location = New-Object System.Drawing.Size(75,120)
$OKButton.Size = New-Object System.Drawing.Size(75,23)
$OKButton.Text = "OK"
$OKButton.Add_Click({$x=$objListBox.SelectedItem;$objForm.Close()})
$objForm.Controls.Add($OKButton)
$CancelButton = New-Object System.Windows.Forms.Button
$CancelButton.Location = New-Object System.Drawing.Size(150,120)
$CancelButton.Size = New-Object System.Drawing.Size(75,23)
$CancelButton.Text = "Cancel"
$CancelButton.Add_Click({$objForm.Close()})
$objForm.Controls.Add($CancelButton)
$objLabel = New-Object System.Windows.Forms.Label
$objLabel.Location = New-Object System.Drawing.Size(10,20)
$objLabel.Size = New-Object System.Drawing.Size(280,20)
$objLabel.Text = "Available Snapshots for $NetappVols.name :"
$objForm.Controls.Add($objLabel)
$objListBox = New-Object System.Windows.Forms.ListBox
$objListBox.Location = New-Object System.Drawing.Size(10,40)
$objListBox.Size = New-Object System.Drawing.Size(260,20)
$objListBox.Height = 80
foreach ($AllNetavol in $AllNetavols){
[void] $objListBox.Items.Add($AllNetavol.name )
}
$objForm.Controls.Add($objListBox)
$objForm.Topmost = $True
$objForm.Add_Shown({$objForm.Activate()})
[void] $objForm.ShowDialog()
# get the flexclone as selected by the user
$Flexclone = get-ncvol $netappvol | get-ncsnapshot | Where-object {$_.name -like $objListBox.SelectedItem}
$FlexcloneVolname = $netappvol.name+"FC_InstantRestore"
#Check if the volume is already present - if it is warn the user and exit
if (Get-Datastore | Where-Object {$_.name -like $FlexcloneVolname}) {
Clear
write-host "*** Error*** The volume" $FlexcloneVolname "already exists - check there are no VMs running on it , unmount it and rerun the script"
Pause
exit
}
# spawn the flexcloned volume from the snapshot
get-ncvol $netappvol | New-NcVolClone -CloneVolume $FlexcloneVolname -ParentSnapshot $Flexclone
# figure out which host to attach the export to , Create the export , attach the export
$recoveryhostIP = $recoveryhost | Get-VMHostNetworkAdapter
$exportIPS = $recoveryhostIP.ip | Where-Object {$_ -cmatch $RecoveryVMParentStorage.remotehost.Split(".")[2]}
Get-Ncvol $FlexcloneVolname | Mount-NcVol -JunctionPath "/$FlexcloneVolname"
Add-NcNfsExport -Path /$FlexcloneVolname -ReadWrite @($exportIPS) -Root @($exportIPS)
Sleep 30
New-Datastore -VMHost $recoveryhost -Name $FlexcloneVolname -Path /$FlexcloneVolname -NfsHost $RecoveryVMParentStorage.remotehost -Nfs
# Set up Search for .VMX Files in Datastore (partially plagerised from http://www.wooditwork.com/2011/08/11/adding-vmx-files-to-vcenter-inventory-with-powercli-gets-even-easier/)
$ds = Get-Datastore -Name $FlexcloneVolname | %{Get-View $_.Id}
$SearchSpec = New-Object VMware.Vim.HostDatastoreBrowserSearchSpec
$SearchSpec.matchpattern = "*.vmx"
$dsBrowser = Get-View $ds.browser
$DatastorePath = "[" + $ds.Summary.Name + "]"
# Find all .VMX file paths in Datastore, filtering out ones with .snapshot (Useful for NetApp NFS)
$VMXfile = $dsBrowser.SearchDatastoreSubFolders($DatastorePath, $SearchSpec) | where {($_.FolderPath -notmatch ".snapshot") -and ($_.folderpath -cmatch $RecoveryVM.name)} | %{$_.FolderPath + ($_.File | select Path).Path}
#Register the .vmx Files
New-VM -VMFilePath $VMXFile -VMHost $recoveryhost -Location $recoveryVM.Folder -ResourcePool $RecoveryVM.ResourcePool -RunAsync
#Wait until the VM has been registered on the vcentre server
do {
Write-host "confirming that " $recoveryvm "is registered on vcentre server before continuing -"
$VMwaiter = get-vm $recoveryvm -erroraction silentlycontinue
Sleep 5
}
until ($VMwaiter)
# start the VM up and answer the VM startup question
get-vm $RecoveryVM | start-vm -Confirm:$false -ErrorAction SilentlyContinue
Sleep 20
get-vm $RecoveryVM | Get-VMQuestion | Set-VMQuestion -Option button.uuid.copiedTheVM -Confirm:$false -ErrorAction SilentlyContinue
Write-host "VM has been started on flexclone Volume - beginning Storage vmotion to" $recoveryVMparentstorage " you can begin using the VM now"
#svmotion the VM back to the original location
get-vm $RecoveryVM | move-vm -Datastore $RecoveryVMParentStorage -DiskStorageFormat Thin -VMotionPriority High
#Wait for the VM to complete svmotion
do {
$VMwaiter = get-vm $recoveryvm | get-datastore | Where-object {($_.name -notlike "*swap*") -and ($_.name -notlike "*srm*")}
Write-host "waiting for VM to complete svmotioning"
sleep 10
}
until ($vmwaiter -like $RecoveryVMParentStorage)
#Trigger a SIS on the original volume
start-ncsis -path $netappvol -scan
#cleanup + remove recovery volume from ESXi Host and export & Volume from filer
Remove-Datastore -VMHost $recoveryhost -Datastore $FlexcloneVolname -Confirm:$false
#Determine the export policy Name - if its default then abort
$exportpolicyName = Get-NcVol $FlexcloneVolname | select @{n="PolicyName"; E={ $_.VolumeExportAttributes.policy}}
If ($exportpolicyName.policyname -notlike "*Default*"){
remove-ncnfsexport -paths /$FlexcloneVolname -Confirm:$false
Dismount-NcVol -Name $FlexcloneVolname -Confirm:$false
set-ncvol $FlexcloneVolname -Offline -Confirm:$false
Remove-NcVol $FlexcloneVolname -confirm:$false
get-ncexportpolicy | Where-object {$_.PolicyName -like $exportpolicyname.policyname} | Remove-NcExportPolicy -Confirm:$false
}
Else{
write-host "Trying to modify Default policy - Aborting"
Pause
}
DarraghsBlog
Thursday, September 15, 2016
Monday, August 25, 2014
Find the ILO IP of a HP ESXi Server through the CLI
Find the ILO IP of a HP ESXi Server through the CLI
cd /opt/hp/tools
./hponcfg -w /tmp/ilo_config.txt
Open /tmp/ilo_config.txt
cd /opt/hp/tools
./hponcfg -w /tmp/ilo_config.txt
Open /tmp/ilo_config.txt
Wednesday, January 29, 2014
Neatened version of snapshot reporting scrip
import-module dataontap
$HourlyResultsTooMany= @()
$HourlyResultsTooFew= @()
$HourlyResultsNone= @()
$filers = "filer1,filer2,filer3,filer4,filer5,filer6"
$filers | foreach-object {
#write-host $_
connect-nacontroller $_
$vmvols = get-NaVol | Where-Object { ($_.name -like "*vmnfs*" -or $_.name -like "*vmwaredata*") -and -not ($_.name -like "*m" -or $_.name -like "*m2" -or $_.name -like "*page" -or $_.name -like "*srmph" -or $_.name -like "*swap" -or $_.name -like "*sw" -or $_.name -like "*vdi*" -or $_.name -like "*NonProd" -or $_.name -like "*filer1syslog" -or $_.name -like "*filer2vdisys" -or $_.name -like "*filer40*") }
$vmvolc = $vmvols | measure-object
if ($vmvolc.count -gt 0) {
$vmvols | ForEach-Object {
$vmsnaps = Get-NaSnapshot $_.name | Where-Object { ($_.name -like "smvi*") -and ($_.name -like "*hourly*") -and ($_.name -notlike "*appsercvr*")} | measure-object
write-host "volume: " $_.name " Snapshots: " $vmsnaps.count
if ($vmsnaps.Count -eq 0) {
$HourlyResultsNone += New-Object psobject -Property @{
'Volume' = $_.name
}
}
if ($vmsnaps.Count -ge 25 ) {
$HourlyResultsTooMany += New-Object psobject -Property @{
'Volume' = $_.name
'No Of Snapshots' = $vmsnaps.count
}
}
if ($vmsnaps.Count -lt 24 ) {
$HourlyResultsTooFew += New-Object psobject -Property @{
'Volume' = $_.name
'No Of Snapshots' = $vmsnaps.count
}
}
}
}
}
If ( $DailyResultsNone.count -ge 0) {
Send-MailMessage -From "someone@companyname.ie" -To "someone@companyname.ie" -Subject 'Hourly Snapshot Alert , Some Volumes do not have any Hourly snapshots' -Body ( $HourlyResultsNone | Out-String )
}
If ( $DailyResultsTooFew.count -ge 0) {
Send-MailMessage -From "someone@companyname.ie" -To "someone@companyname.ie" -Subject 'Hourly Snapshot Alert , Some Volumes do not have enough Hourly snapshots' -Body ( $HourlyResultsTooFew | Out-String )
}
If ( $DailyResultsTooMany.count -ge 0) {
Send-MailMessage -From "someone@companyname.ie" -To "someone@companyname.ie" -Subject 'Hourly Snapshot Alert , Some Volumes have too many Hourly snapshots' -Body ( $HourlyResultsTooMany | Out-String )
}
Thursday, January 23, 2014
Find volumes without autodelete or autosize enabled
powershell script to loop through each of the filers looking for any VMnfs volume which did not have the autosize enabled and was not able to autogrow
import-module dataontap
$results= @()
$filers = "Filer1","Filer2","Filer3","Filer4","Filer5","Filer6"
$filers | foreach-object {
write-host $_
connect-nacontroller $_
$vmvols = get-NaVol | Where-Object { ($_.name -like "*vmnfs*" -or $_.name -like "*vmwaredata*" -or $_.name -like "*VDI*" ) -and -not ($_.name -like "*m" -or $_.name -like "*m2" -or $_.name -like "*page" -or $_.name -like "*srmph" -or $_.name -like "*swap" -or $_.name -like "*sw" -or $_.name -like "*vdi*" -or $_.name -like "*NonProd" -or $_.name -like "*filer1vmnfsvolsyslog" -or $_.name -like "*filer2vmnfsvolvdisys" -or $_.name -like "*filer3vmnfsvol0*") }
foreach ($volume in $vmvols) {
$VolumeName=$volume.name
$volumeSize=$volume.SizeTotal
$VolumeSizeAvailable=$volume.SizeAvailable
$autogrow = Get-NaVolAutosize -name $volume
$AutogrowEnabled = $autogrow.isenabled
$SnapshotAutodelete = Get-nasnapshotautodelete $volume
}
If (($AutogrowEnabled -notlike "true" ) -or ($SnapshotAutodelete[4].OptionValue -notlike "on") )
{
$results += New-Object psobject -Property @{
'Volume' = $volume
'AutogrowEnabled' = $autogrowEnabled
'SnapshotAutodelete' = $SnapshotAutodelete[4].OptionValue
}
}
}
import-module dataontap
$results= @()
$filers = "Filer1","Filer2","Filer3","Filer4","Filer5","Filer6"
$filers | foreach-object {
write-host $_
connect-nacontroller $_
$vmvols = get-NaVol | Where-Object { ($_.name -like "*vmnfs*" -or $_.name -like "*vmwaredata*" -or $_.name -like "*VDI*" ) -and -not ($_.name -like "*m" -or $_.name -like "*m2" -or $_.name -like "*page" -or $_.name -like "*srmph" -or $_.name -like "*swap" -or $_.name -like "*sw" -or $_.name -like "*vdi*" -or $_.name -like "*NonProd" -or $_.name -like "*filer1vmnfsvolsyslog" -or $_.name -like "*filer2vmnfsvolvdisys" -or $_.name -like "*filer3vmnfsvol0*") }
foreach ($volume in $vmvols) {
$VolumeName=$volume.name
$volumeSize=$volume.SizeTotal
$VolumeSizeAvailable=$volume.SizeAvailable
$autogrow = Get-NaVolAutosize -name $volume
$AutogrowEnabled = $autogrow.isenabled
$SnapshotAutodelete = Get-nasnapshotautodelete $volume
}
If (($AutogrowEnabled -notlike "true" ) -or ($SnapshotAutodelete[4].OptionValue -notlike "on") )
{
$results += New-Object psobject -Property @{
'Volume' = $volume
'AutogrowEnabled' = $autogrowEnabled
'SnapshotAutodelete' = $SnapshotAutodelete[4].OptionValue
}
}
}
Friday, October 11, 2013
Thursday, July 25, 2013
Powershell script to age out Netapp snapshots
I had a an incident where i had to recreate the SMVI jobs on one of our Filers , we have a requirement to keep 26 days of backups online.
As always space was at a premium so What i wanted to do was to delete the old version of the SMVI
Snapshot each time after the new snapshot was taken...
so i created a script which loops through decreasing the value of the number of backups we want to keep
$days = -26
for ($loops = 26;$loops -ge 0; $loops --)
{
$BackupstoKeep = (get-date).adddays($days)
Connect-nacontroller "Filer1"
Get-Navol | Get-NaSnapshot | where-object { $_.name -like "smvi_*" -and $_.created -lt $Backupstokeep } | remove-nasnapshot
Connect-nacontroller "Filer2"
Get-Navol | Get-NaSnapshot | where-object { $_.name -like "smvi_*" -and $_.created -lt $Backupstokeep } | remove-nasnapshot
$days++
Start-sleep 86400
}
I had a an incident where i had to recreate the SMVI jobs on one of our Filers , we have a requirement to keep 26 days of backups online.
As always space was at a premium so What i wanted to do was to delete the old version of the SMVI
Snapshot each time after the new snapshot was taken...
so i created a script which loops through decreasing the value of the number of backups we want to keep
$days = -26
for ($loops = 26;$loops -ge 0; $loops --)
{
$BackupstoKeep = (get-date).adddays($days)
Connect-nacontroller "Filer1"
Get-Navol | Get-NaSnapshot | where-object { $_.name -like "smvi_*" -and $_.created -lt $Backupstokeep } | remove-nasnapshot
Connect-nacontroller "Filer2"
Get-Navol | Get-NaSnapshot | where-object { $_.name -like "smvi_*" -and $_.created -lt $Backupstokeep } | remove-nasnapshot
$days++
Start-sleep 86400
}
Wednesday, July 10, 2013
Enable SSH on all hosts and set the policy to automatic
(in a non production lab obviously)First , have a look at the current state of the SSH service on all of the hosts
Get-VMHost | Get-VMHostService | Where {$_.label -like "SSH"} | select VMhost , running , policy , Label
Then start the SSH service on each of your hosts
Get-VMHost | Get-VMHostService | Where {$_.label -like "SSH"} | Start-VMHostService
Then ensure that it starts up each time on startup
Get-VMHost | Get-VMHostService | Where {$_.label -like "SSH"} | Set-VMHostService -Policy Automatic
Subscribe to:
Posts (Atom)