VBS script to map drives/printers based on groups

I am looking for explanation of a VB script on how to map printers and network shares based on group membership.  The following EE post was helpful, but I don't understand VBS and would like to learn something instead of just being given the script.

http://www.experts-exchange.com/OS/Microsoft_Operating_Systems/Server/Windows_Server_2008/Q_24278433.html?sfQueryTermInfo=1+10+30+base+group+map+membership+script+vb

For example, I don't understand the 'Select Case' statement.  Thanks for your help.
Kram80Asked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

Kram80Author Commented:
exx1976, thank you so much for referencing those articles.  I will take a look at those for some information.  Currently, I am going through the code and disecting it, but some expert knowledge would be helpful.  Over time, I'd like to not have to rely on finding scripts already written, or atleast have a good understanding of what the script is trying to do by just looking at it.  Kollenh wrote a great, easy to follow script, I just am looking for more of the nuts and bolts of what went into writing the script.
'login.vbs
'
'Function:  Map drives and printers according to group membership
 
On Error Resume Next		'Rem for testing
 
Const strDomain = "DC=domain,dc=com"	'AD domain
' Printers
Const DeptPrinter = "\\Server\Printer-Shared-name"
Const AdminPrinter = "\\Server\Printer-Shared-name"
' Groups for the T: drive
Const LC_HWYadmin = "\\Server\LC_HWYadmin"
Const LC_APRadmin = "\\Server\LC_APRadmin"
Const LC_COMadmin = "\\Server\LC_COMadmin"
Const LC_PROadmin = "\\Server\LC_PROadmin"
Const LC_REVadmin = "\\Server\LC_REVadmin"
' Groups for the S: drive
Const LC_HWYuser = "\\Server\LC_HWYuser"
Const LC_APRuser = "\\Server\LC_APRuser"
Const LC_COMuser = "\\Server\LC_COMuser"
Const LC_PROuser = "\\Server\LC_PROuser"
Const LC_REVuser = "\\Server\LC_REVuser"
Const LC_ACuser = "\\Server\LC_ACuser"
Const LC_SWuser = "\\Server\LC_SWuser"
Const LC_ENVuser = "\\Server\LC_ENVuser"
 
Set wshNet = CreateObject("Wscript.Network")
Set objfso = CreateObject("Scripting.FileSystemObject")
 
blnAddDeptPrinter=True
blnAddAdminPrinter=True
' Enumerate the network printers
Set colPrinters = wshNet.EnumPrinterConnections
If colPrinters.Count > 0 Then
	For p = 0 To colPrinters.Count -1 Step 2
		 ' compare the printers by name CASE SENSITIVE
		If colprinters.item(p+1) = DeptPrinter Then blnAddDeptPrinter=False 
		
		If colprinters.item(p+1) = Adminprinter Then blnAddAdminPrinter=False
 
		 ' add new/additional printers here using above format
	Next
End If
 
' Search AD for user
strUser = CreateObject("Wscript.Network").Username
Set objconn = CreateObject("ADODB.Connection")
Set objcmd = CreateObject("ADODB.Command")
objconn.Provider = "ADsDSOObject"
objconn.Open "Active Directory Provider"
Set objcmd.ActiveConnection = objconn
 
objcmd.commandtext = _
  "<LDAP://" & strDomain & ">;(&(&objectCategory=User)" & _
    "(samAccountName=" & strUser & "));distinguishedname;subtree"
 
Set objrs = objcmd.Execute
While Not objrs.eof
	If objrs.recordcount = 0 Then
		 ' cannot continue w/o finding user group memberships
	Else
		 ' connect to the user object and enumerate their groups
		Set objUser = GetObject("LDAP://" & objrs.fields("distinguishedName"))
		arrGroups = objUser.GetEx("memberOf")
		 ' memberOf is an extended value so treat as an array
		For Each group in arrGroups
			' wscript.echo group		'Un-remark for TESTING
			'If using "distinguished" group names:
'			strGroup = group
 
			'otherwise use "friendly" group names
			Set objGroup = GetObject("LDAP://" & group)
			strGroup = objGroup.SAMaccountName
 
			Select Case LCase(strGroup)
			   ' Admin groups
			  Case "lc_hwyadmin"
				 ' make sure drive isn't mapped already
				If objfso.FolderExists("T:") Then wshNet.RemoveNetworkDrive "T:",True
				 ' map drive
				wshNet.MapNetworkDrive "T:", LC_HWYadmin
				 ' add printer if it wasn't found initially
				If blnAddAdminPrinter Then wshNet.AddWindowsPrinterConnection AdminPrinter
			  Case "lc_apradmin"
				 ' make sure drive isn't mapped already
				If objfso.FolderExists("T:") Then wshNet.RemoveNetworkDrive "T:",True
				 ' map drive
				wshNet.MapNetworkDrive "T:", LC_APRadmin
				 ' add printer if it wasn't found initially
				If blnAddAdminPrinter Then wshNet.AddWindowsPrinterConnection AdminPrinter
			  Case "lc_comadmin"
  				 ' make sure drive isn't mapped already
				If objfso.FolderExists("T:") Then wshNet.RemoveNetworkDrive "T:",True
				 ' map drive
				wshNet.MapNetworkDrive "T:", LC_COMadmin
				 ' add printer if it wasn't found initially
				If blnAddAdminPrinter Then wshNet.AddWindowsPrinterConnection AdminPrinter
			  Case "lc_proadmin"
				 ' make sure drive isn't mapped already
				If objfso.FolderExists("T:") Then wshNet.RemoveNetworkDrive "T:",True
				 ' map drive
				wshNet.MapNetworkDrive "T:", LC_PROadmin
				 ' add printer if it wasn't found initially
				If blnAddAdminPrinter Then wshNet.AddWindowsPrinterConnection AdminPrinter
			  Case "lc_revadmin"
				 ' make sure drive isn't mapped already
				If objfso.FolderExists("T:") Then wshNet.RemoveNetworkDrive "T:",True
				 ' map drive
				wshNet.MapNetworkDrive "T:", LC_REVadmin
				 ' add printer if it wasn't found initially
				If blnAddAdminPrinter Then wshNet.AddWindowsPrinterConnection AdminPrinter
			  
			   ' Departmental groups
			  Case "lc_hwyuser"
				 ' make sure drive isn't mapped already
				If objfso.FolderExists("T:") Then wshNet.RemoveNetworkDrive "T:",True
				 ' map drive
				wshNet.MapNetworkDrive "T:", LC_HWYuser
				 ' add printer if it wasn't found initially
				If blnAddAdminPrinter Then wshNet.AddWindowsPrinterConnection AdminPrinter
			  Case "lc_apruser"
				 ' make sure drive isn't mapped already
				If objfso.FolderExists("T:") Then wshNet.RemoveNetworkDrive "T:",True
				 ' map drive
				wshNet.MapNetworkDrive "T:", LC_APuser
				 ' add printer if it wasn't found initially
				If blnAddAdminPrinter Then wshNet.AddWindowsPrinterConnection AdminPrinter
			  Case "lc_comuser"
				 ' make sure drive isn't mapped already
				If objfso.FolderExists("T:") Then wshNet.RemoveNetworkDrive "T:",True
				 ' map drive
				wshNet.MapNetworkDrive "T:", LC_COMuser
				 ' add printer if it wasn't found initially
				If blnAddAdminPrinter Then wshNet.AddWindowsPrinterConnection AdminPrinter
			  Case "lc_prouser"
				 ' make sure drive isn't mapped already
				If objfso.FolderExists("T:") Then wshNet.RemoveNetworkDrive "T:",True
				 ' map drive
				wshNet.MapNetworkDrive "T:", LC_PROuser
				 ' add printer if it wasn't found initially
				If blnAddAdminPrinter Then wshNet.AddWindowsPrinterConnection AdminPrinter
			  Case "lc_revuser"					 ' make sure drive isn't mapped already
				If objfso.FolderExists("T:") Then wshNet.RemoveNetworkDrive "T:",True
				 ' map drive
				wshNet.MapNetworkDrive "T:", LC_REVuser
				 ' add printer if it wasn't found initially
				If blnAddAdminPrinter Then wshNet.AddWindowsPrinterConnection AdminPrinter
			  Case "lc_acuser"
				 ' make sure drive isn't mapped already
				If objfso.FolderExists("T:") Then wshNet.RemoveNetworkDrive "T:",True
				 ' map drive
				wshNet.MapNetworkDrive "T:", LC_ACuser
				 ' add printer if it wasn't found initially
				If blnAddAdminPrinter Then wshNet.AddWindowsPrinterConnection AdminPrinter
			  Case "lc_swuser"
				 ' make sure drive isn't mapped already
				If objfso.FolderExists("T:") Then wshNet.RemoveNetworkDrive "T:",True
				 ' map drive
				wshNet.MapNetworkDrive "T:", LC_SWuser
				 ' add printer if it wasn't found initially
				If blnAddAdminPrinter Then wshNet.AddWindowsPrinterConnection AdminPrinter
			  Case "lc_envuser"
				 ' make sure drive isn't mapped already
				If objfso.FolderExists("T:") Then wshNet.RemoveNetworkDrive "T:",True
				 ' map drive
				wshNet.MapNetworkDrive "T:", LC_ENVuser
				 ' add printer if it wasn't found initially
				If blnAddAdminPrinter Then wshNet.AddWindowsPrinterConnection AdminPrinter
			End Select
 
		Next
	End If
	objrs.movenext
Wend
objconn.close()
 
' Optional command to set the default (not recommended, tends to disgruntle employees)
'wshNet.SetDefaultPrinter DeptPrinter
 
' Release objects
If IsObject(objGroup)	Then Set objGroup = Nothing
If IsObject(objUser)	 Then Set objUser = Nothing
If IsObject(objfso)	Then Set objfso = Nothing
If IsObject(wshNet)	Then Set wshNet = Nothing

Open in new window

0
Ron MalmsteadInformation Services ManagerCommented:
While the vbs scripts are very elegant, it is not really practical to maintain them due to their complexity...in my opinion.  Everytime something changes...you have to dig back through them to figure out how you broke it.

For simple tasks such as printers and file shares...it's easier to create batch files and use GPO(group policy objects) to apply them to users or groups of users at logon.

Microsoft designed it that way so that you don't have to be a programmer to do these things.

....Using GPMC.MSC
Create a GPO, and link it to your OU that holds your users.
Name it something useful... for example:  Office A Printers and Shares
Add the Group Name to the "Security filtering" so that members of the group will apply the GPO.
Edit the GPO and create a batch file to be assinged as the logon script in the GPO. (User Configuration/Windows Settings/Scripts Logon/Logoff)

Example Batch file:

CSCRIPT %SYSTEMROOT%\SYSTEM32\PRNMNGR.VBS -ac -p \\server\HPLaserJ
NET USE Q: \\server\quickbooks
0
Creating Active Directory Users from a Text File

If your organization has a need to mass-create AD user accounts, watch this video to see how its done without the need for scripting or other unnecessary complexities.

exx1976Commented:
OK..  I'll dessect it for you here by line.

5 just says "if anything blows up, ignore the error and keep going"

7-25 are all constants, meaning their value cannot be changed once they are declared.

27 creates a network object
28 creates a file system object

30 & 31 are boolean values to determine if... What looks like a department printer or an admin printer, judging by the variable names.

33 enumerates all the network printers and stores them in a collection
34 checks to see if there are any network printers.  If so, then go through them starting with 0 and going to the number of printers -1, and look at every other one in the list (network printers get two entries in the list)
37 says if the printer matches the constant defined on line 9, then it's been added already
39 compares the printer name to the constant on line 10.

46 gets the username of the logged on user
47 and 48 create ADODB connections & command, respectively
49 sets the type of provider for the connection created on 47, & 50 opens the connection.

53-55 is all one line, and it is the LDAP search string to query AD with.

57 executes the query and stores it in a recordset.

58-174 is a big loop that goes through once for each record returned by the query

63 gets the user from AD
64 gets the groups the user is a member of
66 starts a loop that will execute once for each group the user is a member of

72 gets the group object
73 gets the samaccountname of the group

75 begins a select...case statement based on the value returned on 73


A select...case is basically like a big series of if statements, but easier to read.  You decide what it is you want to compare (in this case, on line 75, the chosen control is the variable strGroup).  Then, line 77 says "if strGroup = lc_hwyadmin then do lines 79 and 81 and 83".  Like 84 says "if strGroup = lc_apradmin then do lines 86, 88, and 90", etc.  You get the idea.


Lines 181-184 can be removed, they are a waste of space because WSH (the command interpreter for the VBS language) performs its own garbage collection.


HTH,
exx
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
Kram80Author Commented:
exx, thank you for taking the time to go through that for me.  I was able to implement the script successfully.  And more importantly, I have learned a little more about VB Script in the process.

xuserx2000, you bring up an interesting point.  Something I will definately consider in the future.  However, I believe the approach you described does bring upon it's own set of complexities with managing multiple permissions on GPOs.  I see an opportunity for it to get very messy.

Since this question focused on VB Script, I am going to award points to exx.  Appreciate both of your inputs.
0
exx1976Commented:
xuserx - FWIW, all your "sample batch file" is doing is calling a vbscript, you realize that, right?  LOL

CSCRIPT %SYSTEMROOT%\SYSTEM32\PRNMNGR.VBS -ac -p \\server\HPLaserJ
NET USE Q: \\server\quickbooks



cscript is the commandline interpreter for VBS, and .vbs is a vbscript file.  LOL


Sorry, just wanted to point out the irony of your complaining about VBS and recommending batch, and then just using the batch to call a VBS.


Either way, batch is the days of old, and cannot do a LOT of things that you can do with vbs, unless someone writes a utility for you to access those things...


JMO, YMMV.

-exx
0
Ron MalmsteadInformation Services ManagerCommented:
"" all your "sample batch file" is doing is calling a vbscript, you realize that, right? lol""""

Yes, i'm quite aware of this thank you....

PRNMNGR.VBS  is a script that is built in to windows XP system32 folder, by default,... to aid in adding and removing printers.  It was created and added by microsoft for this exact scenario.  Point being, one doesn't have to be a programmer to use it.

""batch is the days of old,""  >   Batch is not the days of old.  That's absurd.  Unless you contend that command lines are not relevant or useful.

... batch files are simple to understand for most people who are NOT programmers, and GPO objects are the microsoft recommended method of running scripts based on security principles whether they are batch files or vbscripts.

Yes you can do a lot of things with vb script that you cannot do with bat, and I use them quite often, but for simple tasks such as this... I was providing my opinion that creating a script that is over 100 lines of code, rather than just call two lines from a batch file was not really worth it.

In a "race".... I guarantee I could have printers and mapped drives installed company wide, via a simple batch file faster than you can write a wonderfully complicated vbscript to do the same.

Please reconsider your condescending attitude, next time you decide to "educate" another expert on this site.  The questioner got their solution and that's all that matters.
0
exx1976Commented:
Command lines are becoming less and less relevant as the days go by, it seems...  I mean, don't misunderstand, I've written batch, I've been in IT for what feels like forever.  Certainly before VBS was around (remember kix?)..  But, GUI is the way of the future.  Granted, I still find myself at the command line often, for many reasons, but batch files are not one of them.  The OP had expressed his interest to *learn* vbs, and I just found it interesting that rather than teach, you would tell him to stick with old technology.  Technology moves at a breakneck pace - I mean, even VBS it seems is being slowly phased out by M$ in favor of powershell.  That's also not to mention that if you have a GPO in place to prevent your users from running a command window, they aren't goign to be able to execute the batch files you assign to them anyway, so...

Learning VBS is a good thing for any WinTel admin, and if someone wants to learn, I wouldn't steer them away from it because there is a faster, albeit more limited, solution available to them.  Today, the OP wants to map pritners.  Tomorrow, he wants to change AD properties.  Next week, file permissions.  After that, he wants to start automating Office applications and writing Exchange Event Sinks.  Everyone has to start somewhere, and just because this is a simple task doesn't mean we shouldn't take the time to teach what he wanted to know, even if it is the "long way".


-exx
0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
VB Script

From novice to tech pro — start learning today.

Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.