Guy’s Scripting Ezine 138 – Scripting Groups with ‘Join’

 Scripting Groups with the VBScript ‘Join’ Command

This ezine will help you decide the best strategy for controlling a user’s environment based on group membership.  We will examine the use of the ‘Join’ command in VBScript and also discuss alternatives such as Group Policy.  I thank Charles Trevor for supplying the idea and the example script.

Topics

 ♣

This Week’s Secret

Avoid groups.  This is indeed strange advice for an article on scripting group membership.  Nevertheless, my recommendation remains to research such as a group policy before you start writing VBScript commands.  After all, think of that name, why is it called GROUP policy, not User Policy?  Even in cases where there is no suitable group policy, with a little lateral thinking you may be able to find a workaround and thus avoid needing to control a script through group membership.

Primary problem with interrogating memberOf

OK, perhaps this talk of alternatives to scripting groups is unrealistic.  I accept reluctantly that there are occasions where you really do need to extract a user’s group membership in your VBScript.  The main technical problem is that unlike other LDAP properties, memberOf (group membership) can have multiple values.  All the groups to which a user belongs are stored in an array.  In my opinion, data held in arrays is an order of magnitude more difficult for VBScript to extract, than data held in non-array fields.  In conclusion, my advice is this, if you decide that your script must determine group membership, then take the time to become an expert at arrays in general, and the ‘Join’ command in particular.

Secondary problem with groups

Here follows a classic case of knowledge is power.  In a domain, each user object is a member of the Domain Users group.  The problem in scripting occurs because the Domain Users group is their default group, their primary group and also the only group that many users belong.  What happens is that when VBScript interrogates a user’s properties, the Domain Users group does not show in the output.  It’s as though the operating system knows internally about the Domain Users, but it’s hard for a VBScript to get a handle on this membership information.  The final complication is that VBScript needs a different technique to handle a single value held by memberOf, compared with cases where memberOf holds an array of groups.

Scripting Techniques

Our ‘Join Groups’ VBScript is a triumph for researching the subject matter.  Another related technique, which I often recommend is the ‘Walk-Through’.  If you launch Active Directory Users and Computers and inspect the memberOf property tab, then you can see that the User belongs to the Domain Users.  Closer scrutiny reveals that the Domain Users is the primary group.  By constantly returning to this memberOf tab, you can understand why your script produces a particular output.  If the script does not work as expected, then we can gain extra information by adding other groups to the memberOf tab – then running the script again.

I cannot resist the temptation to preach on my favorite subject: build your script in stages.  Today’s script does very little on its own, what we really need is to bolt-on a combination of: GetEx, InStr and MapNetworkDrive commands, only then do have a complete script to solve a variety of network problems.

This week’s mission

This Week’s Mission is to produce a scriplet with the dedicated and important job of displaying a user’s group membership.  Example 1 holds a self-contained block of code, which is purely designed to display the value(s) held by the LDAP property called memberOf.  To be effective in a production script, you would have to add more code.  Thus the simplicity of this week’s example is both its strength and its weakness.  It works, but only in a limited situation, it cries out for the context of a wider project.

Guy Recommends:  SolarWinds’ Free Bulk Import ToolFree Download Solarwinds Bulk Import Tool

Import users from a spreadsheet.  Just provide a list of the users with their fields in the top row, and save as .csv file.  Then launch this FREE utility and match your fields with AD’s attributes, click and import the users.

Optionally, you can provide the name of the OU where the new accounts will be born. Download your FREE bulk import tool.

If you need more comprehensive software, download a free trial of SAM (Server & Application Monitor)

Example 1: Script to Display the Group(s) that a User is memberOf

This script will echo a string containing all the groups to which a user is a member.  The idea is to master one command block which you can then employ in other scripts which need to take action depending on group membership.

Instructions

  1. Copy and paste the script below into notepad, or get a script editor such as OnScript.
  2. Save the file with .vbs extension e.g. JoinGroup.vbs
  3. I recommend that you investigate Active Directory Users and Computers to check the current user’s group membership.  If necessary add the current user to more groups, then run the script a second time.

 

 

‘ JoinGroups.vbs
‘ Example VBScript to interrogate group membership
‘ Authors Charles Trevor and Guy Thomas
‘ Version 2.2 – April 2007 http: //computerperformance.co.uk
‘ —————————————————————‘
Option Explicit
Dim strGroups, colGroups
Dim objUser, CurrentUser

Set objUser = CreateObject("ADSystemInfo")
Set CurrentUser = GetObject("LDAP://" & objUser.UserName)
colGroups = CurrentUser.memberOf
If IsEmpty(colGroups) Then
   strGroups = ""
   ElseIf TypeName(colGroups) = "String" Then
      strGroups = LCase(colGroups)
   Else
      strGroups = LCase(Join(colGroups))
End If
Wscript.Echo strGroups
WScript.Quit
‘ End of example script.

Learning Points for the ‘Join’ Command

Note 1: The command ‘Join’ returns a string value.  In this example, our variable strGroups is created by concatenating a number of substrings (groups) contained in the array colGroups.  Observe how we can trace this array back to CurrentUser.memberOf.

Note 1a: The syntax is: Join(list[, delimiter]).  In this example we simplify the expression to: Join(list)

Note 2:  Take the opportunity to study how VBScript employs the Set, GetObject and CreateObject methods.

Note 3:  I love ‘If’ statements.  The power of this particular ‘If.. Then…Else’ block is that caters for users in all situations.  If a user is only a memberOf one group, LCase(colGroups) takes care of business.  Else the famous ‘Join’ command copes for users with multiple group membership.

Note 4:  There are lots of interesting properties in this script, for example, .memberOf and .UserName.

Note 5:  In many scripts, groups and ‘Join’ require the value to be in lower case, hence Lcase(Join(colGroups).  That said, on my machine the script worked without Lcase, nevertheless, watch out for case-sensitivity with groups and with ‘Join’.

See array strings in PowerShell »

Guy Recommends: The Free IP Address Tracker (IPAT) IP Tracker

Calculating IP Address ranges is a black art, which many network managers solve by creating custom Excel spreadsheets.  IPAT cracks this problem of allocating IP addresses in networks in two ways:

For Mr Organized there is a nifty subnet calculator, you enter the network address and the subnet mask, then IPAT works out the usable addresses and their ranges. 

For Mr Lazy IPAT discovers and then displays the IP addresses of existing computers. Download the Free IP Address Tracker

Summary of Scripting Groups with ‘Join’

I guess if you have got this far, then you really need to master this technique of scripting group membership.  However, I will make one last plea: if you get nothing but error messages and frustration, then think laterally, and particularly, think ‘Group Policy will be my salvation’.

For more interesting articles see the Realtime Community

See More Active Directory Group VBScripts

• User Spreadsheet  • Add User to Group  • Create User  • Free Solarwinds Permissions Monitor

Ezine 57 Groups  •Ezine 58 Groups  • Ezine 73 primaryID  • Ezine 112 Local Groups

Ezine 113 Multiple Groups  • Ezine 115 Map Groups  •Ezine 138 Groups Join  • Ezines