The next script for today enumerates all hidden distribution groups.
This is done by an ADO query with a filter on groups, msExchHideFromAddressLists and mail property.

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

  • copy and paste the script in your favorite text editor
  • save the script (for example c:\temp\hidden-distribution-groups.vbs)
  • open a command prompt
  • go to “c:\temp”
  • give “cscript hidden-distribution-groups.vbs” (without quotes) and enter

The script:

' Name : hidden-distribution-groups.vbs
' Description : script to enumerate all distribution groups that are hidden in the Global Address List
' Author : dirk adamsky - deludi bv
' Version : 1.00
' Date : 15-07-2010
' Level: intermediate

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

Set objRootDSE = GetObject("LDAP://RootDSE")
strBase = "<LDAP://" & objRootDSE.Get("defaultNamingContext") & ">"
strFilter = "(&(objectCategory=group)(msExchHideFromAddressLists=TRUE)(mail=*))"
strAttributes = "displayname, mail, msExchHideFromAddressLists"

strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False

Set objRecordset = adoCommand.Execute

objRecordSet.MoveFirst
Do Until objRecordSet.EOF
	Wscript.Echo objRecordSet.Fields("displayname").Value & " ; " & objRecordSet.Fields("mail").Value
	objRecordSet.MoveNext
Loop

Set objRecordset = Nothing
Set objRootDSE = Nothing
Set adoConnection = Nothing
Set adoCommand = Nothing

When you have problems/questions please post a reply or give a ‘star’ rating.

Happy scripting.

Best regards,

Dirk Adamsky – Deludi BV

VN:F [1.9.4_1102]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.4_1102]
Rating: 0 (from 0 votes)

Script for today is about members of the remote desktop users local group.
This group exists on all servers except the domain controllers.
The script can take a long time in large domains because it connects each server separately.

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

  • copy and paste the script in your favorite text editor
  • save the script (for example c:\temp\remotedesktopusers.vbs)
  • open a command prompt
  • go to “c:\temp”
  • give “cscript remotedesktopusers.vbs” (without quotes) and enter

The script:

' Name : remotedesktopusers.vbs
' Description : script to enumerate the members of remote desktop users group of all servers
' Author : dirk adamsky - deludi bv
' Version : 1.00
' Date : 23-04-2010
' Level: intermediate

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

Set objRootDSE = GetObject("LDAP://RootDSE")
strDNSDomain = objRootDSE.Get("defaultNamingContext")
strBase = "<LDAP://" & strDNSDomain & ">"

strFilter = "(&(objectCategory=computer)(operatingSystem=*server*))"

strAttributes = "name,distinguishedName"
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False
Set adoRecordset = adoCommand.Execute

Do Until adoRecordset.EOF
	strHostname = adoRecordset.Fields("name").Value
	If CheckStatus(strHostname) = True Then
		If Instr(adoRecordset.Fields("distinguishedName").Value,"Domain Controllers") = 0 Then
			Set objGroup = GetObject("WinNT://" & strHostname & "/Remote Desktop Users,group")
			For Each Member In objGroup.Members
				wscript.echo strHostname & " has " & Member.Name & " in the remote desktop users group"
			Next
			Set objGroup = Nothing
		End If
	End If
	adoRecordset.MoveNext
Loop

adoRecordset.Close
adoConnection.Close

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

Function CheckStatus(strAddress)
	Dim objPing, objRetStatus
	Set objPing = GetObject("winmgmts:{impersonationLevel=impersonate}").ExecQuery _
      ("select * from Win32_PingStatus where address = '" & strAddress & "'")
	For Each objRetStatus In objPing
        If IsNull(objRetStatus.StatusCode) Or objRetStatus.StatusCode <> 0 Then
			CheckStatus = False
        Else
			CheckStatus = True
        End If
    Next
	Set objPing = Nothing
End Function

When you have problems/questions please post a reply or give a ‘star’ rating.

Happy scripting.

Best regards,

Dirk Adamsky – Deludi BV

VN:F [1.9.4_1102]
Rating: 10.0/10 (2 votes cast)
VN:F [1.9.4_1102]
Rating: 0 (from 0 votes)

Ok let’s do another script.
The script shows you who is connected to a domain controller.
This is accomplished through the WMI class “Win32_ServerSession”.
Enumerated are: prew2k username, hostname, workstation os and the time connected.
The script needs to be run as admin because of the wmi connection to the server.

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

  • copy and paste the script in your favorite text editor
  • change the value of strServer to the name of your domain controller (example: strServer = “srv001″)
  • save the script (for example c:\temp\connected.vbs)
  • open a command prompt
  • go to “c:\temp”
  • give “cscript connected.vbs” (without quotes) and enter

The script:

' Name : connected.vbs
' Description : script to enumerate who is connected to a domain controller
' Author : dirk adamsky - deludi bv
' Version : 1.00
' Date : 22-04-2010
' Level: intermediate

strServer = "domaincontroller"
Set objWMI = GetObject("winmgmts://" & strServer & "/root\cimv2")
Set objInstances = objWMI.InstancesOf("Win32_ServerSession",48)

For Each objInstance in objInstances
    With objInstance
        WScript.Echo .UserName & " ; " & .ComputerName & " ; " & .ClientType &_
		.Name & " ; " & Round(.ActiveTime/60,0) & " minutes connected"
    End With
Next

Set objInstances = Nothing
Set objWMI = Nothing

When you have problems/questions please post a reply or give a ‘star’ rating.

Happy scripting.

Best regards,

Dirk Adamsky – Deludi BV

VN:F [1.9.4_1102]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.4_1102]
Rating: 0 (from 0 votes)

Ok let’s do another nested group script.
This script enumerates the lastlogon of all members of a nested group.
Attention: the lastlogontimestamp attribute has a treshold of 2 weeks, so recently added users might not occur in the output of the script.

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

  • copy and paste the script in your favorite text editor
  • change the distinguished name of the nested group to your group distinguished name
  • save the script (for example c:\temp\enumeratenestedgrouplastlogon.vbs)
  • open a command prompt
  • go to “c:\temp”
  • give “cscript enumeratenestedgrouplastlogon.vbs” (without quotes) and enter

The script:

' Name : enumeratenestedgrouplastlogon.vbs
' Description : script to enumerate the lastlogon of all users of a nested group
' Author : dirk adamsky - deludi bv
' Version : 1.00
' Date : 13-04-2010
' Level: intermediate

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
		ElseIf TypeName(objMember.lastLogonTimeStamp) <> "Empty" Then
			Set objDate = objMember.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
			Wscript.Echo objMember.DisplayName & " ; " & objMember.Mail & " ; " & dtmDate
		End If
	Next
	Set objGroup = Nothing
End Sub

Function TimeZoneBias
	strComputer = "."
	Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
	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 or give a ‘star’ rating.

Happy scripting.

Best regards,

Dirk Adamsky – Deludi BV

VN:F [1.9.4_1102]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.4_1102]
Rating: 0 (from 0 votes)

Script for today is a mutation of my previous enumerate nested group script.
The script enumerates all nested group users with a citrix token.

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

  • copy and paste the script in your favorite text editor
  • change the distinguished name of the nested group to your group distinguished name
  • save the script (for example c:\temp\enumeratenestedgrouptokens.vbs)
  • open a command prompt
  • go to “c:\temp”
  • give “cscript enumeratenestedgrouptokens.vbs” (without quotes) and enter

The script:

' Name : enumeratenestedgrouptokens.vbs
' Description : script to enumerate the citrix tokens of a nested group
' Author : dirk adamsky - deludi bv
' Version : 1.00
' Date : 13-04-2010
' Level: intermediate
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
		ElseIf objMember.[securecomputingCom2000-SafeWord-UserID] <> "" Then
			Wscript.Echo objMember.DisplayName & " ; " & objMember.Mail & " ; " & objMember.[securecomputingCom2000-SafeWord-UserID]
		End If
	Next
	Set objGroup = Nothing
End Sub

When you have problems/questions please post a reply or give a ‘star’ rating.

Happy scripting.

Best regards,

Dirk Adamsky – Deludi BV

VN:F [1.9.4_1102]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.4_1102]
Rating: 0 (from 0 votes)

This script disables outlook mobile access for all users in your company, this can be useful when oma access has to be restricted to a certain amount of users. Later I will post a script to enable oma for a limited amount of users based on an excel sheet with smtp addresses.
The script is created for a win2003/exchange2003 environment.

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:\temp\disableoma.vbs)
* open a command prompt
* go to “c:\temp”
* give “cscript disableoma.vbs” (without quotes) and enter

The script:

' Name : disableoma.vbs
' Description : script to disable Outlook Mobile Access (oma) for all users in your company
' Author : dirk adamsky - deludi bv
' Version : 1.00
' Date : 31-03-2010
' Level : intermediate

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

Set objRootDSE = GetObject("LDAP://RootDSE")
strBase = "<LDAP://" & objRootDSE.Get("defaultNamingContext") & ">"
strFilter = "(&(objectCategory=person)(objectClass=user)(mail=*)(!(msExchOmaAdminWirelessEnable=7)))"
strAttributes = "mail,msExchOmaAdminWirelessEnable"

strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
adoCommand.CommandText = strQuery
adoCommand.Properties("Page Size") = 100
adoCommand.Properties("Timeout") = 30
adoCommand.Properties("Cache Results") = False

Set adoRecordset = adoCommand.Execute

Do Until adoRecordset.EOF
	Set objUser = GetObject ("LDAP://" & adoRecordset.Fields("distinguishedName").Value)
	objUser.Put "msExchOmaAdminWirelessEnable", "7"
    objUser.Setinfo
	Set objUser = Nothing
	Logprint "outlook mobile access is disabled for ; " & adoRecordset.Fields("mail").Value
	adoRecordset.MoveNext
Loop

adoRecordset.Close
adoConnection.Close

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

Function LogPrint(Message)
Const ForAppending = 8
strDate = Replace(Date,"/","-")

Set ObjFSO = CreateObject("Scripting.FileSystemObject")
Set objTextFile = ObjFSO.OpenTextFile(strDate & "-OmaDisabledUsers.csv", ForAppending, True)
    objTextFile.WriteLine Message
    objTextFile.Close
Set objTextFile = Nothing
Set ObjFSO = Nothing
End Function

When you have problems/questions please post a reply, you can also rate the script.

Happy scripting.

Best regards,

Dirk Adamsky – Deludi BV

VN:F [1.9.4_1102]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.4_1102]
Rating: 0 (from 0 votes)

Last friday I got a question from Marten on the number of users that a subgroup contains.
I have made a small mutation of the previous script to achieve this. The output of the script now contains the number of users in each subgroup.

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
  • save the script (for example c:\temp\countgroupmembershipnestedgroup.vbs)
  • open a command prompt
  • go to “c:\temp”
  • give “cscript countgroupmembershipnestedgroup.vbs” (without quotes) and enter

The script:

' Name : countgroupmembershipnestedgroup.vbs
' Description : script to count the number of users in subgroups of a nested distribution group
' Author : dirk adamsky - deludi bv
' Version : 1.00
' Date : 30-03-2010
' Level : intermediate

Set objDictionary = CreateObject("Scripting.Dictionary")
strTargetGroupDN = "LDAP://CN=SW (Alle Medewerkers),OU=DistributieGroepen,OU=Groepen,DC=domstad,DC=org"
Call EnumNestedgroup(strTargetGroupDN)

Sub EnumNestedgroup(strGroupDN)
	Set objGroup = GetObject(strGroupDN)
	For Each objMember in objGroup.Members
		If (LCase(objMember.Class) = "group") Then
			Call EnumNestedgroup(objMember.AdsPath)
		Else
			If objDictionary.Exists(objGroup.DisplayName) Then
				objDictionary.Item(objGroup.DisplayName) = objDictionary.Item(objGroup.DisplayName) + 1
			Else
				objDictionary.Add objGroup.DisplayName, 1
			End If
		End If
	Next
	Set objGroup = Nothing
End Sub

For Each strKey in objDictionary.Keys
	If objDictionary.Item(strKey) > 1 Then
		Wscript.Echo strKey & " contains ; " & objDictionary.Item(strKey) & " ; users"
	End If
Next

Set objDictionary = Nothing

When you have problems/questions please post a reply.

Happy scripting.

Best regards,

Dirk Adamsky – Deludi BV

VN:F [1.9.4_1102]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.4_1102]
Rating: 0 (from 0 votes)

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:\temp\enumerate-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 & "\root\cimv2")
	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

VN:F [1.9.4_1102]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.4_1102]
Rating: 0 (from 0 votes)

Outlook web access is incorporated in Active Directory through the user attribute “protocolSettings”.
Default setting is for owa is ‘enabled’. The attribute ‘protocolSettings’ has no specific entry for owa at this stage. Only when owa is explicitly denied for a specific user an entry is added, the value of this entry is:
HTTP§0§1§§§§§§. When owa is enabled again for this user the value changes to HTTP§0§0§§§§§§.
This script is tested for outlook/exchange2003.

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
* save the script (for example c:\temp\owausers.vbs)
* open a command prompt
* go to “c:\temp”
* give “cscript owausers.vbs” (without quotes) and enter

The script:

' Name : owausers.vbs
' Description : script to enumerate all users with Outlook Web Access (owa)
' Author : dirk adamsky - deludi bv
' Version : 1.00
' Date : 22-03-2010
' Level : intermediate

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

Set objRootDSE = GetObject("LDAP://RootDSE")
strBase = "<LDAP://" & objRootDSE.Get("defaultNamingContext") & ">"
Set objRootDSE = Nothing

strFilter = "(&(objectCategory=person)(objectClass=user)(mail=*)(!(cn=systemmailbox*)))"
strAttributes = "distinguishedname, mail, displayname, protocolSettings"
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
objCommand.CommandText = strQuery
objCommand.Properties("Page Size") = 100
objCommand.Properties("Timeout") = 30
objCommand.Properties("Cache Results") = False

Set objRecordSet = objCommand.Execute
Do Until objRecordSet.EOF
	strOwa = "Yes"
	If TypeName(objRecordSet.Fields("protocolSettings").value) = "Variant()" Then
		arrProtocolsettings = objRecordSet.Fields("protocolSettings").value
		For Each Protocol in arrProtocolsettings
			If Protocol = "HTTP§0§1§§§§§§" Then
				strOWA = "No"
			End If
		Next
	End If
	Wscript.Echo objRecordSet.Fields("displayname").Value & " uses outlook web access = " & strOwa
	objRecordSet.MoveNext
Loop

objRecordSet.Close
objConnection.Close

Set objRecordSet = Nothing
Set objConnection = Nothing
Set objCommand = Nothing

When you have problems/questions please post a reply, you can also rate the script.

Happy scripting.

Best regards,

Dirk Adamsky – Deludi BV

VN:F [1.9.4_1102]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.4_1102]
Rating: 0 (from 0 votes)

For most system administrators cleaning up Active Directory is not their favorite thing.
This script helps you by enumerating all empty groups, so you can remove them (manually).

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
* save the script (for example c:\temp\emptygroups.vbs)
* open a command prompt
* go to “c:\temp”
* give “cscript emptygroups.vbs” (without quotes) and enter

The script:

' Name : emptygroups.vbs
' Description : script to enumerate all empty groups
' Author : dirk adamsky - deludi bv
' Version : 1.00
' Date : 18-03-2010
' Level : intermediate

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

Set objRootDSE = GetObject("LDAP://RootDSE")
strBase = "<LDAP://" & objRootDSE.Get("defaultNamingContext") & ">"
Set objRootDSE = Nothing

strFilter = "(&(objectCategory=group)(!member=*))"
strAttributes = "name"
strQuery = strBase & ";" & strFilter & ";" & strAttributes & ";subtree"
objCommand.CommandText = strQuery
objCommand.Properties("Page Size") = 100
objCommand.Properties("Timeout") = 30
objCommand.Properties("Cache Results") = False

Set objRecordSet = objCommand.Execute
Do Until objRecordSet.EOF
	Wscript.Echo objRecordSet.Fields("name").Value
	objRecordSet.MoveNext
Loop

objRecordSet.Close
objConnection.Close

Set objRecordSet = Nothing
Set objConnection = Nothing
Set objCommand = Nothing

When you have problems/questions please post a reply, you can also rate the script.

Happy scripting.

Best regards,

Dirk Adamsky – Deludi BV

VN:F [1.9.4_1102]
Rating: 0.0/10 (0 votes cast)
VN:F [1.9.4_1102]
Rating: 0 (from 0 votes)
© 2010 Dirk Adamsky Scripting Blog Suffusion WordPress theme by Sayontan Sinha