Updating Remote Passwords with PowerShell

Changing passwords is always one of those fun tasks for any admin. It becomes even more challenging when your a Windows admin over hundreds of individual servers that are not part of the same domain.  Here’s my take on a PowerShell script to change the password of a local user on a remote system (or many remote systems), regardless of domain status.

I like to take the opportunity to use vSphere as a way to gather systems to run scripts against as opposed to the traditional serverlist.txt files.  This lets me target systems to run scripts against via any grouping provided by vSphere including folders, hosts, clusters, datacenters, etc.  My favorite is the use of folders as many folks already use these to group common systems together. Note you can always use the ‘VM’ folder which is the (hidden) root folder which holds all VMs if you want to take it that far.

So we’ll connect to vCenter via PowerCli and grab a list of Powered On Windows systems. Next comes connecting to each system via WMI and changing the password. Two sets of credentials are required, one used to connect to the remote system and the second being the account being updated (Note these can be the same account – you can logon as bob and change bob’s password).

In the script you will notice a -flush parameter.  This helps resolve the “Multiple connections to a server or shared resource by the same user, using more than one user name, are not allowed. Disconnect all previous connections to the server or shared resource and try again.” issue.  Be aware that the -flush switch will remove all mapped drives and connections to all remote systems by simply running – net use * /d /y

#
# ChangePwd
#
# Author: Shawn Masterson
# Created: June 2013
# Version: 1
#
# Purpose: Change local Windows account passwords on remote systems located in a vSphere folder
#
#
# Arguments:
# -vCenter – vCenter Server FQDN or IP
# -VMFolder – vCenter folder containing VMs to update
# -Flush – Clears current share connections (\\computer\share$)
#
# Examples:
# .\ChangePwd.ps1
# .\ChangePwd.ps1 -Flush
# .\ChangePwd.ps1 -vCenter vcenterserver -VMFolder "My VMs"
#
# Notes:
# You can right click on script and 'Run from Powershell'
# The -Flush parameter will run the following command on start-up – net use * /d /y (understand what this does before using!)
# If you have multiple folders with the same name, VMs in all folders will be updated
#
# Supported OS's:
# Windows Servers 03/03×64/08/08×64/08R2/2012
#
# Requirements:
# vCenter (Server list to be updated is gathered from vCenter – only tested on 5.x)
# Script host must have PowerCLI (only tested on 5.x)
# Script host needs WMI/RPC access to servers being updated
# VMware Tools must be installed and running on the Windows VMs
# Must be able to resolve DNS names of systems as seen in vCenter
#
# Disclaimer:
# There is absolutely zero error catching built into this script!
# USE AT YOUR OWN RISK
#
#
#
#——————————————————————–
# Parameters (Arguments)
#
param (
$vcenter,
$VMFolder,
[switch]$Flush
)
#
#
#——————————————————————–
# User Denifed Variables
#
# vSphere folder to exclude (notmatch)
$skipFolder = "Clone"
#
#——————————————————————–
# Load Snap-ins
#
# Add VMware snap-in if required
if ( (Get-PSSnapin Name VMware.VimAutomation.Core ErrorAction SilentlyContinue) -eq $null ) {add-pssnapin VMware.VimAutomation.Core}
#
#
#——————————————————————–
# Main Procedures
#
# Flush share connections if -Flush is used
If ($Flush) {net use * /d /y | Out-Null}
#
cls
Write-Host "ChangePwd " (Get-Date) foregroundcolor "Yellow"
Write-Host "`nThis script will change the password of a user account on remote VMs" foregroundcolor "Yellow"
Write-Host "VMs are gathered from a choosen vSphere folder`n`n`n" foregroundcolor "Yellow"
#
# Ask for vCenter address (if not provided)
If ($vcenter -eq $Null) {$vcenter = Read-Host "Enter vCenter server FQDN or IP"}
Write-Host
#
# Connect to vCenter server
Try
{
Write-Host "Connecting to vCenter –" $vcenter foregroundcolor "Yellow"
Connect-VIServer $vcenter EA Stop
}
Catch
{
Write-Host "`r`n`r`nUnable to connect to" $vcenter backgroundcolor Red
Write-Host "Exiting…`r`n`r`n" foregroundcolor "Yellow"
Exit
}
#
# Ask for vSphere folder to get VMs from (if not provided)
Write-Host "`n"
If ($VMFolder -eq $Null) {$VMFolder = Read-Host "Enter vSphere folder to query"}
#
# Grab all Windows VM guest hostnames that are Powered On in the supplied vSphere folder
Write-Host "`n"
Write-Host "Querying All Running Windows VMs in Folder(s) –" $VMFolder foregroundcolor "Yellow"
$vms = Get-Folder $VMFolder | Get-VM | Where-Object {$_.Guest.OSFullName -like "*Windows*" -and $_.PowerState -eq "PoweredOn" -and $_.Folder.Name -notmatch $skipFolder} | `
Sort Property Name | foreach { $_.Guest.Hostname }
#
# Confirm vSphere Folder exists
If ($vms -eq $Null) {
Write-Host "`r`n`r`nFolder does not exists or no VMs in Folder to scan" backgroundcolor Red
Write-Host "Exiting…`r`n`r`n" foregroundcolor "Yellow"
Exit}
#
Write-Host "`nFound" $vms.Count "systems`n" foregroundcolor "Yellow"
#
#
Write-Host "`n`n"
If ($Account -eq $Null) {$Account = Read-Host "Enter Windows account to update password"}
If ($Newpwd -eq $Null) {$Newpwd = Read-Host 'Enter NEW password for' $Account}
#
#
#
Write-Host "`n`n"
Write-Host "Credentials are needed to connect to the Windows Servers being updated`n" foregroundcolor "Yellow"
If ($Username -eq $Null) {$Username = Read-Host "Enter Windows Admin username"}
If ($Password -eq $Null) {$Password = Read-Host 'Enter Windows password for' $Username}
Write-Host "`n`n"
Write-Host "Process started…" foregroundcolor "Yellow"
Write-Host
#
#
# Update account password on each VM
foreach ($vm in $vms) {
Write-Host "`nUpdating" $vm foregroundcolor "Yellow"
Try {
$remote = New-Object System.DirectoryServices.DirectoryEntry("WinNT://$vm/$account,user",$username,$password)
$remote.SetPassword($Newpwd)
}
Catch {
Write-Host "FAILED" backgroundcolor Red
$error[0]
$fails = $fails + "`n" + $vm
}
}
#
#
#
#
#——————————————————————–
# Close Connections
#
# Disconnect vCenter
Disconnect-VIServer Server $vcenter Force Confirm:$false
#
#——————————————————————–
# Outputs
#
Write-Host "`n`n"
Write-Host "Update Complete`n" foregroundcolor "Yellow"
If ($fails -ne $Null) {Write-Host "The following servers failed to update:" $fails backgroundcolor Red}
#
# Prompt to exit script
Write-Host "`n`n"
Write-Host "Press any key to continue …"
$x = $host.UI.RawUI.ReadKey("NoEcho,IncludeKeyDown")

view raw
ChangePwd.ps1
hosted with ❤ by GitHub

Leave a Reply

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