VMware Cloud Community
tolstoy143
Enthusiast
Enthusiast

PowerCLI Script to rotate root password on managed ESXi (5.0) hosts

While I borrowed a bit from previous solutions I hacked out the following which I have tested against three speparate environments.  Basically this script will query against the connect vCenter server for all managed hosts, then ask the user for the existing password as well as the new.  All hosts ahould have the same existing password.

If necessary, it will disable Lockdown mode temporarily to connect directly before it chanes the password, then set it back.  I advise adding transcript stanzas to maintain an audit, but that code does not exist here.

Any suggestions on how it might be improved are very welcome, but it works for me as it exists.

# VMware PowerCLI 5.0

# esxi5-root_push.ps1
# Version 1.0

# 23 July 2012
# Justin Mercier

# justin AT justinmercier.com
# It is designed to assist with the rotation of admin passwords on
# ESXi hosts managed by vCenter.

# This script is intended for use with VMware vCenter Server 5.0 Update01
# against similarly versioned hosts.  You MUST know the existing root password
# and all hosts should currently have the same password or this script will
# fail on those hosts.

# You first MUST be logged into vCenter using Connect-VIServer or this script will fail
# with spectacular verbosity; it does not attempt to connect automatically.

# It will then prompt for the existing and new passwords and connect to each managed
# host as the root user using the provided password and reset it with the new password.

# All passwords are stored as encrypted strings in memory and destroyed upon exit.


# Print a warning preamble
Write-Host "The following utility will cycle through all hosts managed by a vCenter server and reset its root password."

Write-Host "`nHosts will be temporarily taken out of lockdown mode while this is performed."

Write-Host "`nYou must first be connected to vCenter before proceeding.`n"

Read-Host "Please press Enter if you are ready to proceed, or CTRL-C to abort"


# Prompt for the exiting root credential
$oldrootPassword = Read-Host "Enter old root password" -AsSecureString
$oldrootCredential = new-object -typename System.Management.Automation.PSCredential -argumentlist "root",$oldrootPassword

# Prompt for new root credential
$newrootPassword = Read-Host "Enter new root password" -AsSecureString
$newrootCredential = new-object -typename System.Management.Automation.PSCredential -argumentlist "root",$newrootPassword
$newrootPassword2 = Read-Host "Confirm new root password" -AsSecureString
$newrootCredential2 = new-object -typename System.Management.Automation.PSCredential -argumentlist "root",$newrootPassword2

# A match value that exludes certain hosts.  Use with caution (i.e. 'esx' will match tes-esx01 as well as esx-srv1 , so be specific)
# THIS IS ONLY PLARTIALLY TESTED!!!
$excludeServers =

# Save the multi-session state and warnings for later restoration (to avoid settings clobber) and set to verbose multimode.
$multiState = (Get-PowerCLIConfiguration).DefaultVIServerMode
$warnings = (Get-PowerCLIConfiguration).DisplayDeprecationWarnings
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -Confirm:$false -DisplayDeprecationWarnings:$false | Out-Null

# Compare new passwords to check against fat finger and general stupidity, if it expressly matches then proceed.
If ($newrootCredential.GetNetworkCredential().Password -ceq $newrootCredential2.GetNetworkCredential().Password) {

    # Loop through all known hosts on this vCenter Server.  If Lockdown mode is enabled lets disable it.
    Get-VMHost | where{$excludeServers -notcontains $_.Name.Split('.')[0]} | %{
        $fHost = get-vmhost $_.Name | Get-View
        $isLockdownEnabled = (get-vmhost $_.Name).ExtensionData.config.adminDisabled
        if ($isLockdownEnabled) {
            Write-Host $_.Name "is in lockdown mode.  Temporarily disabling it."
            $fHost.ExitLockdownMode()
            Sleep -Seconds 1
        }
   
    # There is by now NO WAY my logic is faulty, so lets connect to the ESXi host, shall we?
    Connect-VIServer -Server $_.Name -User root -Password $oldrootCredential.GetNetworkCredential().Password -ErrorAction SilentlyContinue -ErrorVariable ConnectError | Out-Null

    # Ok, so maybe there was an error in my logic.  Let's try and handle it more gracefully than Tom on Oprah's couch.
    If ($ConnectError -ne $Null) {
         Write-Host "ERROR: Failed to connect to ESX server (maybe wrong password):" $_
    } Else {
        Write-Verbose "Connected to $_, attempting to set root password"
        # Our stored credential is only valid while this thread lives, so we ask it to translate back into humam readability
        # before the tender stroke of time has passed us by.
       
        # We then pass this secured string to the host, asking it very nicely to please, please change the root pw.
         Set-VMHostAccount root -Password $newrootCredential2.GetNetworkCredential().Password | Out-Null
        if (!$?) {
            Write-Host "Error updating password:" $_
        } Else {
            Write-Host "Update Successful:" $_
        }
       
        # Disconnect from the ESXi host
        Disconnect-VIServer -Server $_.Name -Confirm:$false
    }
   
    # If hypervisor was running in Lockdown Mode, re-enable it.  
    if ($isLockdownEnabled) {
        $fHost.EnterLockdownMode()
    }  
}

# Restore previous multimode and warning settings.
Set-PowerCLIConfiguration -DefaultVIServerMode $multiState -DisplayDeprecationWarnings $warnings -Confirm:$false | Out-Null

}
Else {
# Let the user know they mistyped.
Write-Host "ERROR: New root passwords do not match. Exiting..."
}

"Quos vult perdere dementat" Leo Tolstoy, "War and Peace"
0 Kudos
2 Replies
Gleed
VMware Employee
VMware Employee

Have you considered using a Host Profile to manage your ESXi host root passwords?

0 Kudos
chjones
Enthusiast
Enthusiast

Thanks for this script, looks good. Will give it a try.

Host Profiles is the preferred way I'd like to use, but that requires Enterprise Plus licencing on all the hosts, and that just isnt feasible in all environments.

0 Kudos