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
336 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
Are your AD admin tools letting you down?

Managing Active Directory can get complicated.  Often, the native tools for managing AD are just not up to the task.  The largest Active Directory installations in the world have relied on one tool to manage their day-to-day administration tasks: Hyena. Start your trial today.

 
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
 
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

Free Tool: Site Down Detector

Helpful to verify reports of your own downtime, or to double check a downed website you are trying to access.

One of a set of tools we are providing to everyone as a way of saying thank you for being a part of the community.

Question has a verified solution.

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

A project that enables an administrator to perform actions within a user session context not just at the time of login but any time later on day(s) or week(s) later.
Previously, on our Nano Server Deployment series, we've created a new nano server image and deployed it on a physical server in part 2. Now we will go through configuration.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
This video will show you how to get GIT to work in Eclipse.   It will walk you through how to install the EGit plugin in eclipse and how to checkout an existing repository.

752 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