How to Reset ESXi Root Password Without Losing VM Configurations: A Technical Deep Dive


30 views

Many sysadmins face this nightmare scenario: inheriting ESXi hosts with lost root credentials while VMs are actively running. Unlike traditional Linux systems where single-user mode can bypass authentication, ESXi's architecture requires different approaches.

ESXi stores credentials in the state.tgz file within the /etc/shadow equivalent. The password hashing follows SHA-512 with salts, making brute-force attacks impractical. Here's a typical hash structure we might see:

root:$6$Ry9Vb7Px$QWG...hashedvalue...:15420:0:99999:7:::

While not exactly single-user mode, ESXi offers a rescue path:

  1. Boot from ESXi installer ISO
  2. Press Shift+O at boot screen
  3. Append rw to the kernel line
  4. Mount the system partition: chroot /mnt/sda5

For environments with multiple hosts, consider this PowerCLI snippet to automate the process after physical reset:

Connect-VIServer -Server esxi01 -User root -Password "newpassword"
Get-VMHost | ForEach-Object {
    $hostProfile = $_ | Export-VMHostProfile
    $hostProfile | New-VMHostProfile -Name "Backup_$($_.Name)"
}

Before any password reset, ensure VM metadata safety:

# On another accessible host:
scp -r root@problem-host:/vmfs/volumes/datastore1/*.vmx ./backup/
# Or using vSphere CLI:
vicfg-cfgbackup -s problem-host -f configBundle.tgz

For experts comfortable with hex editing:

dd if=/dev/sda5 of=state.tgz bs=1M count=10
gunzip state.tgz
tar xf state.tar
vim etc/shadow  # Edit root password line
tar cf state.tar etc/shadow
gzip state.tar
dd if=state.tgz of=/dev/sda5 bs=1M

Post-recovery, establish proper credential rotation:

# Sample Ansible playbook for password rotation:
- hosts: esxi_servers
  vars:
    new_password: "{{ vault_esxi_pass }}"
  tasks:
    - name: Change root password
      community.vmware.vmware_host_password:
        esxi_hostname: "{{ inventory_hostname }}"
        username: root
        password: "{{ current_password }}"
        new_password: "{{ new_password }}"

Finding yourself locked out of an ESXi host with no root credentials is more common than you'd think during infrastructure handovers. Unlike traditional Linux systems, ESXi doesn't support single-user mode recovery, but we have several technical approaches to regain access.

The most reliable method involves interrupting the boot process:

1. Reboot the ESXi host
2. When the bootloader appears, press Shift+O
3. Append 'rw' to the kernel command line
4. Add 'init=/bin/bash' after 'vmkernel'
5. Boot into single-user shell
6. Mount filesystems:
   mount -o remount,rw /
7. Reset password:
   passwd root
8. Reboot normally

For ESXi 6.7 and later:

1. Boot from installation media
2. At welcome screen, press Alt+F1
3. Access tech support mode:
   unsupported
4. Check disk partitions:
   ls -l /dev/disks
5. Mount system partition:
   localcli system visorfs mount
6. Edit shadow file:
   vi /etc/shadow
   (Remove the root password hash between first and second colons)

If you have another host with API access:

from pyVmomi import vim
from tools import cli

service_instance = connect.SmartConnect(
    host='vcenter.example.com',
    user='administrator@vsphere.local',
    pwd='VC_password',
    disableSslCertValidation=True)

host = service_instance.content.searchIndex.FindByIp(
    ip='192.168.1.100',
    vmSearch=False)

host.ExitMaintenanceMode_Task()
host.ReconnectHost_Task(
    cnxSpec=vim.host.ConnectSpec(
        userName='root',
        newPassword='NewPassword123'))
  • Always document password changes in your configuration management system
  • Consider implementing SSO or centralized authentication post-recovery
  • Test recovery procedures during maintenance windows
  • For clustered environments, perform changes during low-activity periods

Create a custom ISO with pre-configured credentials for emergency access:

#!/bin/bash
# Build emergency recovery ISO
mkisofs -R -o esxi-recovery.iso \
    -b isolinux.bin \
    -c boot.cat \
    -no-emul-boot \
    -boot-load-size 4 \
    -boot-info-table \
    ./custom_installer/