One type of config thats often not regularly done in the VMware world is ESXi, usually done only when the host has a software/firmware update, and then manually via SSH
For smaller environments this often doesnt crop up as an issue, but what if you have a larger environment, like 16+ hosts
Well, it becomes something you might want scheduling, or really, an easier less manual way of doing it rather than enabling SSH, running the commands, downloading the files and then disabling SSH, and a customer we have with 50+ hosts often comes to mind, when it takes a couple hours to back all of them up
So, it got me thinking, we have PowerCLI, can this be automated by simply pointing a script at the vCenter and then store them somewhere safe
Simple answer, yes, very easily, however, it does come with a single caveat, the ESXi config backup includes all running VMs, so if a restore is needed, it would need to have them removed to prevent a cluster issue, the vCenter shouldnt bring the host back in with a manual reconnect due to the certificate changes, so ensure all VMs are unregistered
The alternative is to put the host in maintenance mode first, but we dont really want that done every night
Important – By continuing you are agreeing to the disclaimer here
Installing PowerCLI
First, we need PowerShell, this is installed by default on Windows, I tested this on Server 2022/2025 and Windows 11, and the default PowerShell installations work fine, if you want to use this on Ubuntu, then you will need to install PowerShell
Ubuntu PowerShell Install
First, we need to install PowerShell, update the system packages with
sudo apt-get update
Install the pre-requisite packages with
sudo apt-get install -y wget apt-transport-https software-properties-common
Get the Ubuntu version with
source /etc/os-release
Download the repository keys with
wget -q https://packages.microsoft.com/config/ubuntu/$VERSION_ID/packages-microsoft-prod.deb
Register the Microsoft repository keys
sudo dpkg -i packages-microsoft-prod.deb
Update the package list again
sudo apt-get update
And install PowerShell
sudo apt-get install -y powershell
We can then enter PowerShell with
pwsh
From PowerShell, install PowerCLI with
Install-Module VMware.PowerCLI -Scope CurrentUser
You may get this prompt, enter Y and press Enter

And enter A and press Enter here

When its done, we can verify the version with
Get-Module -Name VMware.PowerCLI -ListAvailable
You may also want to opt in/out of the CEIP, as it flags when running with
#Set-PowerCLIConfiguration -Scope User -ParticipateInCEIP $false
User Account
Then, we want to use a dedicated account for this, as we will be putting the permissions in the script in plain text
In the vSphere UI click the three lines on the left and click Administration

Click Access Control/Roles/New

Give it a name, and select the role Host/Configuration/Firmware and click Create

Then under Single Sign On/Users And Groups, click the drop down for domain and select your vSphere domain, likely vSphere.local, mine is leaha.co.uk

Click Add

Enter the username you want, a secure password and click Add

Head to Access Control/Global Permissions and click Add

Select the esxi_config user and the ESXi Config Backup role and enable propagate to children and click ok

Script – v2.0
This script uses the credentials for the service account in plain text, hence the custom role, so the account cannot do anything else making it a lot more secure
There are a couple of bits you will need to edit
$basePath - You can set this to meet your environment
$vcUsername - This want setting to the username of the service account
$vcPassword - Set this to the service account password
$vcServer - Set this to your vCenter FQDN
In your chosen base path you will get a folder like this, using the time when the script runs

And in there will be all your config backups and a log file providing some information about what the script has been doing

# Define the base path for the backups
$basePath = "C:\ESXi-Config-Backups"
# Check if the base path exists, and create it if it doesn't
if (-not (Test-Path -Path $basePath)) {
New-Item -ItemType Directory -Path $basePath | Out-Null
Log-Message "Created base path: $basePath"
}
# Get the current date and time in a format suitable for folder names
$currentDateTime = Get-Date -Format "yyyy-MM-dd_HH-mm-ss"
# Create a single folder for the backup process using the current date and time
$backupFolderPath = Join-Path -Path $basePath -ChildPath $currentDateTime
New-Item -ItemType Directory -Path $backupFolderPath | Out-Null
# Create a log file in the backup folder
$logFilePath = Join-Path -Path $backupFolderPath -ChildPath "BackupLog.txt"
# Function to log messages to both console and file
function Log-Message {
param ([string]$Message)
# Append the message to the log file
$Message | Out-File -FilePath $logFilePath -Append
# Output to the console
Write-Output $Message
}
# Temporarily disable SSL certificate verification
$tempSSLConfigOutput = Set-PowerCLIConfiguration -InvalidCertificateAction Ignore -Confirm:$false
Log-Message "Temporarily disabled SSL certificate verification: $($tempSSLConfigOutput | Out-String)"
# Disconnect from all vCenter servers to prevent multiple connection issues
$disconnectOutput = Disconnect-VIServer -Server * -Force -Confirm:$false
Log-Message "Disconnected from vCenter servers: $($disconnectOutput | Out-String)"
# Define credentials for vCenter connection
$vcUsername = "<service-account>"
$vcPassword = "<password>"
$securePassword = ConvertTo-SecureString $vcPassword -AsPlainText -Force
$vcCredential = New-Object System.Management.Automation.PSCredential ($vcUsername, $securePassword)
$vcServer = "<vCenter-fqdn>"
# Connect to the vCenter server
$connectionOutput = Connect-VIServer -Server $vcServer -Credential $vcCredential
Log-Message "Connected to vCenter server: $($connectionOutput | Out-String)"
# Log the creation of the backup folder
Log-Message "Backup folder created: $backupFolderPath"
# Get the list of all ESXi hosts from the vCenter server
$esxiHosts = Get-VMHost
# Loop through each ESXi host and perform the backup
foreach ($esxiHost in $esxiHosts) {
# Perform the firmware backup for the current host, storing in the shared folder
$backupOutput = Get-VMHostFirmware -VMHost $esxiHost -BackupConfiguration -DestinationPath $backupFolderPath
Log-Message "Backup completed for host: $($esxiHost.Name). Files saved in: $backupFolderPath"
}
# Remove folders older than 5 minutes
$folders = Get-ChildItem -Path $basePath | Where-Object { $_.PSIsContainer -and $_.LastWriteTime -lt (Get-Date).AddMonths(-1) }
if ($folders.Count -eq 0) {
Log-Message "No old backup folders to remove."
} else {
foreach ($folder in $folders) {
Remove-Item -Recurse -Force -Path $folder.FullName
Log-Message "Removed old backup folder: $($folder.FullName)"
}
}
# Log that all backups are done and the location they are in
Log-Message "All backups completed. Files saved in: $backupFolderPath"
# Inform the user about the script log file
Log-Message "Script logs can be found at: $logFilePath"
# Re-enable SSL certificate verification
$restoreSSLConfigOutput = Set-PowerCLIConfiguration -InvalidCertificateAction Prompt -Confirm:$false
Log-Message "Re-enabled SSL certificate verification: $($restoreSSLConfigOutput | Out-String)"
Scheduling The Script
Windows
For scheduling, we will be using Task Scheduler, open it on a Windows Server

Click Task Scheduler Library and then right click it and click Create Task

Give it a name, check the radio button to run whether the user is logged in or not and check the box to not store passwords, and configure for Server 2025 on the drop down if youre using that OS, then click Triggers

Click New

Set a time to Daily and set a time to run it at and recur every day and click ok

Under actions click New

Set the program to
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
In add arguments add
-ExecutionPolicy Bypass -File “File-Path”
Eg I used
-ExecutionPolicy Bypass -File “C:\Scripts\ESXi-Config-Backupv2.ps1”
And click ok

Click Conditions and uncheck the option to only run if the computer is on AC power

Click Settings and uncheck the box to stop the task is run longer than 3 days

And click ok
Click the task and click Enable All Tasks History

Ubuntu
Once you have PowerShell install and PowerCLI you will also need to change the directory to save the configs in for the base URL from
$basePath = "C:\ESXi-Config-Backups"
To whatever you want in Linux, Eg
$basePath = "/mnt/Sol-General/Backups/ESXi-Config-Backups/"
We can schedule this with crontab with
crontab -e
Press 1 and hit enter

And at the bottom add
0 17 * * * pwsh /home/leaha/Scripts/ESXi-Config-Backupv2.ps1
Then press Ctrl + X and hit y then enter to save and exit