Home > Host Profile, password, PowerShell, root > Change the root password in hosts and Host Profiles

Change the root password in hosts and Host Profiles

January 15th, 2012 Leave a comment Go to comments

For good security measures you should change the password of your root account on your ESX(i) servers on a regular basis. Instead of logging on to each and everyone of your ESX(I) servers, you can easily automate this process.

But what about the new ESX(i) hosts you will roll out in between root password changes and where you use a Host Profile to configure these new ESX(i) hosts ? Will you need to run a script after the deployment to change the root password ?

Turns out that you can easily update  the root password in your Host Profile with the help of an SDK method.

The installed hosts

There are numerous scripts available in the blogosphere to accomplish this. But for good measure, this is one script that can do the task.

$currentPswd = "currentPassword"
$newPswd = "newPassword"

$excludeServers = "esx51","esx56"

$multiState = (Get-PowerCLIConfiguration).DefaultVIServerMode
$warnings = (Get-PowerCLIConfiguration).DisplayDeprecationWarnings
Set-PowerCLIConfiguration -DefaultVIServerMode Multiple -Confirm:$false -DisplayDeprecationWarnings:$false | Out-Null

Get-VMHost | where{$excludeServers -notcontains $_.Name.Split('.')[0]} | %{
  Connect-VIServer -Server $_.Name -User root -Password $currentPswd | Out-Null
  Write-Verbose "Connected to $_"
  Set-VMHostAccount -UserAccount root -Password $newPswd -Confirm:$false | Out-Null
  Disconnect-VIServer -Server $_.Name -Confirm:$false
}

Set-PowerCLIConfiguration -DefaultVIServerMode $multiState -DisplayDeprecationWarnings $warnings -Confirm:$false | Out-Null

Annotations

Line 1-2:  Provide the current and the new password for the root account.

Line 4: The script allows for ESX(i) hosts whose root password should not be changed to the password specified in this run of the script. These ESX(i) hosts can excluded by adding their hostname to this array.

Line 6-8: The script needs to run in Multiple mode, in other words it needs connections to multiple vSphere servers at the same time. For the run of this script I also disable the warning messages for deprecated properties, this to avoid a long list of warning messages. The script remembers the current settings before changing them.

Line 10: The script gets all the ESX(i) servers and excludes the ones we defined in the array in line 4.

Line 11-14: The script makes a connection to the ESX(i) server and changes the password of the root account.

Line 12: If you want to track the ESX(i) hosts for which the script is changing the root password, you can set the $verbosePreference variable to Continue instead of the default SilentlyContinue.

Line 17: The script restores the PowerCLI Configuration settings.

The Host Profile

When you use Host Profiles to configure your newly deployed ESX(i) servers, you will need to update the root account in those Host Profiles on a regular basis as well. That way the new ESX(i) hosts you roll out will immediately have the current root password.

function Set-VMHostProfileExtended{
<#
.SYNOPSIS  Update the root password in a Host Profile
.DESCRIPTION The function will update the root password in
  a Host Profile.
.NOTES  Author:  Luc Dekens
.PARAMETER Profile
  The Host Profile for which you want to change the root
  password. You can pass the name of the Host Profile
  or the VMHostProfile object
.PARAMETER AdminPassword
  The new root password.
.EXAMPLE
  PS> $prof = Get-VMHostProfile -Name MyProfile
  PS> Set-VMHostProfileExtended -Profile $prof -AdminPassword "abc"
#>

  param(
  [CmdletBinding()]
  [parameter(Mandatory = $true, ValueFromPipeline = $true)]
  [PSObject]$Profile,
  [string]$AdminPassword
  )

  begin{
    function Copy-Property ($From, $To, $PropertyName ="*")
    {
      foreach ($p in Get-Member -In $From -MemberType Property -Name $propertyName)
      {        trap {
          Add-Member -In $To -MemberType NoteProperty -Name $p.Name -Value $From.$($p.Name) -Force
          continue
        }
        $To.$($P.Name) = $From.$($P.Name)
      }
    }
  }

  process{
    if($Profile.GetType().Name -eq "string"){
      $Profile = Get-VMHostProfile -Name $Profile -Server $defaultVIServers[0]
    }

    $spec = New-Object VMware.Vim.HostProfileCompleteConfigSpec

    Copy-Property -From $Profile.ExtensionData.Config -To $spec

    $secpol = New-Object VMware.Vim.ProfilePolicy
    $secpol.Id = "AdminPasswordPolicy"
    $secpol.PolicyOption = New-Object VMware.Vim.PolicyOption
    $secpol.PolicyOption.Id = "FixedAdminPasswordOption"
    $secpol.PolicyOption.Parameter += New-Object VMware.Vim.KeyAnyValue
    $secpol.PolicyOption.Parameter[0].Key = "password"
    $secpol.PolicyOption.Parameter[0].Value = New-Object VMware.Vim.PasswordField
    $secpol.PolicyOption.Parameter[0].Value.Value = $AdminPassword
    $spec.ApplyProfile.Security.Policy = @($secpol)

    $Profile.ExtensionData.UpdateHostProfile($spec)

    Get-VMHostProfile -Name $Profile.Name
  }
}

Annotations

Line 26-35: The function needs to copy all the Config properties from the HostProfile to the HostProfileCompleteConfigSpec object. Instead of reinventing the wheel, I used a function called Copy-Property function from Dennis Verwiej.

Line 39-41: My simplistic Object By Name (OBN) implementation.

Line 45: The copy of the Config property to the HostProfileCompleteConfigSpec object.

Line 47-55: To the copied HostProfile configuration the script adds the AdminPasswordPolicy definitions.

Line 57: The HostProfile is updated with the UpdateHostProfile method.

Line 59: To emulate the behaviour of the Set-VMHostProfile cmdlet, the function places the updated VMHostProfile object on the pipeline.

Sample usage

The function to update the Host Profile can be called with the Host Profile as a parameter.

$hostProf = "MyProfile"
$newProf = Set-VMHostProfileExtended -Profile $hostProf -AdminPassword "secret"

or

$hostProf = Get-VMHostProfile -Name MyProfile
$newProf = Set-VMHostProfileExtended -Profile $hostProf -AdminPassword "secret"

Or you can place the Host Profile on the pipeline.

Get-VMHostProfile -Name MyProfile | Set-VMHostProfileExtended -AdminPassword "secret"

Notice that I called the function Set-VMHostProfileExtended. The reason for that is that one can update several other settings in a Host Profile this way. I’ll probably add some other settings to the function in a later stage.

Enjoy !

  1. Natasha
    February 7th, 2012 at 18:14 | #1

    I’m assuming that the first script requires a connect-viserver line at the beginning. Or do I need to modify line 11? I’m new to powershell.

    • February 7th, 2012 at 18:59 | #2

      @Natasha, the first script needs indeed a Connect-ViServer to the vCenter when you run it.
      The script will then connect to each ESX(i) host (line 11) to update the password. For that you will need to update the variable in line 1. Line 2 is of course the new password.

  2. January 16th, 2012 at 09:18 | #3

    There is a mismatch between the line numbering of the second script and the annotations. E.g. Line 0-19 should be Line 26-35.

    You probably added the comment at the beginning of the function after writing the annotations section.

    • January 16th, 2012 at 09:24 | #4

      Thanks for catching that one Robert.
      I corrected the line numbering

  1. No trackbacks yet.