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
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
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
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
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
Got it! Thanks for all your help!
Hello All,
please suggest me the way how can i schedule this script.I want the password should change automatically bimonthly.
Thanks
PravinU
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
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.
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
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.
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
}
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
Hi Lucd,
I want to check it for single host. By mistake I mentioned the vm.
Please help me with this..
Thanks
PravinU
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
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
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.
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.
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
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
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