Bulk password change on ESX hosts

Here is an script to make life a little easier when doing bulk updates to a password for an account as long as the account has a common password on the different hosts.

The script has some documentation in it so make sure to use Get-Help to find more detail.

Get-Help .\Set-VMHostAccountPassword.ps1 -Examples

NAME
C:\Set-VMHostAccountPassword.ps1

SYNOPSIS
Sets the password for the given account across one or more VMware hosts.

————————– EXAMPLE 1 ————————–

C:\PS>.\Set-VMHostAccountPassword.ps1 -VMHost “host1″,”host2″,”host3″ -Credential (Get-Credential)

Get prompted for all credential information so it is not on the command line.

————————– EXAMPLE 2 ————————–

C:\PS>”host1″,”host2″,”host3” | .\Set-VMHostAccountPassword.ps1 -Credential (Get-Credential)

Use pipelining.

————————– EXAMPLE 3 ————————–

C:\PS>.\Set-VMHostAccountPassword.ps1 -Credential $myCred -accountName root -newPassword Secret123 -VMHost “host1″,”host2″,”host3” -testConnection

Specify everything on the command line.

Here is the script.

<#
 
.SYNOPSIS
 
Sets the password for the given account across one or more VMware hosts.
 
.EXAMPLE
 
.\Set-VMHostAccountPassword.ps1 -VMHost "host1","host2","host3" -Credential (Get-Credential)
 
Get prompted for all credential information so it is not on the command line.
 
.EXAMPLE
 
"host1","host2","host3" | .\Set-VMHostAccountPassword.ps1 -Credential (Get-Credential)
 
Use pipelining.
 
 
.EXAMPLE
 
.\Set-VMHostAccountPassword.ps1 -Credential $myCred -accountName root -newPassword Secret123 -VMHost "host1","host2","host3" -testConnection
 
Specify everything on the command line.
 
#>
 
PARAM 
(
    [parameter(Mandatory=$true,
    ValueFromPipeline=$true,
    HelpMessage="An array of VM host names.")]
    [String[]]$VMHost,
 
    [parameter(Mandatory=$false,
    HelpMessage="The credential used to connect to the host.")]
    [System.Management.Automation.PSCredential]$credential,
 
    [parameter(Mandatory=$false,
    HelpMessage="The account whose password will be changed.")]
    [String]$accountName,
 
    [parameter(Mandatory=$false,
    HelpMessage="The new password for the account.")]
    [String]$newPassword,
 
    [parameter(Mandatory=$false,
    HelpMessage="Do a post-change connection test to validate the password.")]
    [switch]$testConnection
)
 
BEGIN
{
    # Provide param prompting. This is a workaround for the multiple prompting that
    # happens if this were done in the PARAM block.
    if (!$credential)
    {
        $myCredential = Get-Credential
    }
    else
    {
        $myCredential = $credential
    }
 
    if (!$accountName)
    {
        $myAccountName = Read-Host "Account to change:"
    }
    else
    {
        $myAccountName = $accountName
    }
 
    if (!$newPassword)
    {
        $myNewPassword = Read-Host "New password:"
    }
    else
    {
        $myNewPassword = $newPassword
    }
}
 
PROCESS
{
    foreach ($h in $VMHost)
    {
        "Changing the password for {0} on {1}." -f $myAccountName, $h
        $connection = Connect-VIServer -Server $h -Credential $myCredential -ErrorAction SilentlyContinue
 
        if (!$connection)
        {
            "ERROR: Unable to connect to {0} to change the password." -f $h
            continue
        }
 
        # Do the actual work of changing the password.
        $accountError = $false
        $account = Get-VMHostAccount $myAccountName -ErrorAction SilentlyContinue
        if (!$account)
        {
            "ERROR: The account {0} on {1} could not be found." -f $myAccountName, $h
            $accountError = $true
        }
        else
        {
            $account = $account | Set-VMHostAccount -Password $myNewPassword -ErrorAction SilentlyContinue
            if (!$account)
            {
                "ERROR: The password for account {0} on {1} could not be set." -f $myAccountName, $h
                $accountError = $true
            }
        }
        Disconnect-VIServer $connection -Confirm:$false
 
        # If there was a problem with the account, move to the next host.
        if ($accountError)
        {
            continue
        }
 
        # Test the connection using the new password if requested.
        if ($testConnection)
        {
            "Testing the password for {0} on {1}." -f $myAccountName, $h
            $connection = Connect-VIServer -Server $h -User $myAccountName -Password $myNewPassword -ErrorAction SilentlyContinue
            if (!$connection)
            {
                Write-Error ("Unable to verify the password for {0} on {1}." -f $myAccountName, $h)
                continue
            }
 
            "Password changed for {0} on {1}." -f $myAccountName, $h
            Disconnect-VIServer $connection -Confirm:$false
        }
    }
}

Leave a Comment

Your email address will not be published.