&
");ADsPath;subtree"
' Create ADO connection object
Set objConnect = CreateObject("ADODB.Connection")
If Err.Number <> 0 Then
ReportError "FAIL: Error creating ADO connection Object."
Wscript.Quit
End If
' Set properties on the connection object
objConnect.Provider = "ADsDSOObject"
objConnect.Open "STACCTS"
' Create ADO command object
Set objCommand = CreateObject("ADODB.Command")
If Err.Number <> 0 Then
ReportError "FAIL: Error creating ADO command Object."
Wscript.Quit
End If
' Link command object to connection object
Set objCommand.ActiveConnection = objConnect
' Set properties on the command object
objCommand.Properties("Page Size") = 1000
objCommand.Properties("Cache Results") = False
objCommand.CommandText = adoQuery
' Run the query and get the result set
Set objAttributeSet = objCommand.Execute
If Err.Number <> 0 Then
ReportError "FAIL: Error running ADO query."
Wscript.Quit
End If
' Create output header
Call PrintReportHeader()
' Loop through results of query
Do While Not objAttributeSet.EOF
' Get object returned from query
Set objUser = GetObject(objAttributeSet.Fields ("ADsPath"))
' If we can't get this object, note the error and move on
If Err.Number <> 0 Then
ReportError "FAIL: Error accessing object " &
objAttributeSet.Fields("ADsPath")
Err.Clear
Else
' Otherwise, get properties of object
strUserName = objUser.Name
pwdLastChanged = objUser.PasswordLastChanged
' If the users password has never been set, we'll generate
' an error when we try to access the PasswordLastChanged
' property. Trap the error and assign an arbitrary value
' to the password age.
If Err.Number <> 0 Then
Err.Clear
pwdAge = 999
Else
' Otherwise calculate the difference between today and
' when the password was last set
pwdLastChanged = CDate(pwdLastChanged)
todaysDate = CDate(Now())
pwdAge = DateDiff("d", pwdLastChanged, todaysDate)
End If
' Check to see if the password age is greater than the
' interval specified by the user. If it is, write a record
' to the screen.
If (CInt(pwdAge) > CInt(intInterval)) Then
Wscript.Echo FormatField(strUserName, 20, 1) & vbTab &
FormatField(pwdAge, 7, 3)
End If
End If
' Clean up user object
Set objUser = Nothing
' Next record
objAttributeSet.MoveNext
Loop
' Clean up the ADO objects
Set objAttributeSet = Nothing
Set objCommand = Nothing
Set objConnect = Nothing
End Sub
'********************************************************* ***********
'*
'* Function ConvertFQDN()
'* Purpose: Converts the FQDN of a DNS domain to a Distinguished
'* name.
'* Input: strFQDN Fully qualified domain name of the
'* target domain
'* Output: The distinguished name for the domain
'*
'********************************************************* ***********
Private Function ConvertFQDN(strFQDN)
Dim aryDN, strDN
Dim i
strFQDN = Trim(strFQDN)
aryDN = Split(strFQDN, ".", -1, 1)
strDN = "DC=" & Trim(aryDN(0))
For i = 1 to UBound(aryDN)
If Trim(aryDN(i)) <> "" Then
strDN = strDN & ",DC=" & Trim(aryDN(i))
End If
Next
ConvertFQDN = strDN
End Function
'********************************************************* ***********
'*
'* Function FormatField()
'* Purpose: Format output for display.
'* name.
'* Input: strContents Data to be displayed.
'* intWidth Width of the field in which to place
'* the data.
'* intJustify Justification
'* 1 = Left Justify
'* 2 = Center
'* 3 = Right Justify
'* Output: Properly formatted field
'*
'* Notes: If the width provided is not enough to display all the
'* data, the data is truncated to fit.
'*
'********************************************************* ***********
Private Function FormatField(strContents, intWidth, intJustify)
Dim LSpace, RSpace
Select Case intJustify
Case 1 ' left justify
If Len(strContents) > CInt(intWidth) Then 'truncate
FormatField = Left(strContents, CInt (intWidth))
Else
RSpace = Space(CInt(intWidth) - Len (strContents))
FormatField = strContents & RSpace
End If
Case 2 ' center
If Len(strContents) > CInt(intWidth) Then 'truncate
FormatField = Left(strContents, CInt (intWidth))
Else
LSpace = Space((CInt(intWidth) - Len (strContents)) \ 2)
RSpace = Space(CInt(intWidth) - Len (LSpace & strContents))
FormatField = LSpace & strContents & RSpace
End If
Case 3 ' right justify
If Len(strContents) > CInt(intWidth) Then 'truncate
FormatField = Left(strContents, CInt (intWidth))
Else
LSpace = Space(CInt(intWidth) - Len (strContents))
FormatField = LSpace & strContents
End If
End Select
End Function
'********************************************************* ***********
'*
'* Function GetSchemaNC()
'* Purpose: Binds to a DC and determines the Schema Naming Context
'* Output: Returns the DN of the Schema Naming Context
'*
'********************************************************* ***********
Private Function GetSchemaNC
On Error Resume Next
Err.Clear
' Declare variables
Dim rootDSE, schemaNC
' connect to RootDSE
Set rootDSE = GetObject("LDAP://RootDSE")
If Err.Number <> 0 Then
ReportError "A domain controller could not be contacted."
Wscript.Quit
End If
' get the Schema Naming Context
schemaNC = rootDSE.Get("schemaNamingContext")
If Err.Number <> 0 Then
ReportError "Failed to get schema naming context."
Wscript.Quit
End If
GetSchemaNC = schemaNC
' Clean up
Set rootDSE = Nothing
End Function
'********************************************************* ***********
'*
'* Sub ReportError()
'* Purpose: Outputs error message.
'* Input: errorMessage Error message Text
'* Output: Error messages are displayed on screen.
'*
'********************************************************* ***********
Private Sub ReportError(errorMessage)
Wscript.Echo errorMessage & vbCrLf & vbCrlF
Wscript.Echo "Error: " & Hex(Err.Number) & " - " & Err.Description
End Sub
'********************************************************* ***********
'*
'* Sub PrintReportHeader()
'* Purpose: Prints output header
'*
'* Output: Report Header displayed on screen.
'*
'********************************************************* ***********
Private Sub PrintReportHeader()
Wscript.Echo FormatField("Account Name", 20, 2) & FormatField("Password
Age",
20, 2)
Wscript.Echo Space(20) & FormatField("(999=Pwd never set)", 20, 2)
Wscript.Echo String(40, "=")
End Sub
--
Richard McCall [MSFT]
"This posting is provided "AS IS" with no warranties, and confers no
rights."
A previous thread refrenced the following article
http://support.microsoft.com/default.aspx?scid=kb;en-
us;197478
to manage old machine accounts however when putting this
NT4 based script into use for my Win2K domain I find that
the command:
nltest /server:%3 /user:%1$ | find "PasswordLastSet" >
temp.txt
fils to return useful data with the error:
Cannot open
SAM\SAM\Domains\Account\Users\Names\<machinename_here>
Status = 2 0x2 ERROR_FILE_NOT_FOUND
It works just as expected in NT4, is there a way to
enumerate this information in Win2K?
.