Wednesday, July 8, 2015

Powershell change local administrator account password for all computers in the domain

Hi mates,
how many times you asked to yourself : how can I change all pcs local administrator password ?
I had the need to change it for all computers in one of my customer domain.
The password was compromised and the old Microsoft GPO was no longer working (a patch disabled it for security reasons - MS14-025: Vulnerability in Group Policy Preferences could ... - https://support.microsoft.com/en-us/kb/2962486).
So what to do ?

I mixed some parts of other ideas and created my own script that will run for example once a hour on one or several domain controllers. It depends on your specific needs.
In few days I should have the job done since there are also road warrior users that connects, to our network , only once a day.
Anyway at the end of every cycle I should have a text file that recap the situation
You can for sure improve it and don't forget to customize it for your environment :
$ErrorActionPreference = "Continue"
$pcfilelist = "$env:temp\pwd_change_list_pc.txt"
$password = "mynewlocaladministratoraccountpassword"
$error.Clear()
$pcfound = "$env:temp\pwd_change_list_pc_FOUND.txt"
$pcnotfound = "$env:temp\pwd_change_list_pc_NOT_FOUND.txt"
$pcreachable = "$env:temp\pwd_change_list_pc_REACHABLE.txt"
$pcNOTreachable = "$env:temp\pwd_change_list_pc_NOT_REACHABLE.txt"
$intermediate = "$env:temp\pwd_change_intermediate.txt"
$pcdone = "$env:temp\pwd_change_pc_done.txt"
$useradm = "administrator"
if ((test-path $pcfound) -or (test-path $pcnotfound) -or (test-path $pcreachable) -or (test-path $pcNOTreachable )){
Remove-Item $pcfound
Remove-Item $pcnotfound
Remove-item $pcreachable
remove-item $pcNOTreachable
}
else{
}
# this specific loop will be executed the first time
if (-not (test-path $pcfilelist)){
$pclist = @();
$pclist = $null
# filter to group all computer account...you can exclude a specific ou for example inside the filter
# if a specific OU has to have a different password you have only to modify this filter
$pclist = Get-ADComputer -Filter { OperatingSystem -notLike '*Windows Server*' -and operatingsystem -notlike "*Windows 2*" } -Properties name | where-object {$_.DistinguishedName -notlike "*OU=Excluded OU*"} | where {$_.enabled -eq "True"} | Select-Object -ExpandProperty name
Get-ADComputer -Filter { OperatingSystem -notLike '*Windows Server*' -and operatingsystem -notlike "*Windows 2*" } -Properties name | where-object {$_.DistinguishedName -notlike "*OU=Excluded OU*"} | where {$_.enabled -eq "True"} | Select-Object -ExpandProperty name | out-file $pcfilelist
$pclist | foreach {
$pc=$_
if (Test-Connection $pc -count 2 -delay 1){
write-host "Reachable via ping : " $pc
$pc | out-file $pcfound -append
if ([adsi]"WinNT://$pc/$useradm,user") {
$pc | out-file $pcreachable -append
$user = [adsi]"WinNT://$pc/$useradm,user"
try {
# the next row is only for test : it lists the local administrator group members.......
# ([ADSI]"WinNT://$pc/Administrators,group").psbase.Invoke('Members') | foreach { $_.GetType().InvokeMember('ADspath', 'GetProperty', $null, $_, $null).Replace('WinNT://', '') }
# you have to uncomment the following two rows if you want to really change the password.....leave as they are now to test the script
#$user.SetPassword($Password)
#$user.SetInfo()
$pc | out-file $pcdone -Append
write-host "Password successfully changed on : " $pc
}
Catch [system.exception]
{
write-host "Access denied. Even if the pc is reachable you may not have the rights to change the password " $Error
$pc | out-file $pcNOTreachable -append
}
Finally
{
}
}
else {
$pc | out-file $pcNOTreachable -append
write-host "Password NOT changed on : " $pc
}
}
else{
write-host "NOT reachable via ping : " $pc
$pc | out-file $pcnotfound -append
}
}
}
# this loop will restart from the list created the first time from the loop above
else {
$pclist = $pcfilelist
(get-content $pclist) | foreach {
$pc=$_
if (Test-Connection $pc -count 2 -delay 1){
write-host "Reachable via ping : " $pc
$pc | out-file $pcfound -append
if ([adsi]"WinNT://$pc/$useradm,user") {
$pc | out-file $pcreachable -append
$user = [adsi]"WinNT://$pc/$useradm,user"
$error.Clear()
try {
# the next row is only for test : it lists the local administrator group members.......
# ([ADSI]"WinNT://$pc/Administrators,group").psbase.Invoke('Members') | foreach { $_.GetType().InvokeMember('ADspath', 'GetProperty', $null, $_, $null).Replace('WinNT://', '') }
# you have to uncomment the following two rows if you want to really change the password.....leave as they are now to test the script
#$user.SetPassword($Password)
#$user.SetInfo()
$pc | out-file $pcdone -Append
write-host "Password successfully changed on : " $pc
}
Catch [system.exception]
{
write-host "Access denied. Even if the pc is reachable you may not have the rights to change the password " $Error
$pc | out-file $pcNOTreachable -append
}
Finally
{
}
}
else {
$pc | out-file $pcNOTreachable -append
write-host "Password NOT changed on : " $pc
}
}
else{
write-host "NOT reachable via ping : " $pc
$pc | out-file $pcnotfound -append
}
}
}
# clean the useless files for the next scheduled task that will start from the list of the computer where the password, for a motivation or another, was not changed
Get-Content $pcNOTreachable | out-file $intermediate -Append
Get-Content $pcnotfound | out-file $intermediate -append
Remove-Item $pcfilelist
Get-Content $intermediate | Get-Unique | out-file $pcfilelist
Remove-Item $intermediate
view raw gistfile1.ps1 hosted with ❤ by GitHub
For sure adjustable in every single line but usable more or less in few minutes.
Comments and critics are welcome
Hope this helps
See you soon

No comments:

Post a Comment