Solved

Monitor a Ou and all sub Ou's and email if a computer has not contacted domain for more than 10 days. Vbs or Powershell

Posted on 2010-08-21
14
305 Views
Last Modified: 2012-05-10
Hi,

Monitor a Ou and all sub Ou's and email if a computer has not contacted domain for more than 10 days.
I want help with a script that can scan all computers and email just the machine names that has not contacted the Domain or no switched on for 10 days.

Can anyone help me with this please.

regards
Sharath
0
Comment
Question by:bsharath
  • 7
  • 6
14 Comments
 
LVL 1

Expert Comment

by:ldap389
ID: 33493039
You can do that by using Quest AD CMDlets

http://dmitrysotnikov.wordpress.com/2010/07/30/locating-obsolete-users-and-computers/

Be aware that the value used for last logon is LastLogonTimeStamp, which is replicated on every DCs, but refreshed only every 14 days. So your threshold 10 days is too short.

http://blogs.technet.com/b/askds/archive/2009/04/15/the-lastlogontimestamp-attribute-what-it-was-designed-for-and-how-it-works.aspx

If you still want to stick to 10 days you will have to query every computer in your OU by using WMI:

http://gallery.technet.microsoft.com/ScriptCenter/en-us/1918777c-1915-406f-8193-3febb6012d3c

0
 
LVL 42

Expert Comment

by:sedgwick
ID: 33494578
@bsharath

u can use the monitoring script i've posted in your other question to do that.
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 33494591
>>Monitor a Ou and all sub Ou's and email if a computer has not contacted domain for more than 10 days.

do u mean u wish to know if last logon of computer exceed 10 days?
0
 
LVL 11

Author Comment

by:bsharath
ID: 33494604
Yes last logon by any user or last contacted to the domain.

The base is to find out machines which did not switch on are offiline for more than 10 days
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 33494679
i used the script from this post: http://www.experts-exchange.com/Programming/Languages/Visual_Basic/VB_Script/Q_22904602.html

you can change DAYS_DIFF at the top of the script (currently it's 10).
const DAYS_DIFF = 10
Dim objRootDSE, strConfig, objConnection, objCommand, strQuery
Dim objRecordSet, objDC, f, fso
Dim strDNSDomain, objShell, lngBiasKey, lngBias, k, arrstrDCs()
Dim strDN, dtmDate, objDate, lngDate, objList, strUser
Dim strBase, strFilter, strAttributes, lngHigh, lngLow

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.CreateTextFile("C:\temp\Last_Logon.txt", 2, True)

' Use a dictionary object to track latest lastLogon for each user.
Set objList = CreateObject("Scripting.Dictionary")
objList.CompareMode = vbTextCompare

' Obtain local Time Zone bias from machine registry.
Set objShell = CreateObject("Wscript.Shell")
lngBiasKey = objShell.RegRead("HKLM\System\CurrentControlSet\Control\" _
  & "TimeZoneInformation\ActiveTimeBias")
If UCase(TypeName(lngBiasKey)) = "LONG" Then
  lngBias = lngBiasKey
ElseIf UCase(TypeName(lngBiasKey)) = "VARIANT()" Then
  lngBias = 0
  For k = 0 To UBound(lngBiasKey)
    lngBias = lngBias + (lngBiasKey(k) * 256 ^ k)
  Next
End If

' Determine configuration context and DNS domain from RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strConfig = objRootDSE.Get("configurationNamingContext")
strDNSDomain = objRootDSE.Get("defaultNamingContext")

' Use ADO to search Active Directory for ObjectClass nTDSDSA.
' This will identify all Domain Controllers.
Set objCommand = CreateObject("ADODB.Command")
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
objCommand.ActiveConnection = objConnection

strBase = "<LDAP://" & strConfig & ">"
strFilter = "(objectClass=nTDSDSA)"
strAttributes = "AdsPath"
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"

objCommand.CommandText = strQuery
objCommand.Properties("Page Size") = 100
objCommand.Properties("Timeout") = 60
objCommand.Properties("Cache Results") = False

Set objRecordSet = objCommand.Execute

' Enumerate parent objects of class nTDSDSA. Save Domain Controller
' AdsPaths in dynamic array arrstrDCs.
k = 0
Do Until objRecordSet.EOF
  Set objDC = _
    GetObject(GetObject(objRecordSet.Fields("AdsPath")).Parent)
  ReDim Preserve arrstrDCs(k)
  arrstrDCs(k) = objDC.DNSHostName
  k = k + 1
  objRecordSet.MoveNext
Loop
' Retrieve lastLogon attribute for each user on each Domain Controller.
For k = 0 To UBound(arrstrDCs)
  strBase = "<LDAP://" & arrstrDCs(k) & "/" & strDNSDomain & ">"
 strFilter = "(&(objectCategory=computer)(objectClass=computer))"
  strAttributes = "CN,lastLogon"
  strQuery = strBase & ";" & strFilter & ";" & strAttributes _
    & ";subtree"
  objCommand.CommandText = strQuery
  On Error Resume Next
  Err.Clear
  Set objRecordSet = objCommand.Execute
  If Err.Number <> 0 Then
    Err.Clear
    On Error GoTo 0
  Else
  Dim i 'As Integer
    On Error GoTo 0
    Do Until objRecordSet.EOF
   
      strDN = objRecordSet.Fields("CN")
      lngDate = objRecordSet.Fields("lastLogon")
      On Error Resume Next
      Err.Clear
      Set objDate = lngDate

      If Err.Number <> 0 Then
        Err.Clear
        dtmDate = #1/1/1601#
      Else
        lngHigh = objDate.HighPart
        lngLow = objDate.LowPart
        If lngLow < 0 Then
          lngHigh = lngHigh + 1
        End If
        If (lngHigh = 0) And (lngLow = 0) Then
          dtmDate = #1/1/1601#
        Else
          dtmDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _
            + lngLow) / 600000000 - lngBias) / 1440
        End If
      End If
      On Error GoTo 0
      If objList.Exists(strDN) Then
        If dtmDate > objList(strDN) Then
          objList(strDN) = dtmDate
        End If
      Else
        objList.Add strDN, dtmDate
      End If
      objRecordSet.MoveNext
    Loop
  End If
Next

For Each strUser In objList
	objDate = CDate(objList(strUser))
	diffDays = DateDiff("d",objDate,Date)
	If diffDays > DAYS_DIFF Then 
		objTextFile.Write strUser & ";" & objList(strUser)
		objTextFile.Writeblanklines (1)
	End If       
Next

objConnection.Close
Set objRootDSE = Nothing
Set objConnection = Nothing
Set objCommand = Nothing
Set objRecordSet = Nothing
Set objDC = Nothing
Set objDate = Nothing
Set objList = Nothing
Set objShell = Nothing

NotifyByEmail "Machines LastLogon Email Notification", objFSO.OpenTextFile("C:\temp\Last_Logon.txt").ReadAll

MsgBox "done"

sub NotifyByEmail(strSubject, strResult)
	Dim ToAddress
	Dim MessageSubject
	Dim MessageBody
	Dim MessageAttachment
	dim myRecipient,olMailItem

	Dim ol, ns, newMail

	ToAddress = "xxx.yyy@zzz.com"
	MessageSubject = strSubject
	MessageBody = strResult

	Set ol = WScript.CreateObject("Outlook.Application")
	Set ns = ol.getNamespace("MAPI")
	ns.logon "","",true,false
	Set newMail = ol.CreateItem(olMailItem)
	newMail.Subject = MessageSubject
	newMail.Body = MessageBody & vbCrLf

	' validate the recipient, just in case...
	Set myRecipient = ns.CreateRecipient(ToAddress)
	myRecipient.Resolve
	If Not myRecipient.Resolved Then
	   MsgBox "unknown recipient"
	Else
	   newMail.Recipients.Add(myRecipient)
	   newMail.Send
	End If

	Set ol = Nothing

end sub

Open in new window

0
 
LVL 42

Expert Comment

by:sedgwick
ID: 33494686
do you wish to integrate this script with the previous one you closed (Audit AD of users)?
0
 
LVL 11

Author Comment

by:bsharath
ID: 33494694
Thanks sedgwick
Will it do all that it used to do before as well.?
0
Best Practices: Disaster Recovery Testing

Besides backup, any IT division should have a disaster recovery plan. You will find a few tips below relating to the development of such a plan and to what issues one should pay special attention in the course of backup planning.

 
LVL 11

Author Comment

by:bsharath
ID: 33494698
Ok i guess its a seperate code for this task. let me check this. If it works i shall see if i need it integrated thansk
0
 
LVL 11

Author Comment

by:bsharath
ID: 33494700
I need to restrict to query all computers in a specific Root OU
0
 
LVL 42

Expert Comment

by:sedgwick
ID: 33494714
done
const DAYS_DIFF = 10
const ROOT_OU = "cn=computers"

Dim objRootDSE, strConfig, objConnection, objCommand, strQuery
Dim objRecordSet, objDC, f, fso
Dim strDNSDomain, objShell, lngBiasKey, lngBias, k, arrstrDCs()
Dim strDN, dtmDate, objDate, lngDate, objList, strUser
Dim strBase, strFilter, strAttributes, lngHigh, lngLow

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.CreateTextFile("C:\temp\Last_Logon.txt", 2, True)

' Use a dictionary object to track latest lastLogon for each user.
Set objList = CreateObject("Scripting.Dictionary")
objList.CompareMode = vbTextCompare

' Obtain local Time Zone bias from machine registry.
Set objShell = CreateObject("Wscript.Shell")
lngBiasKey = objShell.RegRead("HKLM\System\CurrentControlSet\Control\" _
  & "TimeZoneInformation\ActiveTimeBias")
If UCase(TypeName(lngBiasKey)) = "LONG" Then
  lngBias = lngBiasKey
ElseIf UCase(TypeName(lngBiasKey)) = "VARIANT()" Then
  lngBias = 0
  For k = 0 To UBound(lngBiasKey)
    lngBias = lngBias + (lngBiasKey(k) * 256 ^ k)
  Next
End If

' Determine configuration context and DNS domain from RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strConfig = objRootDSE.Get("configurationNamingContext")
strDNSDomain = objRootDSE.Get("defaultNamingContext")

' Use ADO to search Active Directory for ObjectClass nTDSDSA.
' This will identify all Domain Controllers.
Set objCommand = CreateObject("ADODB.Command")
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
objCommand.ActiveConnection = objConnection

strBase = "<LDAP://" & strConfig & ">"
strFilter = "(objectClass=nTDSDSA)"
strAttributes = "AdsPath"
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"

objCommand.CommandText = strQuery
objCommand.Properties("Page Size") = 100
objCommand.Properties("Timeout") = 60
objCommand.Properties("Cache Results") = False

Set objRecordSet = objCommand.Execute

' Enumerate parent objects of class nTDSDSA. Save Domain Controller
' AdsPaths in dynamic array arrstrDCs.
k = 0
Do Until objRecordSet.EOF
  Set objDC = _
    GetObject(GetObject(objRecordSet.Fields("AdsPath")).Parent)
  ReDim Preserve arrstrDCs(k)
  arrstrDCs(k) = objDC.DNSHostName
  k = k + 1
  objRecordSet.MoveNext
Loop
' Retrieve lastLogon attribute for each user on each Domain Controller.
For k = 0 To UBound(arrstrDCs)

	if ROOT_OU <> "" then
		strBase = "<LDAP://" & ROOT_OU & "," & arrstrDCs(k) & "/" & strDNSDomain & ">"
	else
		strBase = "<LDAP://" & arrstrDCs(k) & "/" & strDNSDomain & ">"
	end if

	  
 strFilter = "(&(objectCategory=computer)(objectClass=computer))"
  strAttributes = "CN,lastLogon"
  strQuery = strBase & ";" & strFilter & ";" & strAttributes _
    & ";subtree"
  objCommand.CommandText = strQuery
  On Error Resume Next
  Err.Clear
  Set objRecordSet = objCommand.Execute
  If Err.Number <> 0 Then
    Err.Clear
    On Error GoTo 0
  Else
  Dim i 'As Integer
    On Error GoTo 0
    Do Until objRecordSet.EOF
   
      strDN = objRecordSet.Fields("CN")
      lngDate = objRecordSet.Fields("lastLogon")
      On Error Resume Next
      Err.Clear
      Set objDate = lngDate

      If Err.Number <> 0 Then
        Err.Clear
        dtmDate = #1/1/1601#
      Else
        lngHigh = objDate.HighPart
        lngLow = objDate.LowPart
        If lngLow < 0 Then
          lngHigh = lngHigh + 1
        End If
        If (lngHigh = 0) And (lngLow = 0) Then
          dtmDate = #1/1/1601#
        Else
          dtmDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _
            + lngLow) / 600000000 - lngBias) / 1440
        End If
      End If
      On Error GoTo 0
      If objList.Exists(strDN) Then
        If dtmDate > objList(strDN) Then
          objList(strDN) = dtmDate
        End If
      Else
        objList.Add strDN, dtmDate
      End If
      objRecordSet.MoveNext
    Loop
  End If
Next

For Each strUser In objList
	objDate = CDate(objList(strUser))
	diffDays = DateDiff("d",objDate,Date)
	If diffDays > DAYS_DIFF Then 
		objTextFile.Write strUser & ";" & objList(strUser)
		objTextFile.Writeblanklines (1)
	End If       
Next

objConnection.Close
Set objRootDSE = Nothing
Set objConnection = Nothing
Set objCommand = Nothing
Set objRecordSet = Nothing
Set objDC = Nothing
Set objDate = Nothing
Set objList = Nothing
Set objShell = Nothing

NotifyByEmail "Machines LastLogon Email Notification", objFSO.OpenTextFile("C:\temp\Last_Logon.txt").ReadAll

MsgBox "done"

sub NotifyByEmail(strSubject, strResult)
	Dim ToAddress
	Dim MessageSubject
	Dim MessageBody
	Dim MessageAttachment
	dim myRecipient,olMailItem

	Dim ol, ns, newMail

	ToAddress = "xxx.yyy@zzz.com"
	MessageSubject = strSubject
	MessageBody = strResult

	Set ol = WScript.CreateObject("Outlook.Application")
	Set ns = ol.getNamespace("MAPI")
	ns.logon "","",true,false
	Set newMail = ol.CreateItem(olMailItem)
	newMail.Subject = MessageSubject
	newMail.Body = MessageBody & vbCrLf

	' validate the recipient, just in case...
	Set myRecipient = ns.CreateRecipient(ToAddress)
	myRecipient.Resolve
	If Not myRecipient.Resolved Then
	   MsgBox "unknown recipient"
	Else
	   newMail.Recipients.Add(myRecipient)
	   newMail.Send
	End If

	Set ol = Nothing

end sub

Open in new window

0
 
LVL 42

Expert Comment

by:sedgwick
ID: 33494716
change ROOT_OU to whatever required
0
 
LVL 11

Author Comment

by:bsharath
ID: 33494741
it runs and completes in a secound and a email i get with body of it with just this

ÿþ
0
 
LVL 42

Accepted Solution

by:
sedgwick earned 500 total points
ID: 33494834
fixed
const DAYS_DIFF = 10
const ROOT_OU = "cn=computers"
const LOG_FILE = "C:\temp\Last_Logon.log"

Dim objRootDSE, strConfig, objConnection, objCommand, strQuery
Dim objRecordSet, objDC, f, fso
Dim strDNSDomain, objShell, lngBiasKey, lngBias, k, arrstrDCs()
Dim strDN, dtmDate, objDate, lngDate, objList, strUser
Dim strBase, strFilter, strAttributes, lngHigh, lngLow, logContent

Set objFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = objFSO.CreateTextFile(LOG_FILE, 2, True)

' Use a dictionary object to track latest lastLogon for each user.
Set objList = CreateObject("Scripting.Dictionary")
objList.CompareMode = vbTextCompare

' Obtain local Time Zone bias from machine registry.
Set objShell = CreateObject("Wscript.Shell")
lngBiasKey = objShell.RegRead("HKLM\System\CurrentControlSet\Control\" _
  & "TimeZoneInformation\ActiveTimeBias")
If UCase(TypeName(lngBiasKey)) = "LONG" Then
  lngBias = lngBiasKey
ElseIf UCase(TypeName(lngBiasKey)) = "VARIANT()" Then
  lngBias = 0
  For k = 0 To UBound(lngBiasKey)
    lngBias = lngBias + (lngBiasKey(k) * 256 ^ k)
  Next
End If

' Determine configuration context and DNS domain from RootDSE object.
Set objRootDSE = GetObject("LDAP://RootDSE")
strConfig = objRootDSE.Get("configurationNamingContext")
strDNSDomain = objRootDSE.Get("defaultNamingContext")

' Use ADO to search Active Directory for ObjectClass nTDSDSA.
' This will identify all Domain Controllers.
Set objCommand = CreateObject("ADODB.Command")
Set objConnection = CreateObject("ADODB.Connection")
objConnection.Provider = "ADsDSOObject"
objConnection.Open "Active Directory Provider"
objCommand.ActiveConnection = objConnection

strBase = "<LDAP://" & strConfig & ">"
strFilter = "(objectClass=nTDSDSA)"
strAttributes = "AdsPath"
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"

objCommand.CommandText = strQuery
objCommand.Properties("Page Size") = 100
objCommand.Properties("Timeout") = 60
objCommand.Properties("Cache Results") = False

Set objRecordSet = objCommand.Execute

' Enumerate parent objects of class nTDSDSA. Save Domain Controller
' AdsPaths in dynamic array arrstrDCs.
k = 0
Do Until objRecordSet.EOF
  Set objDC = _
    GetObject(GetObject(objRecordSet.Fields("AdsPath")).Parent)
  ReDim Preserve arrstrDCs(k)
  arrstrDCs(k) = objDC.DNSHostName
  k = k + 1
  objRecordSet.MoveNext
Loop
' Retrieve lastLogon attribute for each user on each Domain Controller.
For k = 0 To UBound(arrstrDCs)

	if ROOT_OU <> "" then
		strBase = "<LDAP://" & arrstrDCs(k) & "/" & ROOT_OU & "," & strDNSDomain & ">"
	else
		strBase = "<LDAP://" & arrstrDCs(k) & "/" & strDNSDomain & ">"
	end if
	  
 strFilter = "(&(objectCategory=computer)(objectClass=computer))"
  strAttributes = "CN,lastLogon"
  strQuery = strBase & ";" & strFilter & ";" & strAttributes _
    & ";subtree"

  objCommand.CommandText = strQuery
  On Error Resume Next
  Err.Clear
  Set objRecordSet = objCommand.Execute
  If Err.Number <> 0 Then
    Err.Clear
    On Error GoTo 0
  Else
  Dim i 'As Integer
    On Error GoTo 0
    Do Until objRecordSet.EOF
   
      strDN = objRecordSet.Fields("CN")
      lngDate = objRecordSet.Fields("lastLogon")
      On Error Resume Next
      Err.Clear
      Set objDate = lngDate

      If Err.Number <> 0 Then
        Err.Clear
        dtmDate = #1/1/1601#
      Else
        lngHigh = objDate.HighPart
        lngLow = objDate.LowPart
        If lngLow < 0 Then
          lngHigh = lngHigh + 1
        End If
        If (lngHigh = 0) And (lngLow = 0) Then
          dtmDate = #1/1/1601#
        Else
          dtmDate = #1/1/1601# + (((lngHigh * (2 ^ 32)) _
            + lngLow) / 600000000 - lngBias) / 1440
        End If
      End If
      On Error GoTo 0
      If objList.Exists(strDN) Then
        If dtmDate > objList(strDN) Then
          objList(strDN) = dtmDate
        End If
      Else
        objList.Add strDN, dtmDate
      End If
      objRecordSet.MoveNext
    Loop
  End If
Next

For Each strUser In objList
	objDate = CDate(objList(strUser))
	diffDays = DateDiff("d",objDate,Date)
	If diffDays > DAYS_DIFF Then 
		logContent = logContent &  strUser & ";" & objList(strUser) & vbNewLine
	End If       
Next

objTextFile.WriteLine logContent
objTextFile.Close

NotifyByEmail "Machines LastLogon Email Notification", logContent

objConnection.Close
Set objRootDSE = Nothing
Set objConnection = Nothing
Set objCommand = Nothing
Set objRecordSet = Nothing
Set objDC = Nothing
Set objDate = Nothing
Set objList = Nothing
Set objShell = Nothing

MsgBox "done"

sub NotifyByEmail(strSubject, strResult)
	Dim ToAddress
	Dim MessageSubject
	Dim MessageBody
	Dim MessageAttachment
	dim myRecipient,olMailItem

	Dim ol, ns, newMail

	ToAddress = "xxx.yyy@zzz.com"
	MessageSubject = strSubject
	MessageBody = strResult

	Set ol = WScript.CreateObject("Outlook.Application")
	Set ns = ol.getNamespace("MAPI")
	ns.logon "","",true,false
	Set newMail = ol.CreateItem(olMailItem)
	newMail.Subject = MessageSubject
	newMail.Body = MessageBody & vbCrLf

	' validate the recipient, just in case...
	Set myRecipient = ns.CreateRecipient(ToAddress)
	myRecipient.Resolve
	If Not myRecipient.Resolved Then
	   MsgBox "unknown recipient"
	Else
	   newMail.Recipients.Add(myRecipient)
	   newMail.Send
	End If

	Set ol = Nothing

end sub

Open in new window

0
 
LVL 11

Author Comment

by:bsharath
ID: 33494912
Thanks a lot works perfect
0

Featured Post

Is Your Active Directory as Secure as You Think?

More than 75% of all records are compromised because of the loss or theft of a privileged credential. Experts have been exploring Active Directory infrastructure to identify key threats and establish best practices for keeping data safe. Attend this month’s webinar to learn more.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Microsoft Windows Server Update Service (WSUS) is free for everyone, but it lacks of some desirable features like send an e-mail to the administrator with the status of all computers on the WSUS server. This article is based on my PowerShell script …
A brief introduction to what I consider to be the best editor for PowerShell.
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The goal of the video will be to teach the user the concept of local variables and scope. An example of a locally defined variable will be given as well as an explanation of what scope is in C++. The local variable and concept of scope will be relat…

911 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

16 Experts available now in Live!

Get 1:1 Help Now