Change the root password in hosts and Host Profiles

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.

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.

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.

or

Or you can place the Host Profile on the pipeline.

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 !

39 Comments

    NateC

    Hi LucD,

    Any update on using the host profile script to update password for Versions 6.7 and 7?

    Thanks,

    Nate

      LucD

      Hi Nate,
      I’m afraid not.
      The structure of the HostProfile is undocumented afaik.
      I found the solution in this post via some reverse engineering, but it doesn’t seem to work anymore in more recent releases.

        NateC

        Ty for the update, bummer as we have many Profiles to update.

    Dan

    LucD – I tried using VMware’s code capture to pull the necessary code to update a test host profile root password and it appears they purposefully leave out the password portion of the code. Do you have any tips on how to accomplish this now that your code is obsolete? I’m trying to create a script to automate root password changes in our environment which includes 30+ host profiles.

      LucD

      That is correct, CodeCapture leaves out all private methods and data.

      The version I published worked for that specific vSphere version.
      It took some reverse engineering to find out how it could be done.

      And I haven’t looked if something similar is possible in more recent vSphere versions.
      Luc

    Jessie Rogers

    @LUCD

    Just curious if you have had a chance to circle back to this with regards to a 6.7 Host Profile. Here is the error I am getting. I see that they did in fact change the objects behind the host profile and it appears that the objects stop at Security as shown in my error.

    Exception setting “Security”: “Cannot convert the “System.Object[]” value of type “System.Object[]” to type “VMware.Vim.SecurityProfile”.”
    At line:1 char:1
    + $pwordspec.ApplyProfile.Security = @($secpol)
    + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo : NotSpecified: (:) [], SetValueInvocationException
    + FullyQualifiedErrorId : ExceptionWhenSetting

      Dan

      I’m wondering the same thing!

    marui

    thank you!

    marui

    Hello, Mr. LUC D! I want to modify the password of the account through the java API provided by vSphere in my project. I can’t find the corresponding API. Looking forward to your reply. thank you very much.

      LucD

      Sorry, but I don’t do Java, nor do I know anything about using the APIs from Java.

    Kane

    Hey Lucd,

    I have *tried* to get this working with newer host profiles by creating a placeholder *.Security object and then populating it appropriately.

    All I’m getting is:

    Exception calling “UpdateHostProfile” with “1” argument(s): “A general system error occurred:. Host profile update failed. Check the log files for details.”

    I’ve had a go at modifying it here: https://controlc.com/7bae9337

    Do you think this is at all possible? ie creating the object structure and attaching it before updating the profile?

    Cheers!

      LucD

      I’m afraid they changed the objects behind HostProfiles.
      They can do that because these objects are not really documented, and my method was based on reverse engineering.

      I’ll see if I can do the same for the latest version.

    Sany

    Hi LucD,
    Can we have a script to modify the Host Profile(without Reference Host) with a new port group(standard Switch) with Vlan ID ?

    How can we find out the policy ids and policy option ids ?

    Thanks,

      Michael

      This (adding port groups to a host profile) is something I am very much interested in as well. Where can we find documentation of object names for things like adding new VM port groups or datastore objects? My VMware account team has not been able to get me this answer yet, hoping LucD might have knowledge of this one… 🙂

      Thanks for the great article.

    Sany

    Hi LucD,
    Can we have a powercli to Update Host Profile ( Without Reference Host) with new port group with VLAN ID

    Robert

    Hello Lucd,

    Getting the following error on vSphere 6.

    Set-VMHostAccount At least one element in the source array could not be cast down to the destination array type

    I tried the following code but got the same error message.

    https://communities.vmware.com/thread/538292?start=0&tstart=0

    LucDCorrect Answer
    by LucD on Jun 19, 2016 10:35 PM
    Can you try like this ?

    Get-VMHost -location xxx |sort | where{$excludeServers -notcontains $_.Name.Split(‘.’)[0]} | %{
    Connect-VIServer -Server $_.Name -User root -Password $currentPswd | Out-Null
    Write-host “Connected to $_”
    Get-VMHostAccount -User root |
    Set-VMHostAccount -Password $newPswd -Confirm:$false | Out-Null
    Write-host “passwd change for root account on host to $_”
    Disconnect-VIServer -Server $_.Name -Confirm:$false
    Write-host “Disconnected from $_”
    }

    Can you please help.

    Shishir

    Hi LucD,

    I’m trying to overwrite the zebra.conf after backing it up in vShield OVA VM so that I can initialize the IP automatically. For this I’m using “Invoke-VMScript” as follows:

    Invoke-VMScript -VM $vShieldHostName -ScriptText “mv /common/configs/cli/zebra.conf /common/configs/cli/zebra.conf.bak” -ScriptType Bash -GuestUser $vShieldUser -GuestPassword $vShieldPass

    But I’m getting error “invoke-vmscript failed to authenticate with the guest operating system using the supplied credentials”. However, I’v used default credentials which should be working. Could you please help.

      LucD

      Hi Shishir,
      Do you you get the same error whatever command you try to execute inside the guest OS ?
      I assume you tested the same account with an SSH to the guest ?
      Luc

    Melvin

    Hi Luc,

    Hope you are doing well. Have been following all your post. Keep doing well.

    I would like to have a script to create an admin user across all ESXi hosts in the Vcenter other than root so that we can minimize the security threat. Can you please help me on this.

    Regards,
    Melvin

      LucD

      Hi Melvin, thanks.
      Have you already seen this thread in the VMTN PowerCLI community.
      That might be what you are looking for.

    srinivas

    I am creating a VM with Ubuntu Linux OS. After that i want to set the “root password” for Linux OS in that VM. Is there way we can do it in Powershell script.
    I am using below command to change but got error “failed to authenticate with the guest operating system using the supplied credentials”

    invoke-vmscript vm-ubuntu-scriptext “echo ‘root:newpassword’ | chpasswd” -guestuser root -guestpassword currentpassword.

    can you help on this.

    Harold

    Hi Luc,

    as also mentioned on the forum, here is some code to use in the Set-VMHostProfileExtended function:

    # Setting the DNS Host Name setting in the Host Profile
    $nwpol = New-Object VMware.Vim.ProfilePolicy
    $nwpol.Id = “HostNamePolicy”
    $nwpol.PolicyOption = New-Object VMware.Vim.PolicyOption
    $nwpol.PolicyOption.Id = “UserInputHostName”
    $spec.applyprofile.network.dnsconfig.policy = @($nwpol)

    # Setting the Domain Name and OU setting in the Host Profile
    $domain = “mydomain.hs.nl/Global/ESXiHosts”
    $domainpol = New-Object VMware.Vim.ProfilePolicy
    $domainpol.Id = “JoinedDomainPolicy”
    $domainpol.PolicyOption = New-Object VMware.Vim.PolicyOption
    $domainpol.PolicyOption.Id = “FixedJoinedDomainOption”
    $domainpol.PolicyOption.Parameter += New-Object VMware.Vim.KeyAnyValue
    $domainpol.PolicyOption.Parameter[0].Key = “joinedDomain”
    $domainpol.PolicyOption.Parameter[0].Value = $domain
    $spec.applyprofile.authentication.activedirectory.policy = @($domainpol)

    Regards,

    Harold

      LucD

      Thanks for sharing that Harold

      Sany

      How can we find out these values
      $nwpol.Id = “HostNamePolicy”
      $nwpol.PolicyOption.Id = “UserInputHostName”

      I am trying to a virtual portgroup with vlan ID to the host profile.

    snrpepie

    since in my ENV, i only deal with certain clusters withing vcenter, but i want to change the passwd on the clusters I manage.

    Can I just add this to the beginning of your code?

    There is too many nodes to add to the vmhost exclusion list as you designed.. pretty cool though.

    Get-Cluster MyCluster01,MyCluster02 |Get-VMHost | where{$excludeServers -notcontains $_.Name.Split(‘.’)[0]} | %{
    11 Connect-VIServer -Server $_.Name -User root -Password $currentPswd | Out-Null

    Kelly

    We just got enterprise plus, so we need to start off with new esxi build to make the profile or can we take existing esxi host and create the profile.
    Going forward, is there any requisites we need to be aware when changing the root password on pre-existing ESXi hosts using the host profile method. Is there a disconnect in Vcenter? Do servers need to be put in maintenance mode for systems that have HA/DRS?

    Beauvjha

    Hi LucD
    How do I import this module.
    I can’t find the following folder on my computer….
    %UserProfile%\Documents\WindowsPowerShell\Modules

    Is it something missing?

      admin

      @Beauvjha, the Set-VMHostProfileExtended is not provided as a module I’m afraid.
      You copy the code under The Host Profile, place that code in a .ps1 file, let’s say Set-VMHostProfileExtended.ps1.
      First you need to dot-source that code, so that the PowerShell engine “knows” the definition of the function.

      . ./Set-VMHostProfileExtended.ps1

      Note that there is a blank between the 2 dots.

      Now you can call this function like shown in the examples under Sample Usage.

      I hope this helps ?

    Beau

    Hi LucD
    How do I run the second script?
    When I run the command it gives “The term ‘set-vmhostprofileextended’is not recongnized as the name of a cmdlet, function….

    Harry

    Hi,
    Is there is a script preventing user with the root previlages to cahnge the password and if for any reason anyone changed it by accidentally is it possible to get an email notification to the unix admin?

    Thanks,

    Harold

    @LucD
    Super, I will keep trying myself as well. Just to get some more knowledge on this.
    And as a colleague of mine once said: there are 24 hours in one day, and than you still have the evening 🙂

    Harold

    Hi Luc,

    Great article.

    Will there be any updates on editing Host Profiles with PowerCLI?

    For instance how to update the Active Directory Domain Name policy,
    or the SNMP Agent Configuration?

    I have tried myself by using this article as an example, but without succes…

      LucD

      Thanks Harold.
      Yes, I definitely plan to do some more posts on editing Host Profiles.
      Your suggestions sound great subjects. I’ll try to post something on those.
      Sooner if I succeed in putting 36 hours in day 😉

    Kiran

    Hi Lucd,

    I have a question which may be little different from this concept. I am creating a VM with Linux OS (CentOS) in it. After that i want to set the “root password” for Linux OS in that VM.

    Is there anyway we can do it in Powershell script. Set-VM is not having any password config available. Any pointers here would be really helpful.

    – Kiran

      LucD

      @Kiran, you might look at the Invoke-VMScript cmdlet. It will allow you to launch a bash script inside the guest OS. That way you should be able to set the root password.
      And although CentOs is not on the list of supported *nix platforms, it might work. I’m sorry, I can’t test it right now, I don’t have a CentOs VM available right now.

    Natasha

    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.

      LucD

      @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.

    Robert van den Nieuwendijk

    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.

      LucD

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

Leave a Reply

Your email address will not be published. Required fields are marked *

*
*

This site uses Akismet to reduce spam. Learn how your comment data is processed.