tlstout
Contributor
Contributor

Root Password Change Script

Jump to solution

I discovered this fine script that bradley4681 posted over at http://communities.vmware.com/thread/172220?start=15&tstart=0. For some reason I am unable to reply to that thread, so I thought I would ask my question here.

Even though this script works fantastic, I would like for the script to prompt me for the current root password and for the new root password, and then use that input to change the root password on each host listed in the hosts.txt file.

Is this possible? I would rather not edit a script file and enter the password data every month to change the passwords.

#Starts a transcript of the script output
Start-Transcript -path "x:\log.txt"

#Gets a list of hosts to change passwords for, make sure there is no break after the last host
$vihosts = Get-Content "x:\hosts.txt"

#Starts Error Report recording
$errReport =@()

#Current Hosts Root Password
$rootpswd = 'currentpassword'
#New Root Password
$newpass = 'newpassword'

#Starts the process and loops until the last host in the host.txt file is reached
foreach ($singleViserver in $vihosts){

	#Connects to each host from the hosts.txt list and also continues on any error to finish the list
	Connect-VIServer $singleViserver -User root -Password $rootpswd -ErrorAction SilentlyContinue -ErrorVariable err
	
	
	$errReport += $err
	if($err.Count -eq 0){
	#Sets the root password
	Set-VMHostAccount -UserAccount root -Password $newpass
	}
	
	#Disconnects from each server and suppresses the confirmation
	Disconnect-VIServer -Confirm:$False
	$errReport += $err
	$err = ""
}

#Outputs the error report to a CSV file, if file is empty then no errors.
$errReport | Export-Csv ".\Pass-HostReport.csv" -NoTypeInformation

#Stops the transcript
Stop-Transcript

1 Solution

Accepted Solutions
LucD
Leadership
Leadership

Sure, you can replace these lines

...
#Current Hosts Root Password
$rootpswd = 'currentpassword'
#New Root Password
$newpass = 'newpassword'
...

with this

...
#Current Hosts Root Password
$rootpswd = Read-Host -Prompt "Old root password"
#New Root Password
$newpass = Read-Host -Prompt "New root password"
...

If you want to secure this you can add the -AsSecureString parameter on the Read-Host cmdlet.

But watch out when you want to use the passwords later on in the script.

See

____________

Blog: LucD notes

Twitter: lucd22


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

View solution in original post

0 Kudos
23 Replies
LucD
Leadership
Leadership

Sure, you can replace these lines

...
#Current Hosts Root Password
$rootpswd = 'currentpassword'
#New Root Password
$newpass = 'newpassword'
...

with this

...
#Current Hosts Root Password
$rootpswd = Read-Host -Prompt "Old root password"
#New Root Password
$newpass = Read-Host -Prompt "New root password"
...

If you want to secure this you can add the -AsSecureString parameter on the Read-Host cmdlet.

But watch out when you want to use the passwords later on in the script.

See

____________

Blog: LucD notes

Twitter: lucd22


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
tlstout
Contributor
Contributor

LucD:

Thanks so much for the incredibly fast and correct response! One question though... what do you mean by "But watch out when you want to use the passwords later on in the script"?

Thanks,

Terry

0 Kudos
LucD
Leadership
Leadership

If you use the -AsSecureString parameter, the passwords will not be string objects anymore but securestring objects.

And since the Set-VMhostaccount cmdlet wants a string object with the -Password parameter, you will have to convert the securestring objects first.

The method how to do this, is described in the thread I referred to.

____________

Blog: LucD notes

Twitter: lucd22


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

tlstout
Contributor
Contributor

Got it! Thanks for all your help!

0 Kudos
pravin_utekar12
Contributor
Contributor

Hello All,

please suggest me the way how can i schedule this script.I want the password should change automatically bimonthly.

Thanks

PravinU

0 Kudos
LucD
Leadership
Leadership

You can schedule the script through the Windows Task Scheduler.

See Alan's Running a PowerCLI Scheduled task


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
pravin_utekar12
Contributor
Contributor

Hi Lucd,

I am a beginner for Powercli scrpting so Before implementing this script for whole infrastructure. I want to test it for one esxi host please suggest me the changes.

also tell me how can i Master the scripting suggest me how can i learn the basic......

Thanks

PravinU.

0 Kudos
LucD
Leadership
Leadership

The list with the hosts is read from an external text file

$vihosts = Get-Content "x:\hosts.txt"

If you only put 1 ESXi servername in the file, the script will only do the changes on that 1 host.

There are several ways of learning PowerCLI and PowerShell

There are a number of links in my My PS library post.

Josh also has some good links in his Resources for Getting Started with #PowerCLI Automation post


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

pravin_utekar12
Contributor
Contributor

Hey Thanks LucD

For the quick reply  I will do the changes that u have suggested and will test the script and will let u know.

Thanks

PravinU.

0 Kudos
pravin_utekar12
Contributor
Contributor

Hello Lucd,

I find below script on community but having problem that I am not able to identify how I can change the password for one vm so I am stuck and I dont want to take risk of changing the password of all the host. So please suggest me th e changes in below script.

#Read in old passwords, masked

$oldpw = read-host -prompt "Enter the current root password" -AsSecureString

$newpw = read-host -prompt "Enter the desired new root password" -AsSecureString

#Decrypting for actual use

$oldpw = [System.Runtime.InteropServices.marshal]::PtrToStringAuto([System.Runtime.InteropServices.marshal]::SecureStringToBSTR($oldpw))

$newpw = [System.Runtime.InteropServices.marshal]::PtrToStringAuto([System.Runtime.InteropServices.marshal]::SecureStringToBSTR($newpw))

#Get list of ESXi hosts

$vCenter = Read-host -prompt "Enter the vCenter hostname:"

write-host "Prompting for credentials and connecting to vCenter..."

connect-viserver -server $vCenter -Credential (Get-Credential)

$hosts = @()

write-host "Querying for ESXi hosts..."

#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

# Host selection section

# Uncomment only one Get-VMHost line

#!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

#Only ESXi hosts

Get-VMHost | sort | Where {$_.State -eq "Connected" -or $_.State -eq "Maintenance"} | Get-View | Where {$_.Summary.Config.Product.Name -match "i"} | % { $hosts+= $_.Name }

#All hosts

#Get-VMHost | sort | Where {$_.State -eq "Connected" -or $_.State -eq "Maintenance"} | % { $hosts+= $_.Name }

#All vSphere hosts (>= version 4.0.0)

#Get-VMHost | sort | Where {($_.State -eq "Connected" -or $_.State -eq "Maintenance") -and $_.version -ge '4.0.0'} | % { $hosts+= $_.Name }

Disconnect-VIServer -confirm:$false

#Connect to each ESXi host and change pw

foreach ($vmhost in $hosts) {

    write-host "Connecting to $vmhost..."

    connect-viserver -server $vmhost -user root -password "$oldpw"

    write-host "Changing root password on $vmhost..."

    Set-VMHostAccount -UserAccount root -password "$newpw"

    Disconnect-VIServer -confirm:$false

}

0 Kudos
LucD
Leadership
Leadership

Not sure I'm getting the question I'm afraid.

That script is intended to change the password on ESXi hosts, not on vm


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
pravin_utekar12
Contributor
Contributor

Hi Lucd,

I want to check it for single host. By mistake I mentioned the vm.

Please help me with this..

Thanks

PravinU

0 Kudos
pravin_utekar12
Contributor
Contributor

Hi LucD,

I am using the below script and its working properly. But want some changes in the script which are aws follows

1 First thing I want to schedule this script and I dont want to put the credentials every time I want the credentials to be read form the text file. I tried my self but no luck please suggest me the changes.

Thanks

PravinU.

Script which is running properly.

# This script changes the root password on all ESX hosts in the esxservers.txt textfile

# Get old root credential

$oldrootPassword = Read-Host "Enter old root password" -AsSecureString

$oldrootCredential = new-object -typename System.Management.Automation.PSCredential -argumentlist "root",$oldrootPassword

# Get new root credential

$newrootPassword = Read-Host "Enter new root password" -AsSecureString

$newrootCredential = new-object -typename System.Management.Automation.PSCredential -argumentlist "root",$newrootPassword

$newrootPassword2 = Read-Host "Retype new root password" -AsSecureString

$newrootCredential2 = new-object -typename System.Management.Automation.PSCredential -argumentlist "root",$newrootPassword2

# Compare passwords

If ($newrootCredential.GetNetworkCredential().Password -ceq $newrootCredential2.GetNetworkCredential().Password) {

    # Create new root account object

    $rootaccount = New-Object VMware.Vim.HostPosixAccountSpec

    $rootaccount.id = "root"

    $rootaccount.password = $newrootCredential.GetNetworkCredential().Password

    $rootaccount.shellAccess = "/bin/bash"

    # Get list of Host servers from textfile to change root password on

    Get-Content C:\host.txt | %{

        Connect-VIServer $_ -User root -Password $oldrootCredential.GetNetworkCredential().Password -ErrorAction SilentlyContinue -ErrorVariable ConnectError | Out-Null

        If ($ConnectError -ne $Null) {

            Write-Host "ERROR: Failed to connect to ESX server:" $_

        }

        Else {

            $si = Get-View ServiceInstance

            $acctMgr = Get-View -Id $si.content.accountManager

            $acctMgr.UpdateUser($rootaccount)

            Write-Host "Root password successfully changed on" $_

            Disconnect-VIServer -Confirm:$False | Out-Null

        }

    }

}

Else {

Write-Host "ERROR: New root passwords do not match. Exiting..."

}

and changes I tried but no luck

# This script changes the root password on all ESX hosts in the esxservers.txt textfile

# Get old root credential

$oldpass = Get-Content "C:\oldpass.txt"

$oldrootPassword =  $_oldpass -AsSecureString

$oldrootCredential = new-object -typename System.Management.Automation.PSCredential -argumentlist "root",$oldrootPassword

# Get new root credential

$newpass = Get-Content "C:\newpass.txt"

$newrootPassword = $_newpass -AsSecureString

$newrootCredential = new-object -typename System.Management.Automation.PSCredential -argumentlist "root",$newrootPassword

$newrootPassword2 = $_newpass -AsSecureString

$newrootCredential2 = new-object -typename System.Management.Automation.PSCredential -argumentlist "root",$newrootPassword2

# Compare passwords

If ($newrootCredential.GetNetworkCredential().Password -ceq $newrootCredential2.GetNetworkCredential().Password) {

    # Create new root account object

    $rootaccount = New-Object VMware.Vim.HostPosixAccountSpec

    $rootaccount.id = "root"

    $rootaccount.password = $newrootCredential.GetNetworkCredential().Password

    $rootaccount.shellAccess = "/bin/bash"

    # Get list of Host servers from textfile to change root password on

    Get-Content C:\host.txt | %{

        Connect-VIServer $_ -User root -Password $oldrootCredential.GetNetworkCredential().Password -ErrorAction SilentlyContinue -ErrorVariable ConnectError | Out-Null

        If ($ConnectError -ne $Null) {

            Write-Host "ERROR: Failed to connect to ESX server:" $_

        }

        Else {

            $si = Get-View ServiceInstance

            $acctMgr = Get-View -Id $si.content.accountManager

            $acctMgr.UpdateUser($rootaccount)

            Write-Host "Root password successfully changed on" $_

            Disconnect-VIServer -Confirm:$False | Out-Null

        }

    }

}

Else {

Write-Host "ERROR: New root passwords do not match. Exiting..."

}

Getting below error

You must provide a value expression on the right-hand side of the '-' operator.

At C:\Program Files\VMware\Infrastructure\vSphere PowerCLI\Scripts\Copy of pwdc

hange.ps1:6 char:32

+ $oldrootPassword =  $_oldpass - <<<< AsSecureString

    + CategoryInfo          : ParserError: (:) [], ParseException

    + FullyQualifiedErrorId : ExpectedValueExpression

0 Kudos
LucD
Leadership
Leadership

Have a look at Schedule Task with PowerCLI.script.

In Step 3 the post shows how to store and retrieve credentials from a PowerCLI script.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
pravin_utekar12
Contributor
Contributor

HI Lucd

Thanks for the reply..

but I dint get the solution of my problem. I am trying to run the script which will take the old and new password form the text file directly.

And I am not able to code this process in the script please help me with this.

I have attached the script in the previous reply.

Please check and update.

Thanks

PravinU.

0 Kudos
pravin_utekar12
Contributor
Contributor

Hi LucD

Please tell me the changes that I need to do in the script so that my script will run properly.

I just want my password should pass to the script from the text file.

other wise the script is working fine.

Thanks

Pravinu.

0 Kudos
LucD
Leadership
Leadership

I assume that the files oldpass.txt and newpass.txt contain the passwords in plain text ?

In that case try the attached script.


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos
pravin_utekar12
Contributor
Contributor

Hello Lucd

Thanks for your reply.

I tried this script and getting below error please review and suggest the changes.

Though it is saying that password has been changed successfully but it is not changing

Get-View : Cannot validate argument on parameter 'Id'. The argument is null or

empty. Supply an argument that is not null or empty and then try the command ag

ain.

At C:\Program Files\VMware\Infrastructure\vSphere PowerCLI\Scripts\root-passwor

d.ps1:27 char:26

+         $acctMgr = Get-View -Id <<<<  $si.content.accountManager

    + CategoryInfo          : InvalidData: (:) [Get-View], ParameterBindingVal

   idationException

    + FullyQualifiedErrorId : ParameterArgumentValidationError,VMware.VimAutom

   ation.ViCore.Cmdlets.Commands.DotNetInterop.GetVIView

You cannot call a method on a null-valued expression.

At C:\Program Files\VMware\Infrastructure\vSphere PowerCLI\Scripts\root-passwor

d.ps1:28 char:22

+         $acctMgr.UpdateUser <<<< ($rootaccount)

    + CategoryInfo          : InvalidOperation: (UpdateUser:String) [], Runtim

   eException

    + FullyQualifiedErrorId : InvokeMethodOnNull

Root password successfully changed on 192.168.20.87

Disconnect-VIServer : 5/16/2013 4:42:06 PM    Disconnect-VIServer        PowerC

LI is currently connected to more than one servers. Specify which server you wa

nt to disconnect or use the "*" wildcard to disconnect all.

At C:\Program Files\VMware\Infrastructure\vSphere PowerCLI\Scripts\root-passwor

d.ps1:30 char:22

+         Disconnect-VIServer <<<<  -Confirm:$False | Out-Null

    + CategoryInfo          : InvalidOperation: (:) [Disconnect-VIServer], Vim

   Exception

    + FullyQualifiedErrorId : Core_DisconnectVIServer_ServerNotSpecified,VMwar

   e.VimAutomation.ViCore.Cmdlets.Commands.DisconnectVIServer

0 Kudos
LucD
Leadership
Leadership

I assume the Connect-VIServer went ok,  and that you are connected to an ESXI ?

You can check by displaying the content of $global:defaultviservers.

Once connected, does this return anything ?

Get-View ServiceInstance


Blog: lucd.info  Twitter: @LucD22  Co-author PowerCLI Reference

0 Kudos