Need some quick help with my vbs active directory login script

Soldato
Joined
1 Dec 2004
Posts
23,083
Location
S.Wales
Hi Dudes and dudesses,

Please see my newly created VBS login script which I am planning on using in a Windows 2003 AD environment, Its about 75% Complete, so far the home user directory and mapped shared drives are mapping fine when user logs in, I can get the printer map working IF the printer is hosted on a dedicated server, the only problem is our domain controller is hosted in a DC up north therefore if we wanted to print, the data would have to be sent up to the DC to be processed by the print server, then back down to our network in South Wales.

As we have 2 printers in the office which both have the ability to hardcode IP addresses in them, we dont therefore need to use a print server on a dedicated server.

Please see my code below.

Code:
' VBScipt for Windows AD-Domain user login script with mapped network drive & mapped printer support----------'
' v1.1--------------------------------------------------------------------------------------------------------'
'copyright 2009-------------------------------------------------------------------------------'
' ------------------------------------------------------------------------------------------------------------'

'On Error Resume Next


' Initialise Groups with Const statement
Const SUPPORT_GROUP = "cn=support"
Const FINANCE_GROUP = "cn=finance"
Const PROVISIONING_GROUP = "cn=provisioning"
Const SALES_GROUP = "cn=sales"

'Map Users home directory to h:\
Set wshNetwork = CreateObject("WScript.Network")
wshNetwork.MapNetworkDrive "h:", "\\***\***$\" & wshNetwork.UserName


' Create objects and extract strGroup values
Set ADSysInfo = CreateObject("ADSystemInfo")
Set CurrentUser = GetObject("LDAP://" & ADSysInfo.UserName)
strGroups = LCase(Join(CurrentUser.MemberOf))



If InStr(strGroups, SUPPORT_GROUP) Then

    wshNetwork.MapNetworkDrive "s:", "\\***\***\"
    wshNetwork.AddWindowsPrinterConnection "\\Servername\Printername\"
    'wshNetWork.SetDefaultPrinter
   

ElseIf InStr(strGroups, FINANCE_GROUP) Then

    wshNetwork.MapNetworkDrive "f:", "\\***\***\"
    wshNetwork.AddWindowsPrinterConnection "\\Servername\Printername\"
    'wshNetWork.SetDefaultPrinter
    '"\\PrintServer\FinLaser"
   
ElseIf InStr(strGroups, PROVISIONING_GROUP) Then

    wshNetwork.MapNetworkDrive "s:", "\\***\***\"
    wshNetwork.AddWindowsPrinterConnection "\\Servername\Printername\"
    'wshNetWork.SetDefaultPrinter
    '"\\PrintServer\HrLaser"
   
ElseIf InStr(strGroups, SALES_GROUP) Then

    wshNetwork.MapNetworkDrive "s:", "\\***\***\"
    wshNetwork.AddWindowsPrinterConnection "\\Servername\Printername\"
    'wshNetWork.SetDefaultPrinter
    '"\\PrintServer\HrLaser"

End If

As you can see, the line

Code:
wshNetwork.AddWindowsPrinterConnection "\\Servername\Printername\"

is in the format "\\servername\Printer Name" and this is causing a problem for us as technically the printer will not be hosted on a server.

I have also tried

Code:
"\\Printer IP\Printer name" and also "\\Printer IP"

but neither work, is there anyway around this? we want the deminish the server name and just connect via IP address of the printer.

Any help greatly appriciated.
 
Last edited:
AFAIK AddWindowsPrinter requires a UNC name in order to work.

The only thing I can suggest is setting up a local printer that connects to the printers IP and port.

EDIT: You should be able create a reg file to add the settings automatically.

interesting, ok, ill read up on UNC. As i mentioned the printer mapping works fine without UNC if the printer is hosted on the print server, we dont want this though, we dont even want it to be hosted on a local machine, the whole point of a printer with configurable IP is so that you can directly connect to them without using a print server or a local machine to host them.

Do you have more info on this reg file? what will it enable me to do?

This login script will be added to each users "login script" through active directory, then when they login it will run.

Thanks for your info so far :)
 
So to clarify, when the script is loaded when the user logs in, it automates the procedure of going through start>programmes>add printers, it adds a printer using TCP/IP ports and uses the driver located in a shared location.

OK, i think iv got it, thanks very much for your help :)

Im going to work on this when I get a chance (probably tomorrow in work and ill post the code I have up here to see what everyone thinks).

Thanks

DJMK4
 
OK, here is abit of an update on this project, its going good but im still trying to sort out a few bugs.

1) I want to implement the login script so that when it logs in, it will disconnect the network drives before reconnecting them, I thought I had sussed it by using the following code before mapping them:

wshNetwork.RemoveNetworkDrive "f:"

However this is not the case and I get the following error

Line 20 this network connection does not exist?? however if i remove it maps fine.

2) With regards to the print mapping, I have got this working! It creates a TCP/IP port, adds the driver, then adds the printer, when i log off and log back in, it stays put, is this the best way of doing this or is it best to disconnect the printer on log off? also, everytime I log back in it will look for and install the printer driver, I want it to check to see if the driver is already installed, if it is, skip that section.

Any tips on how to achieve this?

Kind Regards

DJMK4


Here is the code

Code:
' VBScipt for Windows AD-Domain user login script with mapped network drive & mapped printer support----------'
' v1.1--------------------------------------------------------------------------------------------------------'
' copyright 2009-------------------------------------------------------------------------------'
' ------------------------------------------------------------------------------------------------------------'


'MAP NETWORK DRIVES
'--------------------------------------------------------------------------------

'On Error Resume Next

' Initialise Groups with Const statement
Const SUPPORT_GROUP = "cn=support"
Const FINANCE_GROUP = "cn=finance"
Const PROVISIONING_GROUP = "cn=provisioning"
Const SALES_GROUP = "cn=sales"

'Map Users home directory to h:\
Set wshNetwork = CreateObject("WScript.Network")
wshNetwork.RemoveNetworkDrive "h:"
wshNetwork.MapNetworkDrive "h:", "\\****\Users$\" & wshNetwork.UserName


'Create objects and extract strGroup values
Set ADSysInfo = CreateObject("ADSystemInfo")
Set CurrentUser = GetObject("LDAP://" & ADSysInfo.UserName)
strGroups = LCase(Join(CurrentUser.MemberOf))


If InStr(strGroups, SUPPORT_GROUP) Then
    wshNetwork.RemoveNetworkDrive "s:"
    wshNetwork.MapNetworkDrive "s:", "\\****\DATA"
   

ElseIf InStr(strGroups, FINANCE_GROUP) Then
    wshNetwork.RemoveNetworkDrive "f:"
    wshNetwork.RemoveNetworkDrive "s:"
    wshNetwork.MapNetworkDrive "f:", "\\****\finance"
    wshNetwork.MapNetworkDrive "s:", "\\****\DATA"

       
       
ElseIf InStr(strGroups, PROVISIONING_GROUP) Then
    wshNetwork.RemoveNetworkDrive "s:"
    wshNetwork.MapNetworkDrive "s:", "\\****\DATA"

   
   
ElseIf InStr(strGroups, SALES_GROUP) Then
    WshNetwork.RemoveNetworkDrive "s:"
    wshNetwork.MapNetworkDrive "s:", "\\****\DATA"
End If



'MAP NETWORK PRINTER VIA IP PORT
'--------------------------------------------------------------------------------
'Create TCP/IP Port

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
Set objNewPort = objWMIService.Get _
("Win32_TCPIPPrinterPort").SpawnInstance_

objNewPort.Name = "IP_****"
objNewPort.Protocol = 1
objNewPort.HostAddress = "****"
objNewPort.PortNumber = "9100"
objNewPort.SNMPEnabled = False
objNewPort.Put_


'ADD Driver

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")
objWMIService.Security_.Privileges.AddAsString "SeLoadDriverPrivilege", True

Set objDriver = objWMIService.Get("Win32_PrinterDriver")

objDriver.Name = "HP Color LaserJet 2600n"
objDriver.SupportedPlatform = "Windows NT x86"
objDriver.Version = "3"
'objDriver.DriverPath = "\\****\netlogon\clj2600n\NewPrinter.dll"
objDriver.Infname = "\\****\netlogon\clj2600n\CLJ2600.INF"
intResult = objDriver.AddPrinterDriver(objDriver)


'Install printer

strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\root\cimv2")

Set objPrinter = objWMIService.Get("Win32_Printer").SpawnInstance_

objPrinter.DriverName = "HP Color LaserJet 2600n"
objPrinter.PortName   = "IP_****"
objPrinter.DeviceID   = "HP Color LaserJet 2600n"
objPrinter.Location = "****"
objPrinter.Network = True
objPrinter.Shared = False
objPrinter.Put_
 
Last edited:
Did you map the drive using your script or was it created manually beforehand? When you can create it manually using Windows Explorer (Well a reg file at least... I'm unable to test Map Network Drive through explorer here at the moment) it adds the information to the registry under Network. You won't be able to remove this using WSHNetwork, you'll need to remove the keys first.

You can remove drives created with WSHNetwork but not ones that weren't. As a test enumerate the network drives on your PC to a text file or similar and see if the drive you're unable to remove with your script is listed - I've got a feeling it won't be.

The mapped drives was created using wshNetwork, the mapping works fine, but apon login before they map the drives I want them to removemapped drives before mapping them. Saves any errors coming up because "This drive is already mapped"



From what I remember printers are stored in the Control Set, you shouldn't need to add them for specific users just PC's, once they're added - everyone here in work has a default "HP LaserJet" that doesn't actually exist - you can read the registry for the printer and check it has keys listed for drivers. In theory, that should work.

Thanks, will look in to this.
 
How odd. Can you check to see if the is anything stored under HKEY_CURRENT_USERS\Network

I can replicate the error if I have drives listed there but cannot just using WSHNetwork. Did you enumerate the drives? If so, was the troublesome drive listed? If WSHNetwork doesn't see it you want be able to remove it.

You could even use the enumeration as part of your code. e.g. F:\, \\myShare\Drive$ is listed so remove it then remap if not simply map it. :)


Thanks for the info on this :) Will be having another look at this project tomorrow as Iv been lumbered with some more work, d'oh!

Will post updates :)

Just a question though, when you say "enumeration", what is this? I will have to look this up on google i think,lol!
 
Thanks for that info.

I am however getting issues with the drive mapping side now!

Seems that on mine it works, when i use it with someone elses AD account it has problems and returns a "Type Mismatch - "Join" error for the following line:

strGroups = LCase(Join(CurrentUser.MemberOf))

This is due to AD members being in less than or two or more groups which makes it return an error. I have dug and dug around on the web and have found various fix code snippets for this problem including the one below:

Code:
Dim strGroup
Dim colGroups

Set objUser = CreateObject("ADSystemInfo")
Set CurrentUser = GetObject("LDAP://" & objUser.UserName)

colGroups = CurrentUser.memberOf
If IsEmpty(colGroups) Then
strGroup = ""
ElseIf TypeName(colGroups) = "String" Then
strGroup = LCase(colGroups)
Else
strGroup = LCase(Join(colGroups))
End If

which is supposed to replace that statement above, It doesnt return any errors but then the only drive it maps is the users home drive. See below for full code.

Code:
' VBScipt for Windows AD-Domain user login script with mapped network drive & mapped printer support----------'
' v1.1--------------------------------------------------------------------------------------------------------'
' dmoranda.co.uk copyright 2009-------------------------------------------------------------------------------'
' ------------------------------------------------------------------------------------------------------------'

'On Error Resume Next




Const SUPPORT_GROUP = "cn=support"
Const FINANCE_GROUP = "cn=finance"
Const PROVISIONING_GROUP = "cn=provisioning"
Const SALES_GROUP = "cn=sales"

'Map Users home directory to h:\
Set wshNetwork = CreateObject("WScript.Network")
wshNetwork.MapNetworkDrive "h:", "\\*****\Users$\" & wshNetwork.UserName


'Create objects and extract strGroup values
'Set ADSysInfo = CreateObject("ADSystemInfo")
'Set CurrentUser = GetObject("LDAP://" & ADSysInfo.UserName)
'strGroups = LCase(Join(CurrentUser.MemberOf))


'Fix for AD users and number of groups they are a member 
Dim strGroup
Dim colGroups

Set objUser = CreateObject("ADSystemInfo")
Set CurrentUser = GetObject("LDAP://" & objUser.UserName)

colGroups = CurrentUser.memberOf
If IsEmpty(colGroups) Then
strGroup = ""
ElseIf TypeName(colGroups) = "String" Then
strGroup = LCase(colGroups)
Else
strGroup = LCase(Join(colGroups))
End If


If InStr(strGroups, SUPPORT_GROUP) Then
    'wshNetwork.RemoveNetworkDrive "s:", "\\****\DATA"
	wshNetwork.MapNetworkDrive "s:", "\\***\DATA"

	

ElseIf InStr(strGroups, FINANCE_GROUP) Then
	'WshNet.RemoveNetworkDrive "f:", "\\****\finance"
	'WshNet.RemoveNetworkDrive "s:", "\\*****\DATA"
	wshNetwork.MapNetworkDrive "f:", "\\*****\finance"
    	wshNetwork.MapNetworkDrive "s:", "\\*****\DATA"

    	
		
ElseIf InStr(strGroups, PROVISIONING_GROUP) Then
	'WshNet.RemoveNetworkDrive "s:", "\\*****\DATA"
	wshNetwork.MapNetworkDrive "s:", "\\*****\DATA"

	
	
ElseIf InStr(strGroups, SALES_GROUP) Then
	'WshNet.RemoveNetworkDrive "s:", "\\*****\DATA"
	wshNetwork.MapNetworkDrive "s:", "\\*****\DATA"
End If

Would really appriciate some help on this :( I have spent hours trying to get this working "fully" but everytime i get i think I have it working I run into yet another problem.

Here is one of the links I have found regarding this issue.

http://www.petri.co.il/forums/archive/index.php/t-9290.html


Thanks in advance :)
 
Hmm think i may have just cracked it, still havnt tested this on a non-admins user account tho..

Code:
' VBScipt for Windows AD-Domain user login script with mapped network drive & mapped printer support----------'
' v1.1--------------------------------------------------------------------------------------------------------'
' copyright 2009-------------------------------------------------------------------------------'
' ------------------------------------------------------------------------------------------------------------'


Dim objNetwork, objUser, CurrentUser
Dim strGroup, arrGroups
'Defines a list for the variable values

Const SUPPORT_GROUP = "cn=support"
Const FINANCE_GROUP = "cn=finance"
Const PROVISIONING_GROUP = "cn=provisioning"
Const SALES_GROUP = "cn=sales"

Set objNetwork = CreateObject("WScript.Network")
Set objUser = CreateObject("ADSystemInfo")
Set CurrentUser = GetObject("LDAP://" & objUser.UserName)

'On Error Resume Next
arrGroups = CurrentUser.memberOf
If (Err.Number <> 0) Then
On Error GoTo 0
strGroups = ""
Else
On Error GoTo 0
strGroup = LCase(Join(arrGroups))
End If

If InStr(strGroup, SUPPORT_GROUP) then
objNetwork.MapNetworkDrive "s:", "\\***\DATA"

Else If InStr(strGroups, FINANCE_GROUP) Then
objNetwork.MapNetworkDrive "s:", "\\***\DATA"
objNetwork.MapNetworkDrive "f:", "\\***\finance"

Else If InStr(strGroups, PROVISIONING_GROUP) Then
objNetwork.MapNetworkDrive "s:", "\\***\DATA"

Else If InStr(strGroups, SALES_GROUP) Then
objNetwork.MapNetworkDrive "s:", "\\***\DATA"
End If
end if
end if
end if
 
Last edited:
OK, the last attempt didnt work, still getting "Type mismatch - "Join" when a user tries to log in on line 34 which is

If InStr(strGroup, SUPPORT_GROUP) then

i belive. it maps the home directory fine.

Any ideas?
 
That's your problem - you're trying to Join a string. If they're not part of a group you shouldn't really be proceeding with the code.

Do you mean if the user is not part of a group?? well I have tested these users that are part of a group, the users who its not working with are members of two groups "domain users" which apparently does not count, and their divisional
group e.g. "Sales".

Whats the best way around this problem?? I really dont want to revert back to using batch files :(
 
arrGroups = currentUser.memberOf

Should return an array representing each of the users groups. If it doesn't you won't be able to Join it - Type Mismatch :). You can Join elements of "" strings if you'd like but you can't join a String. At the very least the method should be be returning "CN=Sales" if it's not you need to establish why.

If you want to bypass the error using the code you've got now, which I wouldn't advise, you could

ReDim strGroups(1)
strGroups(0) = ""

That'll get you past the error but you'll still be stuck when it's comes to mapping unless you set up another condition which simply maps a drive accessible to everyone.


Thanks for the info :) however im a little lost with this one,lol, do you have an example of how the array should look and how the groups should be added?
 
Im still having trouble exactly how this was supposed to work, sorry for this but coming from someone who has little experience with VBScript, and infact using arrays's im finding this hard :(

where exactly should

Code:
CN=Superheroes,CN=Users,DC=DailyPlanet,DC=uk
CN=Users,CN=Users,DC=DailyPlanet,DC=uk

be placed in my code?

also why is there two CN's in that, and 2x DC's?

If im coding this for mine, should it look like:

Code:
CN=Support, CN=Users,DC=Domain Controller, DC=?????" <What is that last bit?

do this for each group?


I also dont understand what this piece of code is supposed to do

Code:
arrGroups = currentUser.memberOf
 
For each sGroup in arrGroups
myOutputFile.Writeline sGroup ' Put your preferred destination here. 
Next

Outputs a file with what info exactly?

Sorry if im a pain :(
 
Thanks so much for this :) ill let you know how I get on with it! that looks a lot clearer for me to understand :)
 
Hi, just returning back to this,

As you are aware when using the above script it chucks up errors if the user is a member of 0 groups as it will see this as empty, or if they are a member of 1 group it will see this a as a string therefore I have re-jigged the code as per below:

Code:
' VBScipt for Windows AD-Domain user login script with mapped network drive & mapped printer support----------'
' v1.1--------------------------------------------------------------------------------------------------------'
' dmoranda.co.uk copyright 2009-------------------------------------------------------------------------------'
' ------------------------------------------------------------------------------------------------------------'
Option Explicit

'Defines a list for the variable values
Dim wshNetwork
Dim ADSysInfo
Dim CurrentUser
Dim strGroups
Dim arrGroups

Const SUPPORT_GROUP	= "cn=support,ou=acc,ou=backoffice,dc=mydomain,dc=com"
Const FINANCE_GROUP = "cn=finance,ou=mky,ou=backoffice,dc=mydomain,dc=com"
Const PROVISIONING_GROUP = "cn=provisioning,ou=acc,ou=backoffice,dc=mydomain,dc=com"
Const SALES_GROUP = "cn=sales,ou=mky,ou=backoffice,dc=mydomain,dc=com"

Set wshNetwork = CreateObject("WScript.Network")
Set ADSysInfo = CreateObject("ADSystemInfo")
Set CurrentUser = GetObject("LDAP://" & ADSysInfo.UserName)



'Map Users home directory to h:\
wshNetwork.MapNetworkDrive "h:", "\\****\Users$\" & wshNetwork.UserName


On Error Resume Next
arrGroups = CurrentUser.GetEx("MemberOf")
If (Err.Number = 0) Then
On Error GoTo 0
strGroups = LCase(Join(arrGroups))

If InStr(strGroups, "SUPPORT_GROUP") Then
	wshNetwork.MapNetworkDrive "s:", "\\****\DATA"	
End If

If InStr(strGroups, "FINANCE_GROUP") Then
	wshNetwork.MapNetworkDrive "f:", "\\****\finance"
    wshNetwork.MapNetworkDrive "s:", "\\****\DATA"
End If

If InStr(strGroups, "PROVISIONING_GROUP") Then
	wshNetwork.MapNetworkDrive "s:", "\\****\DATA"	
End If

If InStr(strGroups, "SALES_GROUP") Then
	wshNetwork.MapNetworkDrive "s:", "\\****\DATA"
End If



End If
On Error GoTo 0

I have taken into account what has been said in this thread and also workarounds I have found on the web.

This hasnt been tested yet, I will be testing this afternoon hopefully but just wanted to see if I am doing it correctly. One thing I am unsure about is the following lines:

Code:
Const SUPPORT_GROUP	= "cn=support,ou=acc,ou=backoffice,dc=mydomain,dc=com"
Const FINANCE_GROUP = "cn=finance,ou=mky,ou=backoffice,dc=mydomain,dc=com"
Const PROVISIONING_GROUP = "cn=provisioning,ou=acc,ou=backoffice,dc=mydomain,dc=com"
Const SALES_GROUP = "cn=sales,ou=mky,ou=backoffice,dc=mydomain,dc=com"

How do I find out what the correct OU/OU/DC/DC? I know what the CN would be.

Also looking at the above, there was one error being thrown up, the last comment was the person managing to fix it, but all he said was

"OK, here is what I was doing wrong... I was putting as the search string
so InStr was compairing FINANCE_GROUP when it should have been looking at
cn=finance."

Does anyone know what he means by this?
 
Last edited:
thanks so much for this help. I will go back over it once again tomorrow when i am in the office and will post my findings :)
 
Back
Top Bottom