Active Directory: VBscript to enumerate the last logon of the members of a nested group with treshold

Posted March 23rd, 2010 in lastlogon by dirk adamsky

Today I had to find out the lastlogon of the members of a nested group.
Extra request was the users who’s lastlogon was longer than 90 days ago.
I solved the problem by creating a script that was a combination of earlier scripts.
The lastlogon code came from my lastlogon script, the enumeration of the group members code was taken from my enumeratenestedgroup script. The users with a lastlogon of 1-1-1601 did never log on.

Follow the next steps to run the script (no admin rights needed):

  • open your favorite text editor
  • copy and paste the script into the editor
  • change the distinguished name of strTargetGroupDN to the distinguished name of your nested group
  • optionally: change the treshold value in line 17 to the desired value (example treshold value is 90 days)
  • save the script (for example c:tempenumerate-lastlogon-nestedgroup-with-treshold.vbs)
  • open a command prompt
  • go to “c:temp”
  • give “cscript enumerate-lastlogon-nestedgroup-with-treshold.vbs” (without quotes) and enter

The script:

' Name : enumerate-lastlogon-nestedgroup-with-treshold.vbs
' Description : script to enumerate the last logon of the members of a nested group with treshold
' Author : dirk adamsky - deludi bv
' Version : 1.00
' Date : 23-03-2010
' Level : advanced

intBias = TimeZoneBias
strTargetGroupDN = "LDAP://CN=Testgroup,OU=Groups,DC=Test,DC=org"
EnumNestedgroup strTargetGroupDN
Sub EnumNestedgroup(strGroupDN)
	Set objGroup = GetObject(strGroupDN)
	For Each objMember in objGroup.Members
		If (LCase(objMember.Class) = "group") Then
			EnumNestedgroup objMember.AdsPath
		Else
			CheckLastLoginWithTreshold objMember.AdsPath, 90
		End If
	Next
	Set objGroup = Nothing
End Sub

Sub CheckLastLoginWithTreshold(strDN,intTreshold)
	Set objUser = GetObject(strDN)
	On Error resume next
	Set objDate = objUser.Get("lastLogonTimestamp")
	If (Err.Number <> 0) Then
        dtmDate = #1/1/1601#
    Else
		dtmDate = ((((objDate.Highpart * (2^32)) + objDate.LowPart)/(600000000 - intBias))/1440) + #1/1/1601#
	End If
	Set objDate = Nothing
	If DateDiff("d",dtmDate,Date) > intTreshold Then
		Wscript.Echo objUser.Displayname & " ; " & objUser.Mail & " ; " & dtmDate
	End If
	Set objUser = Nothing
End Sub

Function TimeZoneBias
	strComputer = "."
	Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\" & strComputer & "rootcimv2")
	Set colTimeZone = objWMIService.ExecQuery("Select * from Win32_TimeZone")
	For Each objTimeZone in colTimeZone
		TimeZoneBias = objTimeZone.Bias
	Next
	Set colTimeZone = Nothing
	Set objWMIService = Nothing
End Function

When you have problems/questions please post a reply.

Happy scripting.

Best regards,

Dirk Adamsky – Deludi BV

 

Active Directory: Simple VBscript to enumerate group members

Posted January 29th, 2010 in groups by dirk adamsky

Scripting sometimes seems tough to learn.
To help you I have made a couple of starter scripts.

This starter script is only 5 lines of code.
The script lists all members of a group.

Follow the next steps to make and run the script (no admin rights needed):

  • open your favorite text editor (mine is notepad++)
  • copy and paste the script into the editor (delete the line numbers)
  • open adsiedit as a user (start=>run=>adsiedit.msc)
  • browse to the group
  • rightclick the group and choose properties
  • select the distinguishedname attribute
  • copy the value of the distinguishedname attribute
  • change the value of the distinguishedname attribute in the script
  • save the script (for example c:tempenumerategroup.vbs)
  • open a command prompt
  • go to “c:temp”
  • give “cscript enumerategroup.vbs” (without quotes) and enter

When you want to save the output in a textfile give:

“cscript enumerategroup.vbs > groupname.txt” (without quotes) and enter

The script:

' Name : enumerategroup.vbs
' Description : script to enumerate group members
' Author : dirk adamsky - deludi bv
' Version : 1.10 corrected with the input of Ciobotario
' Date : 12-04-2011
' Level : beginner

Set objGroup = GetObject("LDAP://CN=test,OU=test,DC=test,DC=org")	' create the group object
For Each Member in objGroup.Members	' for  each member of the group
	WScript.echo Member.cn & " ; " & Member.displayName	' echo the common name and displayname
Next
Set objGroup = Nothing	' delete the group object and clear memory

When you have questions or problems with the script please drop a comment.

Happy scripting.

Best regards,

Dirk Adamsky – Deludi BV

Active Directory: VBScript to enumerate all groups a user is memberOf

Posted January 21st, 2010 in active directory, groups by dirk adamsky

This script enumerates all group memberships of a user.

What the script does:

  • ask for the smtp address of the user (inputbox)
  • the function GetDN gets the distinguished name
  • create the user object
  • check is there are groups that the user is memberOf
  • enumerate the group DN’s

Follow the next steps to run the script (no admin rights needed):

  • find the smtp address of the user (outlook/aduc)
  • open your favorite text editor
  • copy and paste the script into the editor
  • save the script (for example c:tempenumerategroupsfromuser.vbs)
  • open a command prompt
  • go to “c:temp”
  • give “cscript enumerategroupsfromuser.vbs” (without quotes) and enter
  • in the input box fill in the smtp address of the user
  • give “ok”

The script:

' Name : enumerategroupsfromuser.vbs
' Description : script to enumerate all groups a user is memberOf
' Author : dirk adamsky - deludi bv
' Version : 1.00
' Date : 21-01-2010

strChangeUser = InputBox("Fill in the smtp address of the user")
strUserDN = GetDN(strChangeUser)

Set objUser = GetObject("LDAP://" & strUserDN)
If Ubound(objUser.memberOf) <> "" Then
    objGroups = objUser.GetEx("memberOf")
    For Each objGroup in objGroups
        Wscript.Echo objGroup
    Next
End If
Set objUser = Nothing

Function GetDN(strMail)

    Set adoCommand = CreateObject("ADODB.Command")
    Set adoConnection = CreateObject("ADODB.Connection")
    adoConnection.Provider = "ADsDSOObject"
    adoConnection.Open "Active Directory Provider"
    adoCommand.ActiveConnection = adoConnection

    ' Search entire Active Directory domain.
    Set objRootDSE = GetObject("LDAP://RootDSE")
    strDNSDomain = objRootDSE.Get("defaultNamingContext")
    strBase = "<LDAP://" & strDNSDomain & ">"

    ' Filter on user objects.
    strFilter = "(&(objectCategory=person)(objectClass=user)(mail=" &  strMail & "))"

    ' Comma delimited list of attribute values to retrieve.
    strAttributes = "distinguishedName"

    ' Construct the LDAP syntax query.
    strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
    adoCommand.CommandText = strQuery
    adoCommand.Properties("Page Size") = 100
    adoCommand.Properties("Timeout") = 30
    adoCommand.Properties("Cache Results") = False

    ' Run the query.
    Set adoRecordset = adoCommand.Execute
    GetDN = adoRecordset.Fields("distinguishedName").Value
    ' Clean up.
    adoRecordset.Close
    adoConnection.Close

    Set adoRecordset = Nothing
    Set objRootDSE = Nothing
    Set adoConnection = Nothing
    Set adoCommand = Nothing

End Function

Active Directory: VBScript to change the groups from a user based on an example user

Posted January 14th, 2010 in active directory, groups by dirk adamsky

In large organisations users frequently change departments.
As a consequence the group memberships of the user have to change also.
Often this is achieved by using an example user.
When the example user has a lot of memberships this can be a time consuming task.
This script asks for the smtp address of the user that has to be changed,
then for the smtp address of the example user.
The function GetDN does a lookup in Active Directory for the distinguished name
of both users.
Then the old group memberships of the user are removed.
At last the group memberships of the example user are added.

Follow the next steps to run the script (admin rights needed):

  • open your favorite text editor
  • copy and paste the script into the editor
  • save the script (for example c:tempchangegroupmemberships.vbs)
  • open a command prompt with administrative rights
  • go to “c:temp”
  • give “cscript changegroupmemberships.vbs” (without quotes) and enter
  • in the input box fill in the smtp address of the user that has to be changed
  • in the next input box fill in the smtp address of the example user
  • give “ok”

The script:

' Name : changegroupmemberships.vbs
' Description : script to change group memberships based on example user
' Author : dirk adamsky - deludi bv
' Version : 1.01
' Date : 16-01-2010

strChangeUser = InputBox("Fill in the SMTP address of the user that has to be changed")
strVoorbeeldUser = InputBox("Fill in the SMTP address of the example user")
strChangeUserDN = GetDN(strChangeUser)
strVoorbeeldUserDN = GetDN(strVoorbeeldUser)
Removegroups strChangeUserDN
Addgroups strChangeUserDN, strVoorbeeldUserDN

Function GetDN(strMail)

    Set adoCommand = CreateObject("ADODB.Command")
    Set adoConnection = CreateObject("ADODB.Connection")
    adoConnection.Provider = "ADsDSOObject"
    adoConnection.Open "Active Directory Provider"
    adoCommand.ActiveConnection = adoConnection

    ' Search entire Active Directory domain.
    Set objRootDSE = GetObject("LDAP://RootDSE")
    strDNSDomain = objRootDSE.Get("defaultNamingContext")
    strBase = "<LDAP://" & strDNSDomain & ">"

    ' Filter on user objects.
    strFilter = "(&(objectCategory=person)(objectClass=user)(mail=" &  strMail & "))"

    ' Comma delimited list of attribute values to retrieve.
    strAttributes = "distinguishedName"

    ' Construct the LDAP syntax query.
    strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
    adoCommand.CommandText = strQuery
    adoCommand.Properties("Page Size") = 100
    adoCommand.Properties("Timeout") = 30
    adoCommand.Properties("Cache Results") = False

    ' Run the query.
    Set adoRecordset = adoCommand.Execute
    GetDN = adoRecordset.Fields("distinguishedName").Value
    ' Clean up.
    adoRecordset.Close
    adoConnection.Close

    Set adoRecordset = Nothing
    Set objRootDSE = Nothing
    Set adoConnection = Nothing
    Set adoCommand = Nothing

End Function

Sub Removegroups(strUserDN)
    Const ADS_PROPERTY_DELETE = 4
    Set objUser = GetObject("LDAP://" & strUserDN)
    If Ubound(objUser.memberOf) <> "" Then
        arrMemberOf = objUser.GetEx("memberOf")
        For Each Group in arrMemberOf
            Set objGroup = GetObject("LDAP://" & Group)
            objGroup.PutEx ADS_PROPERTY_DELETE, "member", Array(strUserDN)
            objGroup.SetInfo
            Set objGroup = Nothing
        Next
    End If
End Sub

Sub Addgroups(strChangeDN,strVBDN)
    On Error Resume Next
    Set objUser = GetObject("LDAP://" & strVBDN)
    arrMemberOf = objUser.GetEx("memberOf")
    For Each Group in arrMemberOf
        Set objGroup = GetObject("LDAP://" & Group)
        objGroup.Add("LDAP://" & strChangeDN)
        objGroup.SetInfo
        Set objGroup = Nothing
    Next
End Sub