6 Replies Latest reply on Nov 20, 2019 11:47 PM by ganapa2000

    Change Passwords On All ESXi Hosts

    gashbaugh Lurker



      Sorry for the noob questions, I"m slowly learning, all the help I can get helps.


      I found the below script below, but there are a couple of things I want to do with this. Hopefully, they work without me having to modify any security settings in vCenter on the ESXi hosts. I simply want to run these simply at PowerCLI prompt without doing too much else, except modifying the script as needed. I just want to type in > ./script.ps1 and have it work.


      1. Since this is just a function, I want to add in the ability to add in connecting to three different hosts, and then just having the script run through all the hosts it finds via Get-VMhosts. I'd all like some verbose or write-output that shows that each host was changed successfully.

      2. I want to do the same thing as above, except rather than running and changing every host found within Get-VMhosts, I want to specify the exact hosts I want to change. Again, I'd like some verbose or write-output that shows that each host was changed successfully.


      I'm still learning PowerCLI / Powershell as much as possible, but any type of scripting or programming has new been my strong suite. This is a function I need to complete for work, so if anyone can help me, I'd appreciate it greatly. I definitely need to read more Powershell books in general and follow that up with PowerCLI, but my days are filled with so many tasks I have a hard time breathing. There is definitely no way I can log into each host manually and change the password, which has been required to a recent audit.


      I don't know how to integrate the vCenter connections. I'm guessing this needs to be assigned to a variable somehow. But if not, even better. Can it just be added to the top of the script, or does it need to be integrated within the script somehow. If anyone can help me with items one and two, that would be a blessing. #2 script is basically for testing, and the #1 script is just so I can let it rip and change all the passwords at once.


      Connect-VIServer = vcenter1, vcenter2, vcenter 3


      I figure for a lot of the pros here, this will be fairly simple. From my research, searching around the web, this seems to be one of the more popular scripts floating around for mass changes of ESXi host root passwords. Howerver, if you have a better way to do it based on what I described below, by all means, let me know. Thank you in advance!




      Function Set-ESXPassword {





          Reset the password of your ESXi hosts version 6.0 or later.






          Resets the root password (or any users) of ESXi hosts that are connected to vCenter.

          Simply supply a list of ESXi hosts, and a new password.

          If the script does not reset any passwords, verify that your password meets the complexity requirement of the ESXi host.

          The password can either be a clear text string, or a PSCredential Object. This makes it more easy to script and automate.


          .PARAMETER VMHosts

          One or more objects returned by Get-VMHost. The list can be piped into the function.



          .PARAMETER NewCredential

          Can be a PSCredential object or a password string. If using a password string then the username is always 'root'.






          Set-ESXPassword -VMHosts (Get-VMHost) -NewCredential "NewP@ss0rd!"

          Resets the root password of all hosts to NewP@ssw0rd!






          Get-Cluster "Acme" | Get-VMHost | Set-ESXPassword

          This would get all the servers from a clustered named "Acme" and prompt you for the user and new password.






          $MySecurePassword = Get-Credential;  Set-ESXPassword (Get-VMHost -Name "Lockedout.local") $MySecurePassword

          This example uses a PSCredential object to reset the password of the server named Lockedout.local










              [Parameter(Mandatory=$True, Position=0, ValueFromPipeline=$True)]$VMHosts,


              [ValidateScript({$_.GetType().Name -eq "String" -or $_.GetType().Name -eq "PSCredential"})]$NewCredential


          Begin {

              Write-Verbose ((Get-Date).ToString() + "`t" + ($MyInvocation.MyCommand) + "`tStarted execution")



              If (-Not $PSBoundParameters.ContainsKey('NewCredential')) {

                  $NewCredential = Get-Credential -UserName "root" -Message "Enter an existing ESXi username (not vCenter), and what you want their password to be reset to." -ErrorAction STOP

              } ElseIf ($NewCredential.GetType().Name -ne "PSCredential") {

                  # Convert plain text password to PS Credential object so code path is identical.

                  $NewCredential = New-Object System.Management.Automation.PSCredential ("root", (ConvertTo-SecureString $NewCredential -AsPlainText -Force)) -ErrorAction STOP



          Process {

              Foreach ($VMHost in $VMHosts) {

                  $esxcli = get-esxcli -vmhost $VMHost -v2 #Gain access to ESXCLI on the host.

                  $esxcliargs = $esxcli.system.account.set.CreateArgs() #Get Parameter list (Arguments)

                  $esxcliargs.id = $NewCredential.UserName #Specify the user to reset

                  $esxcliargs.password = $NewCredential.GetNetworkCredential().Password #Specify the new password

                  $esxcliargs.passwordconfirmation = $NewCredential.GetNetworkCredential().Password

                  Write-Host ("Resetting password for: " + $VMHost) #Debug line so admin can see what's happening.

                  $esxcli.system.account.set.Invoke($esxcliargs) #Run command, if returns "true" it was successful.



          End {

              Write-Verbose ((Get-Date).ToString() + "`t" + ($MyInvocation.MyCommand) + "`tFinished execution")



        • 1. Re: Change Passwords On All ESXi Hosts
          scott28tt Champion
          Community WarriorsVMware EmployeesUser Moderators

          Moderator note: Moved to the PowerCLI area

          • 2. Re: Change Passwords On All ESXi Hosts
            LucD Guru
            vExpertUser ModeratorsCommunity Warriors

            You could do something like this.

            Depending if the value in $esxName is an '*' or a collection of names, you will be targetting all or a specific set of ESXi nodes.
            Just update the values assigned to the variable, and comment/uncomment the required option.


            $vcNames = 'vc1','vc2','vc3'

            $newPswd = 'VMware1!'

            # If targetting all ESXi nodes

            $esxName  = '*'

            # If targetting specific ESXi nodes

            #$esxName = 'esx1','esx2','esx3'

            Connect-VIServer -Server $vcNames


            Get-VMHost -Name $esxName | ForEach-Object -Process {

                Set-EsxHost -NewCredential $newPswd


            • 3. Re: Change Passwords On All ESXi Hosts
              gashbaugh Lurker

              Can I ask a follow-up question?


              If I want to update hosts by vCenter, by cluster name, how could I do that? I don't want to do everything in a rush.


              Thank you so much!

              • 4. Re: Change Passwords On All ESXi Hosts
                ganapa2000 Hot Shot



                I am getting the below error, when I tried the script.


                Set-VMHost : A parameter cannot be found that matches parameter name 'NewCredential'.

                At D:\change_esxi_password.ps1:73 char:16

                +     Set-VMHost -NewCredential $newPswd

                +                ~~~~~~~~~~~~~~

                    + CategoryInfo          : InvalidArgument: (:) [Set-VMHost], ParameterBindingException

                    + FullyQualifiedErrorId : NamedParameterNotFound,VMware.VimAutomation.ViCore.Cmdlets.Commands.SetVMHost

                • 5. Re: Change Passwords On All ESXi Hosts
                  LucD Guru
                  Community WarriorsvExpertUser Moderators

                  You could do something like this


                  $vcNames = 'vc1','vc2','vc3'

                  $newPswd = 'VMware1!'

                  $clusterName = 'Cluster'

                  Connect-VIServer -Server $vcNames

                  Get-Cluster -Name $clusterName | Get-VMHost -Name $esxName | ForEach-Object -Process {

                      Set-EsxHost -NewCredential $newPswd


                  • 6. Re: Change Passwords On All ESXi Hosts
                    ganapa2000 Hot Shot



                    I am getting the below error


                    Set-EsxHost : The term 'Set-EsxHost' is not recognized as the name of a cmdlet, function, script file, or operable program. Check the spelling of the name, or if a path was included, verify

                    that the path is correct and try again.

                    At D:\change_esxi_password2.ps1:8 char:5

                    +     Set-EsxHost -NewCredential $newPswd

                    +     ~~~~~~~~~~~

                        + CategoryInfo          : ObjectNotFound: (Set-EsxHost:String) [], CommandNotFoundException

                        + FullyQualifiedErrorId : CommandNotFoundException



                    I am using


                    PS D:\> Get-PowerCLIVersion

                    WARNING: The cmdlet "Get-PowerCLIVersion" is deprecated. Please use the 'Get-Module' cmdlet instead.


                    PowerCLI Version


                       VMware PowerCLI 11.5.0 build 14912921


                    Component Versions


                       VMware Common PowerCLI Component 11.5 build 14898112

                       VMware Cis Core PowerCLI Component PowerCLI Component 11.5 build 14898113

                       VMware VimAutomation VICore Commands PowerCLI Component PowerCLI Component 11.5 build 14899560