Link to home
Start Free TrialLog in
Avatar of nouses9
nouses9Flag for United States of America

asked on

Windows AD Scripting - Excluding Machines

Hello all,

Hopefully this is in the right place.  I have a script that I found online that does exactly what I need to do except for one small thing (I don't do a lot of scripting so I thought I would turn to all of you for help).  Here is the script and what it is supposed to do:

'This script enumerates the AD and creates a record set of all machine accounts
'It then loops through the record set checking the machine accounts password age
'and comparing it to the age that was entered. Any machine account that has a
'password age older than that which is specified will be listed.
'Keep in mind that by default a machine will renew it's password after 30 days so
'if a password is 60 days old then it has not been powered on and attached to the
'network for at least 30 days.

'The second inputbox is to decide if you only wish to run this in list mode, which
'will only list the machines in a text file but will not take any other action.
'If you select Yes to run in delete mode, then it will still write to the text
'file but it will also prompt you with the machine account name and its password
'age for each machine account that is greater than the age specified and ask if
'you wish to delete it from AD or not.

'Don't forget to replace "yourdom.com" with your domain name.
DomainName = "yourdom.com"

limit = inputbox("Enter max age")
DeleteMode = Msgbox("Do you wish to run in delete mode?", vbYesNo)

'****************Setup Log file******************************************************

Set fso = CreateObject("Scripting.FileSystemObject")
'The 8 in this line will append to an existing file, replace with a 2 to override
set txtStream = fso.OpenTextFile("System.txt", 8, True)
txtStream.WriteLine "Ran on " & Date & " *******************************"

'****************Setup ADSI connection and populate ADSI Collection******************

Set objADOconnADSI = CreateObject("ADODB.Connection")
objADOconnADSI.Open "Provider=ADsDSOObject;"
Set objCommandADSI = CreateObject("ADODB.Command")
objCommandADSI.ActiveConnection = objADOconnADSI
'there is a 1000 object default if these next 2 lines are omited.
objCommandADSI.Properties("Size Limit")= 10000
objCommandADSI.Properties("Page Size")= 10000
objCommandADSI.Properties("Sort on") = "sAMAccountName"
objCommandADSI.CommandText = "<LDAP://" & DomainName & ">;(objectClass=computer);sAMAccountName,pwdLastSet,name,distinguishedname;subtree"
Set objRSADSI = objCommandADSI.Execute

'Loop through record set and compare password age*************************************

do while NOT objRSADSI.EOF
if not isnull(objRSADSI.Fields("distinguishedname")) and objRSADSI.Fields("distinguishedname") <> "" then
objDate = objRSADSI.Fields("PwdLastSet")
'Go to function to make sense of the PwdLastSet value from AD for the machine account.
dtmPwdLastSet = Integer8Date(objDate, lngBias)
'calculate the current age of the password.
DiffADate = DateDiff("d", dtmPwdLastSet, Now)
'Is the password older than the specified age.
if DiffADate > int(limit) then
'Are we running in delete mode or not.
if DeleteMode = vbYes then
'Ask if this machine account should be deleted from AD.
intReturn = Msgbox("Are you sure you want to delete this computer account?", vbYesNo, "Delete " & objRSADSI.Fields("name"))
'If yes then write info to log file and then delete it else just log it.
If intReturn = vbYes Then
Set objComputer = GetObject("LDAP://" & objRSADSI.Fields("distinguishedname"))
strComputer = objComputer.CN
txtStream.WriteLine objRSADSI.Fields("name") & "," & dtmPwdLastSet & "," & DiffADate & " -- Deleted"
objComputer.DeleteObject (0)
else
txtStream.WriteLine objRSADSI.Fields("name") & "," & dtmPwdLastSet & "," & DiffADate & " -- Not Deleted"
End If
else
'If running in list only mode then just write entry to log file and move on to next record.
txtStream.WriteLine objRSADSI.Fields("name") & "," & dtmPwdLastSet & "," & DiffADate & " -- List Only"
end if
end if
end if
objRSADSI.MoveNext
loop
wscript.echo "Done!"

'I found this function and it seems to work greate. I don't pretend to fully understand it though.
'I don't know who wrote it or I would give them credit.
Function Integer8Date(objDate, lngBias)
' Function to convert Integer8 (64-bit) value to a date, adjusted for
' local time zone bias.
Dim lngAdjust, lngDate, lngHigh, lngLow
lngAdjust = lngBias
lngHigh = objDate.HighPart
lngLow = objdate.LowPart
' Account for bug in IADslargeInteger property methods.
If lngLow < 0 Then
lngHigh = lngHigh + 1
End If
If (lngHigh = 0) And (lngLow = 0) Then
lngAdjust = 0
End If
lngDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _
+ lngLow) / 600000000 - lngAdjust) / 1440
Integer8Date = CDate(lngDate)
End Function

The only thing is that when the record set of all machine accounts is created, I don't want it to include any machines whose name ends in LT (those are laptops and I don't need to know anything about them).  It doesn't sound like it should be to hard, but whne you don't do this often, you sometimes underestimte the challenges.  Any help would be appreciated...

TIA,
Susan
Avatar of 1r2d2c3po
1r2d2c3po

Fixed your code to ignore computers ending in LT.
Try it out first. Good luck

'This script enumerates the AD and creates a record set of all machine accounts
'It then loops through the record set checking the machine accounts password age
'and comparing it to the age that was entered. Any machine account that has a
'password age older than that which is specified will be listed.
'Keep in mind that by default a machine will renew it's password after 30 days so
'if a password is 60 days old then it has not been powered on and attached to the
'network for at least 30 days.

'The second inputbox is to decide if you only wish to run this in list mode, which
'will only list the machines in a text file but will not take any other action.
'If you select Yes to run in delete mode, then it will still write to the text
'file but it will also prompt you with the machine account name and its password
'age for each machine account that is greater than the age specified and ask if
'you wish to delete it from AD or not.

'Don't forget to replace "yourdom.com" with your domain name.
DomainName = "yourdomain.com"
Set regEx = New RegExp
      With regEx
      .Pattern = ".*LT$"
      .IgnoreCase = True
      .Global = True
      End With
limit = InputBox("Enter max age")
DeleteMode = MsgBox("Do you wish to run in delete mode?", vbYesNo)

'****************Setup Log file******************************************************

Set fso = CreateObject("Scripting.FileSystemObject")
'The 8 in this line will append to an existing file, replace with a 2 to override
Set txtStream = fso.OpenTextFile("System.txt", 8, True)
txtStream.WriteLine "Ran on " & Date & " *******************************"

'****************Setup ADSI connection and populate ADSI Collection******************

Set objADOconnADSI = CreateObject("ADODB.Connection")
objADOconnADSI.Open "Provider=ADsDSOObject;"
Set objCommandADSI = CreateObject("ADODB.Command")
objCommandADSI.ActiveConnection = objADOconnADSI
'there is a 1000 object default if these next 2 lines are omited.
objCommandADSI.Properties("Size Limit")= 10000
objCommandADSI.Properties("Page Size")= 10000
objCommandADSI.Properties("Sort on") = "sAMAccountName"
objCommandADSI.CommandText = "<LDAP://" & DomainName & ">;(objectClass=computer);sAMAccountName,pwdLastSet,name,distinguishedname;subtree"
Set objRSADSI = objCommandADSI.Execute

'Loop through record set and compare password age*************************************

Do While Not objRSADSI.EOF
      Set objComputer = GetObject("LDAP://" & objRSADSI.Fields("distinguishedname"))
      strComputer = objComputer.CN
      WScript.Echo strComputer
      If Not( regEx.test(strComputer) ) Then
            If Not IsNull(objRSADSI.Fields("distinguishedname")) And objRSADSI.Fields("distinguishedname") <> "" Then
                  objDate = objRSADSI.Fields("PwdLastSet")
                  'Go to function to make sense of the PwdLastSet value from AD for the machine account.
                  dtmPwdLastSet = Integer8Date(objDate, lngBias)
                  'calculate the current age of the password.
                  DiffADate = DateDiff("d", dtmPwdLastSet, Now)
                  'Is the password older than the specified age.
                  If DiffADate > Int(limit) Then
                        'Are we running in delete mode or not.
                        If DeleteMode = vbYes Then
                              'Ask if this machine account should be deleted from AD.
                              intReturn = MsgBox("Are you sure you want to delete this computer account?", vbYesNo, "Delete " & objRSADSI.Fields("name"))
                              'If yes then write info to log file and then delete it else just log it.
                              If intReturn = vbYes Then
                                    txtStream.WriteLine objRSADSI.Fields("name") & "," & dtmPwdLastSet & "," & DiffADate & " -- Deleted"
                                    objComputer.DeleteObject (0)
                              Else
                                    txtStream.WriteLine objRSADSI.Fields("name") & "," & dtmPwdLastSet & "," & DiffADate & " -- Not Deleted"
                              End If
                        Else
                              'If running in list only mode then just write entry to log file and move on to next record.
                              txtStream.WriteLine objRSADSI.Fields("name") & "," & dtmPwdLastSet & "," & DiffADate & " -- List Only"
                        End If
                  End If
            End If
      End If
objRSADSI.MoveNext
Loop
WScript.echo "Done!"

'I found this function and it seems to work greate. I don't pretend to fully understand it though.
'I don't know who wrote it or I would give them credit.
Function Integer8Date(objDate, lngBias)
' Function to convert Integer8 (64-bit) value to a date, adjusted for
' local time zone bias.
Dim lngAdjust, lngDate, lngHigh, lngLow
lngAdjust = lngBias
lngHigh = objDate.HighPart
lngLow = objDate.LowPart
' Account for bug in IADslargeInteger property methods.
If lngLow < 0 Then
lngHigh = lngHigh + 1
End If
If (lngHigh = 0) And (lngLow = 0) Then
lngAdjust = 0
End If
lngDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _
+ lngLow) / 600000000 - lngAdjust) / 1440
Integer8Date = CDate(lngDate)
End Function
ASKER CERTIFIED SOLUTION
Avatar of 1r2d2c3po
1r2d2c3po

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of nouses9

ASKER

Thank you very much!  OK, I could be doing something obviously stupid, but this is the error I received.

Failed with the following error:
Line 45
Char 1
Error Table does not exist
code 80040E37

Any thoughts?
Avatar of nouses9

ASKER

Nevermind - it was my mistake!  Thank you very much!