Dec 20 2007

How to get a computer’s Active Directory OU using VBScript

If you're new here, you may want to start with my most popular posts. Then, subscribe to my RSS feed to stay updated. Thanks for visiting!



Google Query: get computer’s ou with vbscript

I was working on a project for work today where I had to use a script to get a computer’s Active Directory OU and take an action based on the OU that the computer was in. This project will eventually become a logon script. Since our network consists of a mixture of Windows 2000 and Windows XP computers, Powershell was out of the question. It was time to turn to the tried and true VBScript and its fifty-million lines of code to accomplish one small task.

There are a couple of ways that I could query for the computer’s OU using VBScript. I could connect to Active Directory and walk the whole directory tree but this could take a while. I could dump the contents of the Active Directory tree into a text file and search on it, but that is messy. Fortunately, I found the gem of a snippet below at the Tek-Tips Forums. It was posted by PScottC.
Dim wshShell, wshNetwork
Dim strComputerName
' Create Global Objects
Set wshShell = CreateObject("WScript.Shell")
Set wshNetwork = CreateObject("WScript.Network")
' Initialize Variables
strComputerName = wshNetwork.ComputerName
wscript.echo "Computer DN: " & GetDN
Function GetDN()
' Use the NameTranslate object to convert the NT name of the computer to
' the Distinguished name required for the LDAP provider. Computer names
' must end with "$". Returns comma delimited string to calling code.
Dim objTrans, objDomain
' Constants for the NameTranslate object.
Const ADS_NAME_INITTYPE_GC = 3
Const ADS_NAME_TYPE_NT4 = 3
Const ADS_NAME_TYPE_1779 = 1
Set objTrans = CreateObject("NameTranslate")
Set objDomain = getObject("LDAP://rootDse")
objTrans.Init ADS_NAME_INITTYPE_GC, ""
objTrans.Set ADS_NAME_TYPE_NT4, wshNetwork.UserDomain & "\" _
& strComputerName & "$"
GetDN = objTrans.Get(ADS_NAME_TYPE_1779)
'Set DN to upper Case
GetDN = UCase(GetDN)
End Function

Basically, this script snippet can be used to convert an NT computer name into a the full Active Directory Distinguished Name for the computer. The following line:
wscript.echo "Computer DN: " & GetDN

Is merely there as a placeholder to show you the output of the “GetDN” function at the end of the script. You can replace it with any code you choose. If you want the script to do something different based on the computer’s OU then the natural choice would be to use the “GetDN” value in an “elseif” or “case” statement. When I have my full script complete using this code snippet, I will share the details. Until then…
Happy Coding!

Technorati Tags: , ,

No related posts.

Related posts brought to you by Yet Another Related Posts Plugin.

TAGS:

7 Comments on this post

Trackbacks

  1. Umesh said:

    Hi,
    I am looking for a script which can export computer names from an AD OU to a text file.

    Any help will be appreciated.

    Regards,
    Umesh

    January 21st, 2009 at 1:09 am
  2. Martin Pullen said:

    Thank you for this example, this solution works perfect.

    June 24th, 2009 at 4:35 am
  3. hstagner said:

    Hello Martin,

    I am glad that I could help! Thank you for reading Searchmarked.com!

    June 24th, 2009 at 3:39 pm
  4. Joel said:

    This can also be done through ADSystemInfo object in VBS.

    Set objSysInfo = CreateObject(”ADSystemInfo”)
    DN = objSysInfo.ComputerName

    WScript.Echo DN

    same work, less code :)

    June 14th, 2010 at 9:23 am
  5. Nicko said:

    If you just want the OU, not the whole Distinguished Name, then you just need to add a few more lines to Joel’s code to weed it out:

    Set objSysInfo = CreateObject(”ADSystemInfo”)
    DN = objSysInfo.ComputerName

    Set ADsPath = GetObject(”LDAP://” & DN)
    arrayOUs = Split(ADsPath.Parent, “,”)
    arrayMainOU = Split(arrayOUs(0), “=”)
    OU=arrayMainOU(1)

    Wscript.Echo “This PC is in the OU: ” & OU

    March 17th, 2011 at 3:33 am
  6. harry said:

    can anyone gimme the C# version of this script?

    It will be helpfull for me if anyone can gimme the query to see whole active directory structure of any server in network.

    August 29th, 2011 at 11:00 am
  7. Edmar said:

    Hey,

    I have a last logon script that gives me usernames, dates/times, OUs, DCs, etc…from an active directory. I am trying to also get the computer name of each of these logs, but haven’t found a way to do it yet. How can I do it based on the codes previously mentioned?
    Here is the script I’m working with:

    ‘ LastLogon.vbs
    ‘ VBScript program to determine when each user in the domain last logged
    ‘ on.

    ‘ ———————————————————————-
    ‘ Copyright (c) 2002-2010 Richard L. Mueller
    ‘ Hilltop Lab web site – http://www.rlmueller.net
    ‘ Version 1.0 – December 7, 2002
    ‘ Version 1.1 – January 17, 2003 – Account for null value for lastLogon.
    ‘ Version 1.2 – January 23, 2003 – Account for DC not available.
    ‘ Version 1.3 – February 3, 2003 – Retrieve users but not contacts.
    ‘ Version 1.4 – February 19, 2003 – Standardize Hungarian notation.
    ‘ Version 1.5 – March 11, 2003 – Remove SearchScope property.
    ‘ Version 1.6 – May 9, 2003 – Account for error in IADsLargeInteger
    ‘ property methods HighPart and LowPart.
    ‘ Version 1.7 – January 25, 2004 – Modify error trapping.
    ‘ Version 1.8 – July 6, 2007 – Modify how IADsLargeInteger interface
    ‘ is invoked.
    ‘ Version 1.9 – December 29, 2009 – Output “Never” if no date.
    ‘ Version 1.10 – November 6, 2010 – No need to set objects to Nothing.

    ‘ Because the lastLogon attribute is not replicated, every Domain
    ‘ Controller in the domain must be queried to find the latest lastLogon
    ‘ date for each user. The lastest date found is kept in a dictionary
    ‘ object. The program first uses ADO to search the domain for all Domain
    ‘ Controllers. The AdsPath of each Domain Controller is saved in an
    ‘ array. Then, for each Domain Controller, ADO is used to search the
    ‘ copy of Active Directory on that Domain Controller for all user
    ‘ objects and return the lastLogon attribute. The lastLogon attribute is
    ‘ a 64-bit number representing the number of 100 nanosecond intervals
    ‘ since 12:00 am January 1, 1601. This value is converted to a date. The
    ‘ last logon date is in UTC (Coordinated Univeral Time). It must be
    ‘ adjusted by the Time Zone bias in the machine registry to convert to
    ‘ local time.

    ‘ You have a royalty-free right to use, modify, reproduce, and
    ‘ distribute this script file in any way you find useful, provided that
    ‘ you agree that the copyright owner above has no warranty, obligations,
    ‘ or liability for such use.

    Option Explicit

    Dim objRootDSE, strConfig, adoConnection, adoCommand, strQuery
    Dim adoRecordset, objDC
    Dim strDNSDomain, objShell, lngBiasKey, lngBias, k, arrstrDCs()
    Dim strDN, dtmDate, objDate, objList, strUser
    Dim strBase, strFilter, strAttributes, lngHigh, lngLow

    ‘added variables to output to a file – by Edmar Goncalves 09/16/2011
    Dim objFSO, objFile, objCompN, strComputerName

    Set objFSO = CreateObject(”Scripting.FileSystemObject”)
    Set objFile = objFSO.CreateTextFile(”output2.txt”, 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.
    ‘ This bias changes with Daylight Savings Time.
    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 adoCommand = CreateObject(”ADODB.Command”)
    Set adoConnection = CreateObject(”ADODB.Connection”)
    adoConnection.Provider = “ADsDSOObject”
    adoConnection.Open “Active Directory Provider”
    adoCommand.ActiveConnection = adoConnection

    strBase = “”
    strFilter = “(objectClass=nTDSDSA)”
    strAttributes = “AdsPath”
    strQuery = strBase & “;” & strFilter & “;” & strAttributes & “;subtree”

    adoCommand.CommandText = strQuery
    adoCommand.Properties(”Page Size”) = 1000
    adoCommand.Properties(”Timeout”) = 60
    adoCommand.Properties(”Cache Results”) = False

    Set adoRecordset = adoCommand.Execute

    ‘ Enumerate parent objects of class nTDSDSA. Save Domain Controller
    ‘ AdsPaths in dynamic array arrstrDCs.
    k = 0
    Do Until adoRecordset.EOF
    Set objDC = _
    GetObject(GetObject(adoRecordset.Fields(”AdsPath”).Value).Parent)
    ReDim Preserve arrstrDCs(k)
    arrstrDCs(k) = objDC.DNSHostName
    k = k + 1
    adoRecordset.MoveNext
    Loop
    adoRecordset.Close

    ‘ Retrieve lastLogon attribute for each user on each Domain Controller.
    For k = 0 To Ubound(arrstrDCs)
    strBase = “”
    strFilter = “(&(objectCategory=person)(objectClass=user))”
    strAttributes = “distinguishedName, lastLogon”
    strQuery = strBase & “;” & strFilter & “;” & strAttributes _
    & “;subtree”
    adoCommand.CommandText = strQuery
    On Error Resume Next
    Set adoRecordset = adoCommand.Execute
    If (Err.Number 0) Then
    On Error GoTo 0
    ‘Bellow is commented out because it is not required
    ‘Wscript.Echo “Domain Controller not available: ” & arrstrDCs(k)
    Else
    On Error GoTo 0
    Do Until adoRecordset.EOF
    strDN = adoRecordset.Fields(”distinguishedName”).Value
    On Error Resume Next
    Set objDate = adoRecordset.Fields(”lastLogon”).Value
    If (Err.Number 0) Then
    On Error GoTo 0
    dtmDate = #1/1/1601#
    Else
    On Error GoTo 0
    lngHigh = objDate.HighPart
    lngLow = objDate.LowPart
    If (lngLow objList(strDN)) Then
    objList.Item(strDN) = dtmDate
    End If
    Else
    objList.Add strDN, dtmDate
    End If
    adoRecordset.MoveNext
    Loop
    adoRecordset.Close
    End If
    Next

    ‘ Output latest lastLogon date for each user.
    For Each strUser In objList.Keys
    If (objList.Item(strUser) = #1/1/1601#) Then
    objFile.WriteLine strUser & “,Never”
    Else
    objFile.WriteLine strUser & “,” & objList.Item(strUser)
    End If
    Next

    ‘ Clean up.
    adoConnection.Close

    Thanks,
    -Edmar G.

    September 22nd, 2011 at 9:38 am

LEAVE A COMMENT

Subscribe Form

Subscribe to Blog

Sponsors

Recent Readers

JOIN MY COMMUNITY!
                  Computers Blogs - Blog Top Sites