Jump to content

Password resetting for ESXi hosts


Recommended Posts

I was recently tasked in finding a solution for resetting root passwords for 800+ VMWare ESXi hosts and if Passwordstate would be able to facilitate this. 

I initially started looking at the built-in Linux scripts which utilises SSH connections, something we have disabled for our ESXi hosts for security.

Searching through these forums I found a post where someone used PowerCLI to do the heavy lifting, but I found the post didnt quite give me everything I needed to complete the project.


Here is my attempt at demonstrating my solution, in hopes it will help someone out in the future.


Password reset and password validation scripts:

We need to talk about these custom scripts first, as we need the IDs of the script to fill in the JSON data for scripted host ingest


Password reset script:

1.    Function Set-ESXiPassword 
2.    {
3.        [CmdletBinding()]
4.        param (
5.            [String]$HostName,
6.            [String]$UserName,
7.            [String]$OldPassword,
8.            [String]$NewPassword
9.        )    
10.        try {
11.            $Connection=Connect-VIServer $HostName -User $UserName -Password $OldPassword
12.            } 
13.        catch {
14.            switch -wildcard ($error[0].Exception.ToString().ToLower())
15.            {
16.            "*incorrect user*" { Write-Output "Incorrect username or password on host '$HostName'"; break}
17.            "*" {write-output $error[0].Exception.ToString().ToLower();break}
18.            }
19.        }
20.        try {
21.            $change=Set-VMHostAccount -UserAccount $UserName -Password $NewPassword | out-string
22.            if ($change -like '*root*'){
23.            Write-Output "Success" }
24.            else { 
25.            Write-Output "Failed" }
26.              Disconnect-Viserver * -confirm:$false
27.              } 
28.        catch {
29.            switch -wildcard ($error[0].Exception.ToString().ToLower())
30.            {
31.            "*not currently connected*" {Write-Output "It wasn't possible to connect to '$HostName'";break}
32.            "*weak password*" { Write-Output "Failed to execute script correctly against Host '$HostName' for the account '$UserName'. It appears the new password did not meet the password complexity requirements on the host."; break }
33.            "*" {write-output $error[0].Exception.ToString().ToLower();break}
34.                #Add other wildcard matches here as required
35.                default { Write-Output "Got here" }
36.            }
37.            }
38.    }
40.    Set-ESXiPassword -HostName '[HostName]' -UserName '[UserName]' -OldPassword '[OldPassword]' -NewPassword '[NewPassword]'   


This utilises Set-VMHostAccount Powercli command which is  baked into an ESXi host and only requires powershell to be open from the Passwordstate webserver to the host (port 443).

The success criteria simply looks for the word root in the output, this may be foolish of me, but there isn't much of a result from the command to parse for a successful result

If the command fails it should be captured by my catch commands


Password verification script:

1.    Function Validate-ESXiPassword 
2.    {
3.        [CmdletBinding()]
4.        param (
5.            [String]$HostName,
6.            [String]$UserName,
7.            [String]$CurrentPassword
8.        )   
9.        $ErrorActionPreference = "Stop"
11.        try{   
12.        $Connection = Connect-VIServer $HostName -User $UserName -Password $CurrentPassword 
13.        if ($Connection.isconnected){
14.            Write-Output "Success" }
15.            else { 
16.            Write-Output "Failed" }
17.         }   
19.        catch 
20.        {
21.            switch -wildcard ($error[0].Exception.ToString().ToLower())
22.            {
23.            "*incorrect user*" { Write-Output "Incorrect username or password on host '$HostName'"; break
24.                                    Disconnect-VIServer $HostName -Force -Confirm:$false
25.                               }
26.            default { Write-Output "Error is: $($error[0].Exception.message)"}                   
28.            }
29.        }
30.    }
31.    Validate-ESXiPassword -HostName '[HostName]' -UserName '[UserName]' -CurrentPassword '[CurrentPassword]


Simple script with attempts to connect to a host via powercli, if there is a connection then output success.



Host/Password Entry:

All of our hosts are domain joined so host discovery was rather straightforward enough by using the built in utility in Passwordstate. Unfortunately there was no easy way to automatically discover host accounts, but since we are only dealing with Root here we can script adding of password entries.  You'll need to get your custom script IDs from the ones you created above. This is a one off script and took around one minute to add 800 hosts

Here is the script I used to add password entries:

Connect-VIServer (your vcenter server)

$hostlist = get-vmhost 
$Creds = Get-Credential
$PasswordstateUrl = 'https://passwordstateurl/winapi/passwords'
  foreach ($hostname in $hostlist) {
   Write-Host "I am working on host $($Hostname.name)"
   $jsonData = '
        "Title":"' + $($hostname.name) + '",
        "hostname":"' + $($hostname.name) + '",
        "AccountTypeID": "34", (VMWare)
        "PasswordResetEnabled": false,
        "EnablePasswordResetSchedule": true,
        "ScriptID": "28",
        "HeartbeatEnabled": true,
        "ValidationScriptID": "22",
   Write-Host  $jsondata
   $result = Invoke-Restmethod -Method Post -Uri $PasswordstateUrl -ContentType "application/json" -Body $jsonData -Credential $Creds
   Write-Host "Disconnecting vCenter"
   Disconnect-Viserver * -confirm:$false



Edited by Will
Added my Github Repository URL
Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Create New...