Re: password change
- From: "Richard Mueller [MVP]" <rlmueller-nospam@xxxxxxxxxxxxxxxxxxxx>
- Date: Tue, 10 Jun 2008 12:37:59 -0500
Besides the improvements suggested in the article I linked, I would do
several other things differently. I would not use "On Error Resume Next"
throughout and I would use LDAP syntax in the ADO query. I would also
retrieve sAMAccountName instead of cn, as they are not required to match. My
version follows:
==========
' ResetLocalAdminPwds.vbs
Option Explicit
Dim adoCommand, adoConnection, strBase, strFilter, strAttributes
Dim objRootDSE, strDNSDomain, strQuery, adoRecordset, strComputer
Dim objShell, strFilePath, objFSO, objLogFile
Dim objLocalAdmin, strPassword
Const ForWriting = 2
Const OpenAsASCII = 0
Const CreateIfNotExist = True
' Specify the new local Administrator password for all workstations.
strPassword = "zxy#213$q"
' Specify log file.
strFilePath = "c:\scripts\ResetPwds.log"
' Open the log file for write access.
Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objLogFile = objFSO.OpenTextFile(strFilePath, _
ForWriting, CreateIfNotExist, OpenAsASCII)
' Write to log file.
objLogFile.WriteLine "Program ResetLocalAdminPwds.vbs"
objLogFile.WriteLine "Started: " & CStr(Now())
' WshShell object required by Function PingMachine.
Set objShell = CreateObject("Wscript.Shell")
' Setup ADO objects.
Set adoCommand = CreateObject("ADODB.Command")
Set adoConnection = CreateObject("ADODB.Connection")
adoConnection.Provider = "ADsDSOObject"
adoConnection.Open "Active Directory Provider"
adoCommand.ActiveConnection = adoConnection
' Search entire Active Directory domain.
Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
strBase = "<LDAP://" & strDNSDomain & ">"
' Filter on computers without a server operating system
strFilter = "(&(objectCategory=computer)(!operatingSystem=*server*))"
' Comma delimited list of attribute values to retrieve.
strAttributes = "sAMAccountName"
' Construct the LDAP syntax query.
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False
' Run the query.
Set adoRecordset = adoCommand.Execute
' Enumerate the resulting recordset.
Do Until adoRecordset.EOF
' Retrieve NetBIOS name of computer.
strComputer = adoRecordset.Fields("sAMAccountName").Value
' Remove trailing "$".
strComputer = Left(strComputer, Len(strComputer) - 1)
' Ping the computer.
If (PingMachine(strComputer, 1, 750) = True) Then
' Bind to local Administrator user on the computer.
' Trap error if unable to bind or set password.
On Error Resume Next
Set objLocalAdmin = GetObject("WinNT://" & strComputer _
& "/Administrator,user")
If (Err.Number = 0) Then
objLocalAdmin.SetPassword strPassword
If (Err.Number = 0) Then
' Restore normal error handling.
On Error GoTo 0
objLogFile.WriteLine strComputer & " password reset"
Else
' Restore normal error handling.
On Error GoTo 0
objLogFile.WriteLine strComputer _
& " ## unable to set password"
End If
Else
' Restore normal error handling.
On Error GoTo 0
objLogFile.WriteLine strComputer _
& " ## unable to bind to local Administrator"
End If
Else
' Computer not available.
objLogFile.WriteLine strComputer & " ## not available"
End If
' Move to the next record in the recordset.
adoRecordset.MoveNext
Loop
' Write to log file.
objLogFile.WriteLine "Finished: " & CStr(Now())
' Clean up.
objLogFile.Close
adoRecordset.Close
adoConnection.Close
Function PingMachine(ByVal strHost, ByVal intPings, ByVal intTO)
' Returns True if strHost can be pinged.
' strHost is the NetBIOS name or IP address of host computer.
' intPings is number of echo requests to send.
' intTO is timeout in milliseconds to wait for each reply.
' Variable objShell has global scope and must be declared and set
' in the main program. Requires WSH 5.6, which comes standard with
' Windows XP and above.
Dim strResults
Dim objExecObject
' Defaults.
If (intPings = "") Then
intPings = 2
End If
If (intTO = "") Then
intTO = 750
End If
' Ping the machine.
Set objExecObject = objShell.Exec("%comspec% /c ping -n " _
& CStr(intPings) & " -w " & CStr(intTO) & " " & strHost)
' Read the output.
Do Until objExecObject.StdOut.AtEndOfStream
strResults = objExecObject.StdOut.ReadAll
Loop
Select Case InStr(strResults, "TTL=")
Case 0
' No response.
PingMachine = False
Case Else
' Computer responded to ping.
PingMachine = True
End Select
End Function
============
The next step would be to code it so it outputs computers where the password
is not reset to a separate text file of "missed" computers. Then you could
run the script repeatedly and it would only attempt to reset the password
for computers in the "missed" file. As the passwords are reset, the
computers are removed from the "missed" file. If there is no "missed" file,
the program resets local Administrator password on all computers. If the
"missed" file exists but has no computer names, the process is complete (all
passwords have been reset). I may work on that later.
--
Richard Mueller
MVP Directory Services
Hilltop Lab - http://www.rlmueller.net
--
.
- References:
- Re: password change
- From: Edwin vMierlo [MVP]
- Re: password change
- From: Richard Mueller [MVP]
- Re: password change
- Prev by Date: Re: policy question
- Next by Date: Re: Defragmenting hard drives on Windows Server 2003/SQL Server
- Previous by thread: Re: password change
- Next by thread: Re: password change
- Index(es):
Relevant Pages
|