The following script contains a simple function to use the VMware vSphere PowerCLI to connect to a vCenter and/or ESXi 4.0 host and backup the 'firmware' - the configuration of the ESX host. I don’t think this functionality is exposed directly through the PowerCLI, so a call to the very useful Get-View function is used to get the VI SDK object to call the appropriate method.
From what I can tell all this command does is generate a config dump on the server and return the HTTP URL to access the file download, which I’m then using the .Net web client object to download the file and store as the filename returned with a unique date suffix.
This certainly isn’t original, all I did was look at the vicfg-backup.pl perl RCLI script and (badly) translate to PowerCLI from there.
#
# Description:
# Backup the firmware configuration on an ESXi 4.0 host
#
# Limitations:
# -
#
# Assumptions, this script works on the assumption that:
# The caller provides credentials with permissions to connect to the specified host
#
# Arguments:
# esxServer, the ESX host to connect to, eg. esx01
# vcServerName, The vCenter Server to connect to, eg vc01
# outputDir, The directory to write the backup file to, defaults to %temp%
# username, The username to use when connecting to the vCenter server (if specified), defaults to %username%
# password, The password to use for the connection to vCenter, secure string prompt by default
#
# Usage:
# PowerShell . .\BackupFirmware.ps1 -esxServer 'esx01'
# PowerShell . .\BackupFirmware.ps1 -esxServer 'esx01' -vcServer vc01 -u domain\username
#
# References:
# http://www.vmware.com/support/developer/vc-sdk/visdk400pubs/ReferenceGuide/vim.host.FirmwareSystem.html
#
# Changes:
# 04/07/2009, Wayne Martin, initial version
#$ErrorActionPreference = "Continue"
param (
$esxServer = "",
$vcServerName = "",
$outputDir = $env:Temp,
$username = $env:username,
$password = ""
)
if ($password -eq "" -and !($pass)) {
write-output "No password specified from the command-line"
$pass = Read-Host "Password?" -assecurestring
$credential = new-object System.Management.Automation.PSCredential($username,$pass)
}
if ($esxServer -eq "" -OR ($vcServerName -eq "" -and $esxServer -eq "")) {
Write-Output "Please specify either a standalone host, or a host and a cluster"
Exit 2
}
$viServer = $null
function BackupConfiguration([string] $vcServerName, [string] $esxServer, [string] $outputDir){
$hostSystem = get-view -ViewType HostSystem -Filter @{"Name" = $esxServer} # Find the .Net view of the specified host
$hostConfigManager = $hostSystem.get_ConfigManager() # Get the config manager
$hostfirmwareSystem = $hostConfigManager.get_firmwareSystem() # Find the MOR of the host firmware system
$hostfirmware = Get-View $hostfirmwareSystem # Get the VMware.Vim.HostFirmwareSystem object from the MOR
$backupDownload = $hostfirmware.BackupFirmwareConfiguration() # Call the backup method to generate the config bundle
$backupDownload = $backupDownload.Replace("*", $esxServer) # Replace '*' with the server name
Write-Output "Backup saved to $backupDownload on the ESX host"
$fileName = $backupDownload.SubString($backupDownload.LastIndexOf("/")+1) # Extract the filename to reuse
$fileType = $fileName.SubString($fileName.LastIndexOf(".")) # Find the extension (.tgz in this case)
$Now = [DateTime]::Now.ToString("yyyyMMddTHHmmss") # Unique identifier for the filename
$file = $fileName.SubString(0, $fileName.Length - $fileType.Length) # File name without extension
$outputFile = $outputDir + "\" + $file + "_" + $Now + $fileType # Construct the full filename path\bundle_date.tgz
$wc = new-object system.net.WebClient # use the .Net web client
$wc.DownloadFile($backupDownload, $outputFile) # Download the file from the URL returned
if (test-path -path $outputFile) { # Does the output file exist?
Write-Output "$outputFile downloaded"
} else {
Write-Output "Error: $outputFile was not downloaded from $backupDownload"
}
}
if ($vcServerName -ne "") {
$viServer = Connect-VIServer -server $vcServerName -Credential $credential
} elseif ($esxServer -ne "") {
$esxServer = Connect-VIServer -server $esxServer # connect to VC
}
$results = ""
$results = BackupConfiguration $vcServerName $esxServer $outputDir
$results
if ($vcServerName -ne "") {
Disconnect-VIServer -confirm:$false
}
Wayne's World of IT (WWoIT), Copyright 2009 Wayne Martin.
Information regarding Windows Infrastructure, centred mostly around commandline automation and other useful bits of information.
3 comments:
This was an error we made back in the 1.0 beta days, and hope to fix one day, but you actually do this using "Set-VMHostFirmware". So in other words you back up and restore using the same cmdlet. Dumb, yes. But now you know.
To Carter's point (thanks to Wayne for the original post), perhaps something like this?
$vCenterServer = 'myVCenter'
$username = $env:username
$password = read-host "Password for $username" -assecurestring
$destPath = 'c:\temp\'
connect-viserver -server $vCenterServer -credential (new-object System.Management.Automation.PSCredential($username, $password))
get-vmhost | foreach {
set-vmhostfirmware -vmhost $_.name -BackupConfiguration -DestinationPath $destPath
}
I had to add select-object -index 0 after Get-View HostSystem and Get-View HostFirmwareSystem to make it work in my environment. Without this, the commands were returning multiple objects, packaged Array[System.Object], which prevented subsequent steps from working. I also changed $Now to use current "day of week", for a quick set of 7 reusable backup files.
I hope this is correct and would appreciate any comments or problems. thank you.
Post a Comment