Link to home
Start Free TrialLog in
Avatar of Kram80
Kram80

asked on

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.

https://www.experts-exchange.com/questions/24278433/map-drives-based-on-group-membership.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.
Avatar of exx1976
exx1976
Flag of United States of America image

Avatar of Kram80
Kram80

ASKER

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

Avatar of Ron Malmstead
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
ASKER CERTIFIED SOLUTION
Avatar of exx1976
exx1976
Flag of United States of America image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Kram80

ASKER

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.
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
"" 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.
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