missymadi
asked on
How to run Powershell script on all Servers in domain?
Experts,
I have an existing script that resets a users password. I would like to attach to all of the servers in our domain and run this script from the PDC. How would I accomplish this task? I have made a few attempts but the logic was incorrect.
I think I need to have something like $servers = Get-Content c:\servers.txt. Also the part that I do not know how\where to code the credentials to access each server. The passwords must be encrypted. When I tested the script by adding a test $servers = Get-Content c:\servers.txt the password was changed on the PDC and not the server I wanted to be connected to.
Please advise, Missymadi
I have an existing script that resets a users password. I would like to attach to all of the servers in our domain and run this script from the PDC. How would I accomplish this task? I have made a few attempts but the logic was incorrect.
I think I need to have something like $servers = Get-Content c:\servers.txt. Also the part that I do not know how\where to code the credentials to access each server. The passwords must be encrypted. When I tested the script by adding a test $servers = Get-Content c:\servers.txt the password was changed on the PDC and not the server I wanted to be connected to.
Please advise, Missymadi
# Ask for a username
$Username = Read-Host "Enter UserName"
# Search for the user(s)
$Users = Get-QADUser -SamAccountName $Username | Select-Object Name, DN,
PasswordLastSet, PasswordAge,PasswordExpires, PasswordNeverExpires,
UserMustChangePassword, PasswordIsExpired, PasswordStatus
# Display the user(s)
$Users
If ($Users) {
# Ask if they wish to proceed
$Response = Read-Host "Do you want to reset the user's password?`n[1] Yes, [2] No"
If ($Response -eq "1") {
# Ask for password
$SecurePassword1 = Read-Host "Please enter a password to use" -AsSecureString
$SecurePassword2 = Read-Host "Please re-enter the password to confirm" -AsSecureString
$Password1 = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
[Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword1))
$Password2 = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
[Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword2))
If ($Password1 -ne $Password2) {
Write-Host "Passwords do not match. Aborting script." -ForegroundColor Red
} Else {
# Perform work
# For each user we found earlier, set the password. Log a few things and the name of the
# user running this script
$Users | ForEach-Object {
Set-QADUser $_.DN -UserPassword $Password1
Write-Host "Password reset for $($_.Name)"
} | Select-Object SamAccountName, PasswordLastSet, @{n='SetBy';e={ $Env:Username }} |
Out-File c:\PwdChanged.txt -Append
}
}
} Else {
Write-Host "No users found" -ForegroundColor Red
}
Are you trying to reset the local user passwords on all your Servers?
ASKER
Yes.
I will need to reset local Admin and local users on each server.
I did find a script that changed Admin's password on each server and the concept is what I'm looking for as far as connecting to each Server and changing the passwords BUT I want to use my script above that allows the users(maintainer) control over the script.
The script I found that changes only local admin password on domain servers is attached. I found out on the net.
I will need to reset local Admin and local users on each server.
I did find a script that changed Admin's password on each server and the concept is what I'm looking for as far as connecting to each Server and changing the passwords BUT I want to use my script above that allows the users(maintainer) control over the script.
The script I found that changes only local admin password on domain servers is attached. I found out on the net.
$servers = Get-Content c:\servers.txt
$old_credential = $host.ui.PromptForCredential("Please enter OLD credentials", "Please enter OLD user name/password e.g. local\netserv", "", " NetBiosUserName")
$new_credential = $host.ui.PromptForCredential("Please enter NEW credentials", "Please enter NEW user name/password e.g. local\netserv", "", " NetBiosUserName")
$new_password = $new_credential.GetNetworkCredential()
$npu = $new_password.username
$npp = $new_password.password
foreach($server in $servers) {
Try {
Get-WmiObject win32_BIOS -Computername $server -Credential $old_credential -ErrorAction stop | Out-Null
"Recognized password for $($old_credential.username) in computer $server"
"Changing password for $($new_credential.username) in computer $server"
$admin=[adsi]("WinNT://$server/$npu, user")
$admin.psbase.invoke("SetPassword", $npp)
}
Catch {
"NOT changing password for $($old_credential.username) in computer $server"
}
}
ok, if you are looking to change local user name you can not use the quest cmdlets. The script will need to use the below syntax instead of using get-qaduser and set-qaduser, these are only used for domain accounts. I will look through your script and see what all needs updated.
$admin=[adsi]("WinNT://$Se rver/$User , user")
$admin.psbase.invoke("SetP assword", $Password1)
$admin=[adsi]("WinNT://$Se
$admin.psbase.invoke("SetP
ASKER
Thank you! You guys are great!
Is it only the local administrator account you need to reset on each computer?
If it is then I do not understand why you need an input of the username. If it is not the lcoal administrator account then why do you need to use so many local user accounts on your servers and not domain accounts?
If it is then I do not understand why you need an input of the username. If it is not the lcoal administrator account then why do you need to use so many local user accounts on your servers and not domain accounts?
ASKER
Local administrator and local user accounts.
Our setup is as follows:
no central user database, all users are maintained on each machine.
Our setup is as follows:
no central user database, all users are maintained on each machine.
Are these all stand-alone server or are they in a AD domain? I would assume a domain since you said you want to run from a DC
ASKER
AD domain. The user accounts are maintained by the AD.
ok, now I am really confused. Are these local account to each server or are they user account in AD that the password needs changed? If these are local accounts to each server then we will have to use what I posted before. If these are domain accounts we can use the Quest cmdlets and do not have to loop through a list of servers to change.
ASKER
Sorry - our setup is quite different than most. But you actually helped me ..... I will need two scripts.
One using the cmdlets and one using the one you posted above. We have two separate LAN's one that has no central db so accounts are maintained on each machine. The other LAN is maintained by AD. One the one that has AD is very time sensitive and any discrepancies between Server/client will result in a user not being able to log in.
One using the cmdlets and one using the one you posted above. We have two separate LAN's one that has no central db so accounts are maintained on each machine. The other LAN is maintained by AD. One the one that has AD is very time sensitive and any discrepancies between Server/client will result in a user not being able to log in.
ok, let me look through the scripts and see what needs changed. For the servers that have local accounts, are these servers on the domain or are they stand alone?
ASKER
They are stand alone.
resetting those may be a little difficult becuase you will need to specify a username and password to connect. So you will need to either prompt for a username and password or hard code one in the script. So you may want to have an account on each server for this so they are all the same username and password.
ASKER
Could we prompt the user(maintainer) for the server connecion credentials? And could this be encrypted?
ASKER
The script must be ONE script that resides on the PDC and can reset passwords on a domain and stand alone machines.
Our network is as follows:
One LAN consists of all users maintained on each machine (no central db) the OS is Linux, Linux thin client and monta vista. The other LAN consists of AD and VM's all Windows, VMware(esx) There is one firewall and switches.
Is it possible to create one script and access each machine from PDC? I imagine the script calling other scripts to create a connection to open sockets.
Please advise.
Missymadi
Our network is as follows:
One LAN consists of all users maintained on each machine (no central db) the OS is Linux, Linux thin client and monta vista. The other LAN consists of AD and VM's all Windows, VMware(esx) There is one firewall and switches.
Is it possible to create one script and access each machine from PDC? I imagine the script calling other scripts to create a connection to open sockets.
Please advise.
Missymadi
That makes it even more complicated. I assumed since you started out with using powershell and the quest cmdlets these were windows based computers. I am not very familiar with linux so I do not know how much help I can be. Can you give me an example of how you reset the passwords now on those computers? Do you do it remotly now for a single computer?
ASKER
I can definitely use the Powershell script for the Windows machines and it's doing exactly what the requirements call for. So I will keep this one and use for the Windows machines.
Right now we log into each machine separately. It is a strange mix of machines and we are looking for one script to reach all the servers and reset the password by prompting the user for server credentials then running the script to change username and password.
I posted this before and now I'm understanding this a little more, it will contact the machine from a list of hosts and make a connection through appropriate protocol to a waiting open socket then run the script that resides on that machine to reset the password. Does that make sense? Can you help me get there? Here is an example I found below. This is just an example but I think this is what I need?
Thanks! Missymadi
Right now we log into each machine separately. It is a strange mix of machines and we are looking for one script to reach all the servers and reset the password by prompting the user for server credentials then running the script to change username and password.
I posted this before and now I'm understanding this a little more, it will contact the machine from a list of hosts and make a connection through appropriate protocol to a waiting open socket then run the script that resides on that machine to reset the password. Does that make sense? Can you help me get there? Here is an example I found below. This is just an example but I think this is what I need?
Thanks! Missymadi
#! /usr/bin/ksh
# Change_Password --- change the user's password on a list of hosts
#
# You will need to adjust HOSTLIST. You may need to adjust DELAY
# and all of section 2.
#
#
# Section 0 --- Set stuff up
HOSTLIST="test1 test2"
DELAY=3
stty -echo
print -n Enter Old Password-
read OLDPASS
print
print -n Enter New Password-
read NEWPASS
print
stty echo
USER=$(whoami)
exec 4>&1
#
# Section 1 --- Prove that we can talk with the hosts in HOSTLIST
# Part 1 --- telnet to each and touch a file
for HOST in $HOSTLIST ; do
telnet $HOST >&4 2>&4 |&
sleep $DELAY
print -p $USER
sleep $DELAY
print -p $OLDPASS
sleep $DELAY
print -p touch changepassdatafile.$HOST
sleep $DELAY
print -p exit
wait
done
#
# Section 1 --- Prove that we can talk with the hosts in HOSTLIST
# Part 2 --- Retrieve the files via ftp
ftp -nv >&4 2>&4 |&
for HOST in $HOSTLIST ; do
print -p open $HOST
print -p user $USER $OLDPASS
print -p get changepassdatafile.${HOST}
print -p close
done
print -p bye
wait
#
# Section 1 --- Prove that we can talk with the hosts in HOSTLIST
# Part 3 --- Inspect the retrieved files
errors=0
for HOST in $HOSTLIST ; do
if [[ -f changepassdatafile.${HOST} ]] ; then
echo $HOST was ok
rm changepassdatafile.${HOST}
else
echo $HOST has a problem
((errors=errors+1))
fi
done
((errors)) && exit 1
#
# Section 2 --- Change the passwords
for HOST in $HOSTLIST ; do
telnet $HOST >&4 2>&4 |&
sleep $DELAY
print -p $USER
sleep $DELAY
print -p $OLDPASS
sleep $DELAY
print -p passwd
sleep $DELAY
print -p $OLDPASS
sleep $DELAY
print -p $NEWPASS
sleep $DELAY
print -p $NEWPASS
sleep $DELAY
print -p exit
wait
done
#
# Section 3 --- Verify that the passwords were changed
# Part 1 --- Retrieve those files via ftp again
ftp -nv >&4 2>&4 |&
for HOST in $HOSTLIST ; do
print -p open $HOST
print -p user $USER $NEWPASS
print -p get changepassdatafile.${HOST}
print -p delete changepassdatafile.${HOST}
print -p close
done
print -p bye
wait
#
# Section 3 --- Verify that the passwords were changed
# Part 2 --- Inspect the retrieved files
errors=0
for HOST in $HOSTLIST ; do
if [[ -f changepassdatafile.${HOST} ]] ; then
rm changepassdatafile.${HOST}
else
echo $HOST has a problem!
((errors=errors+1))
fi
done
((errors)) && exit 1
exit 0
ASKER
But the hostlist script would run from windows not linux(in example)
That is a Linux shell script, I do not know enough about Linux and do not have anyway to test. You may need something like cygwin installed on your windows computer to run this. You will probably be better off to close this question and post a new one in a Linux Zone, they would be able to help you better than I can and a lot faster.
http://www.cygwin.com/
http://www.cygwin.com/
ASKER
Could you still help me with the original question? I would need the two scripts - one for stand alone and one for AD to change the passwords. I will use these locally.
I do need the host list of servers script , to be in Windows format because it needs to run on our Win2K3 (PDC) server. I'll post another question for this one.
Thanks for your help!
Missymadi
I do need the host list of servers script , to be in Windows format because it needs to run on our Win2K3 (PDC) server. I'll post another question for this one.
Thanks for your help!
Missymadi
Yes I can help with that. These are the servers that are all in the domain correct? If that is the case we do not need to run against a list of servers, we can just change the password on the DC.
ASKER
Yes they are in the domain. If it's not too much could you provide the one that goes through a list of servers? Just curious to see how I would connect to a server not on a domain and run a script against it.
Thanks so much!
Thanks so much!
Yes, I will test this out tonight and post back.
missymadi
The script you posted will change a domain users password. Here is one that will loop through a list a servers and change a local users password.
The script you posted will change a domain users password. Here is one that will loop through a list a servers and change a local users password.
# Ask for a username
$Username = Read-Host "Enter UserName"
$Servers = get-content C:\Servers.txt
$Servers | %{
# Ask for password
$SecurePassword1 = Read-Host "Please enter a password to use" -AsSecureString
$SecurePassword2 = Read-Host "Please re-enter the password to confirm" -AsSecureString
$Password1 = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
[Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword1))
$Password2 = [Runtime.InteropServices.Marshal]::PtrToStringAuto(
[Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecurePassword2))
If ($Password1 -ne $Password2) {
Write-Host "Passwords do not match. Aborting script." -ForegroundColor Red
} Else {
$admin = [adsi]("WinNT://$($_)/$($UserName), user")
Try{
$admin.SetPassword($Password1)
"The password for $($Username) was changed on $($_)"}
Catch{
"Failed to change password for $($Username) on $($_)"}
}
ASKER
Thanks for the response. Exactly what I needed except could we change instead of having a servers.txt, could we prompt the user for a computer?
Thanks! Missymadi
Thanks! Missymadi
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.