howyadoing
(Getting the hang of it)
2004-09-14 12:20 PM
Two Questions

1. I have an admin script that does x. I want to do x to 90% of the machines in the domain but not all including the servers. There are 2000 machines and many pc techs so some of the computer names change weekly. I can export a new list of computers everytime I want to do x or is there a UDF that can work with the ldap path? All of these machines are in one area of AD.

2. I want to write and computer startup script to change the local administrator password on computers using renameadmin.exe. The following is what I am using from my admin computer. This works but it is a little complicated in the fact that I have to run it every day and check to see what machines it does not get until I get them all. I also have to update the computer list regurarly because of name changes. Ideally I would write a script with the passwords encrypted and based on @date the password would get reset. Is there a way to use @pwage to get the age of the password for that admin without being logged in as that local admin? If not can it be written so when the password is changed it writes the date to a line in a file then each time the script runs it would read the line to see when it ran last and run if needed. If there are multiple lines of dates that the admin password has been changed can you write the readline part to only look at the last line so you are looking at the last date changeg? When you write a line during a password change, the next time the password is changed will it write the next line below the first entry or next to the first?

Thanks in advance

Code:
 Break ON
;Debug ON
;Password Note: This should be the local admin Password of the remote PC's.
;Special Note: @, %, $ are special characters.
;If your Password contains them please type them twice In a row.
;EX: "$Test@_$" = "$$Test@@_$$" Remember, they are inforcing a Password scheme now.

$PWD = "test"
If Open (1,"PCLIST.TXT",0) = 0
$LINEINFO = ReadLine(1)
While @ERROR = 0
? "PCNAME: $LINEINFO"
?
Shell '%COMSPEC% /C renameadmin --computer \\$LINEINFO --pwd $PWD'
Select
Case @ERROR = "0"
? "Successful"
Shell "%COMSPEC% /C echo $LINEINFO,Success>> admin_log.csv"
Case @ERROR = "53"
? "No PC Found"
Shell "%COMSPEC% /C echo $LINEINFO,No PC Found>> admin_log.csv"
Case @ERROR = "5"
? "Access Denied"
Shell "%COMSPEC% /C echo $LINEINFO,Access Denied>> admin_log.csv"
Case @ERROR = "2245"
? "Invalid Password"
Shell "%COMSPEC% /C echo $LINEINFO,Invalid Password>> admin_log.csv"
Case 1
? "Weird Error"
Shell "%COMSPEC% /C echo $LINEINFO,Weird Error>> admin_log.csv"
EndSelect
$LINEINFO = ReadLine(1)
?
Loop
$RC = Close (1)
Else
Exit 0
EndIf
Exit 0



maciep
(Korg Regular)
2004-09-14 03:11 PM
Re: Two Questions

For your first question, this scriptlet should enumerate through the part of AD that you need it to. Just change the LDAP path

Code:

$objConnection = CreateObject("ADODB.Connection")
$objCommand = CreateObject("ADODB.Command")
$objConnection.Provider = "ADsDSOObject"
$objConnection.Open("Active Directory Provider")
$objCommand.ActiveConnection = $objConnection

$objCommand.CommandText =
"SELECT Name FROM "
+ "'LDAP://OU=YourOU,dc=blah,dc=something,dc=net' WHERE objectCategory='computer'"
$objCommand.Properties("Page Size").Value = 100
$objCommand.Properties("Search Scope").Value = 2
$objCommand.Properties("Cache Results").Value = (not 1)

$objRecordSet = $objCommand.Execute()
$objRecordSet.MoveFirst
while not $objRecordSet.EOF
$curComputer = $objRecordSet.Fields("Name").Value
? $curComputer
;DoX($curComputer)
$objRecordSet.MoveNext
Loop




Les
(KiX Master)
2004-09-14 04:23 PM
Re: Two Questions

maciep,
Did you test this code? It looks like a VBS conversion and think there may still be traces of VBS in the line:
$objCommand.Properties("Cache Results").Value = False

Anyway, it does not return anything for me. Should it also work on nested OUs? IN my OU, I nest additional OUs so I can apply GPOs to them based on OU.

howyadoing,
I use the NetView2() function which pulls in every computer without having to maintain any list. In our organization, each Business Unit (BU) has a two character BU code (FF in my case) that prefixes every computer in my BU so I check that it starts with 'FF'. I also use Howard's InContainer() UDF to verify that they are in my OU and pull some ADSI props while I am at it to update the 'description' from the 'comment'.

You say there are 2000 computers. Is that in your OU or domain wide? There are over 6000 in my domain and this works slick and never needs maintenance.


maciep
(Korg Regular)
2004-09-14 04:42 PM
Re: Two Questions

you're right les, it should be (not 1) instead of false, but i just ran it now (with False in there) and it worked fine. it should work on nested ou's as well - that's what the search scope value controls.

Les
(KiX Master)
2004-09-14 04:50 PM
Re: Two Questions

Doh! silly me

I had my OUs in the wrong order.

BTW, I have to assume that the line:
DoX($curComputer)
calls a UDF of your making and could just as well be:
;do something
for the purpose of this example.


maciep
(Korg Regular)
2004-09-14 04:52 PM
Re: Two Questions

yep, i just realized that. i just put it in there but forgot to comment it out. i'll edit my original post to limit further confusion.

howyadoing
(Getting the hang of it)
2004-09-14 05:03 PM
Re: Two Questions

Thanks for the help. Below is what I ended up with and it works. Ideally I would like to run a startup script to change the local admin password. I would like to do it on password age but I dont think I will be able to. I also dont think its a good idea to run the script everytime the computer starts on the network and reset the password every time. Any suggestions on how I can change the administrator password through a startup script. This way works fine but how do you handle the machines that were out of the office when you ran the script? Right now I am in a situtation that an employee left the company so I will use this today.

Code:
 $objConnection = CreateObject("ADODB.Connection")
$objCommand = CreateObject("ADODB.Command")
$objConnection.Provider = "ADsDSOObject"
$objConnection.Open("Active Directory Provider")
$objCommand.ActiveConnection = $objConnection

$objCommand.CommandText =
"SELECT Name FROM "
+ "'LDAP://ou=gp test,ou=cincinnati - 11499,ou=united states,ou=Offices,dc=na,dc=ipsos' WHERE objectCategory='computer'"
$objCommand.Properties("Page Size").Value = 100
$objCommand.Properties("Search Scope").Value = 2
$objCommand.Properties("Cache Results").Value = Not 1

$objRecordSet = $objCommand.Execute()
$objRecordSet.MoveFirst
while not $objRecordSet.EOF
$curComputer = $objRecordSet.Fields("Name").Value
? $curComputer


$PWD = "test"
Shell '%COMSPEC% /C renameadmin --computer \\$CurComputer --pwd $PWD'
Select
Case @ERROR = "0"
? "Successful"
Shell "%COMSPEC% /C echo $CurComputer,Success>> admin_log.csv"
Case @ERROR = "53"
? "No PC Found"
Shell "%COMSPEC% /C echo $CurComputer,No PC Found>> admin_log.csv"
Case @ERROR = "5"
? "Access Denied"
Shell "%COMSPEC% /C echo $CurComputer,Access Denied>> admin_log.csv"
Case @ERROR = "2245"
? "Invalid Password"
Shell "%COMSPEC% /C echo $CurComputer,Invalid Password>> admin_log.csv"
Case 1
? "Weird Error"
Shell "%COMSPEC% /C echo $CurComputer,Weird Error>> admin_log.csv"
EndSelect
$objRecordSet.MoveNext
Loop
EXIT




Les
(KiX Master)
2004-09-14 05:20 PM
Re: Two Questions

Run it as a Task Scheduled admin script like I do. Mine runs every 2 hours and checks an INI file for the last password change. It changes the password every month.

Les
(KiX Master)
2004-09-14 05:24 PM
Re: Two Questions

Why write to a CSV when an INI is easier? It would be a major security risk to run it as a startup script because the password is exposed in the script for anyone to see!

howyadoing
(Getting the hang of it)
2004-09-14 06:08 PM
Re: Two Questions

I was going to encrypt the password with renameadmin.exe first. The script posted is only for me to run on my admin computer.

Les
(KiX Master)
2004-09-14 06:40 PM
Re: Two Questions

Quote:

I was going to encrypt the password with renameadmin.exe first. The script posted is only for me to run on my admin computer.




That is not secure as it is reversable. It would also require that all your users have admin rights.


maciep
(Korg Regular)
2004-09-14 06:41 PM
Re: Two Questions

you might be able to do it based on password age

Code:

$admin = getobject("WinNT://" + @wksta +"/Administrator")
? $admin.PasswordAge



howyadoing
(Getting the hang of it)
2004-09-14 07:18 PM
Re: Two Questions

Computer scripts are nice because they run with the powers of local admin. But the encryption idea I might need to rethink.. This script works other than it seems to be in seconds? The value I got was 18828185

Sealeopard
(KiX Master)
2004-09-15 05:49 AM
Re: Two Questions

See also the OSID() UDF for remote OS detection.