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
290 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
Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

 
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

How to run any project with ease

Manage projects of all sizes how you want. Great for personal to-do lists, project milestones, team priorities and launch plans.
- Combine task lists, docs, spreadsheets, and chat in one
- View and edit from mobile/offline
- Cut down on emails

Join & Write a Comment

Utilizing an array to gracefully append to a list of EmailAddresses
This is a PowerShell web interface I use to manage some task as a network administrator. Clicking an action button on the left frame will display a form in the middle frame to input some data in textboxes, process this data in PowerShell and display…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will learn additional member functions of the vector class. Specifically, the capacity and swap member functions will be introduced.

707 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

11 Experts available now in Live!

Get 1:1 Help Now