0

I am trying to create a login script for Active Directory that will be used for installing printers on client computers. I have a basic script that we are using now, listed below, that installs a series of printers to the local machine from our print server. I have referenced the following posting for some ideas, but it does not help address some of the challenges that I am having.

I am left with the following challenges that I cannot seem to find answers to online:

  • Preventing the computer from forcefully installing the printers every time the script is ran. Ideally, it would check to see if the printer was installed first before trying to install it again. Without this, the machine is really slow to boot.
  • Query the computer group membership that the machine is a member of and then assign the default printer based upon the membership/case returned.

Thanks in advance for your help.

====================================
Code listed below
====================================

On Error Resume Next

PrintServer = "\\PrintServer\HP 4000 - Area1"
set objNetwork = createobject("Wscript.Network")
objNetwork.AddWindowsPrinterConnection(PrintServer)
objNetwork.SetDefaultPrinter PrintServer

PrintServer = "\\PrintServer\HP 4250 - Area2"
set objNetwork = createobject("Wscript.Network")
objNetwork.AddWindowsPrinterConnection(PrintServer)

PrintServer = "\\PrintServer\HP 4350 - Area3"
set objNetwork = createobject("Wscript.Network")
objNetwork.AddWindowsPrinterConnection(PrintServer)

PrintServer = "\\PrintServer\Dell 5200 - Area4"
set objNetwork = createobject("Wscript.Network")
objNetwork.AddWindowsPrinterConnection(PrintServer)

PrintServer = "\\PrintServer\HP 4240 - Area5"
set objNetwork = createobject("Wscript.Network")
objNetwork.AddWindowsPrinterConnection(PrintServer)

PrintServer = "\\PrintServer\HP 4240 - Area6"
set objNetwork = createobject("Wscript.Network")
objNetwork.AddWindowsPrinterConnection(PrintServer)

PrintServer = "\\PrintServer\HP 4240 - Area7"
set objNetwork = createobject("Wscript.Network")
objNetwork.AddWindowsPrinterConnection(PrintServer)

PrintServer = "\\PrintServer\HP 4240 - Area8"
set objNetwork = createobject("Wscript.Network")
objNetwork.AddWindowsPrinterConnection(PrintServer)

PrintServer = "\\PrintServer\HP 4240 - Area9"
set objNetwork = createobject("Wscript.Network")
objNetwork.AddWindowsPrinterConnection(PrintServer)
John
  • 2,266
  • 6
  • 44
  • 60
  • what about using group policy? installing the printer on the server, then using group policy.. user config - policies - windows settings - printer connections \\server\printer_name\ and applying that GPO to OU groups? just an idea instead of scripts – Jeff Apr 21 '11 at 21:15
  • Jeff, can you limit GPO to specifc users based on group membership? (group policy was always a misnomer since it is generally applied to OUs – uSlackr Apr 21 '11 at 21:20
  • Ohh i'm sorry i overlooked group membership. I don't beleive you can do it by membership, i think it is just OUs like you said. sorry about that – Jeff Apr 21 '11 at 21:22
  • No sweat. GPO is the right way to go if you can make it work. We make heavy use of it here. I know you can do WMI queries with it now, still not sure about groups membership. – uSlackr Apr 21 '11 at 21:25
  • i have never learned anything with group members. I use OUs mainly to group all my computers & users , with really only distribution groups. I think we may have 2-3 actual security groups for no internet mail and no local computer logon. Actually that just made me think of something -- whenever i configured the no computer logon, i had to create a security group and then had a gp that basically said if you are a member of this group deny local logon - i'll check into it and see how it worked may provide an option for the printers, not sure – Jeff Apr 21 '11 at 21:28
  • yeah - for that i just had deny local logon to members of the group: nocomputerlogon. you can only select a printer for the deployed printer gp, and assign it to an ou – Jeff Apr 21 '11 at 21:30
  • 2
    WTH? Doing group policies based on an AD Group is simple. Create the policy, and adjust the permissions of the policy. Add the groups you want, and give them the 'Apply To' permission and remove apply from 'Authorized Users'. – Zoredache Apr 21 '11 at 22:41

4 Answers4

3

There are lots of ways to skin this. For part 2, I have a vbscript that queries group membership and returns an errorlevel that you can use in your batch. The same could be done with powershell.

Here is the vbscript:

 'On Error Resume Next
' GroupCheck - GjM - returns errorlevel 1 if user is member of group, else returns 0
' EX: groupcheck.vbs <groupname>
' 
'
option explicit
Dim objADSysInfo, strUser, objGroup, objNetwork, strGroup, objUser, group, bMatched
Dim strGroupToTest, objArgs

set objArgs = wscript.arguments
strGroupToTest = objargs(0)
bMatched = False

'************************
'Make no changes below this point (unless you know why!)
'************************

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

For Each group in objUser.memberOf
    Set objGroup = GetObject("LDAP://" & group)
    If trim(objGroup.CN) = trim(strGroupToTest) Then 
          bMatched = True
      'wscript.echo "Group match"
        Exit For
    End If
Next

If bMatched then 
    'wscript.echo "User in group"
    wscript.quit 1
else
    'wscript.echo "User not in group"
    wscript.quit 0
End If

And here is a batch program to call it:

:: Test to see if we should run this script
cscript /nologo Groupcheck.vbs "groupname"
if %errorlevel% EQU 0 (
   echo Failed groupcheck, exiting...
   Goto :EOF
) Else (
   echo Passed group check....
   'map your printer here
)

For part 1 I found some vbscript to enumerate printers here. Look for the showprn files. Also found this info on installing printers from the commandline that might be easier than the vbscript you have.

uSlackr
  • 6,337
  • 21
  • 36
  • BTW, If I were doing this myself today (the code above is 6-7 yrs old), I would do it all in Powershell today. Windows batch is fine, but powershell is so much more powerful. – uSlackr Apr 21 '11 at 21:21
  • could I please politely ask you to give the [FAQ](http://serverfault.com/faq) a quick once over - specifically the *Can I use a signature or tagline?* section. – Ben Pilbrow Apr 21 '11 at 21:23
  • @Ben I hadn't seen that before. While I suspect they are trying to prevent the 10-line .sig with quotes and links; I'll try to withhold it. I've been typing it since 1990 (literally: http://bit.ly/f8r8ss) so it'll be a tough habit to break. – uSlackr Apr 21 '11 at 21:36
  • nothing personal, we try to keep it as much Q&A as possible, and as such also remove greetings and thanks. There have been several discussions on Meta Server Fault, as well as Meta Stack Overflow if you're interested in the excruciating detail (it's not that thrilling though :P). – Ben Pilbrow Apr 21 '11 at 21:40
2

When it seems like things are difficult in windows, the first question you shold ask yourself is "why is this so hard, maybe there is a different way". In this case while you can map printers in a login script, you probably shouldn't. You can use group policy preferences to apply the primters to the groups you want without scripting.

Take a look at:

GP Preferences: Add a new printer, set as default

The One Reason You Should Use Group Policy Preferences

How to use Group Policy Preferences to dynamically map printers with Roaming Profiles

Jim B
  • 23,938
  • 4
  • 35
  • 58
0

I would use group policy to add printers if possible. If you must use vbs, here's the vbscript we use to do various things to certain groups (add printers, add mapped drives, etc.) We set this script to run via group policy for all users.

Dim strComputerName
Dim strUserName
Dim strDomainName
Dim wshShell
Dim bForce
Dim bUpdateProfile
Dim adsobj

bForce = true
bUpdateProfile = true

on error resume next

Set wshNetwork = WScript.CreateObject( "WScript.Network" )
Set wshShell = WScript.CreateObject("WScript.Shell" )

do while wshNetwork.username = ""
    WScript.Sleep 250
loop

strComputerName = wshNetwork.computerName
strUserName = wshNetwork.userName
strDomainName = wshNetwork.userDomain

adspath = "WinNT://" & strDomainName & "/" & strUserName
set adsobj = getobject(adspath)

'========= MAKE CHANGES BELOW =========     

cRemoveExistingDrives()

'=== Map company-wide drives and printers
cMapNetworkDrive "S:", "\\server\Shared$"

cAddNetworkPrinter "\\server\HP3050"    


'=== Map Group Specific Drives and printers
for each prop in adsobj.groups
    select case UCASE(prop.name)
        case "ACCOUNTING USERS"
                    cAddNetworkPrinter "\\server\AcctngPrinter"
                    wshNetwork.SetDefaultPrinter "AcctngPrinter"
            cMapNetworkDrive "X:", "\\server\accounting$"
        case "HR USERS"
                    cAddNetworkPrinter "\\server\HRPrinter"
                    wshNetwork.SetDefaultPrinter "HRPrinter"
            cMapNetworkDrive "Y:", "\\server\hr$"
    end select
next


'========= NO CHANGES BELOW THIS LINE ===========

Sub cRemoveExistingDrives()
    on error resume next
    Dim colNetDrives
    Set colNetDrives = wshNetwork.EnumNetworkDrives

    If colNetDrives.Count = 0 then
        'No drives
    Else
        For x = 0 to colNetDrives.count-1 Step 2
            wshNetwork.RemoveNetworkDrive colNetDrives.Item(x), bForce, bUpdateProfile
        Next
    End If  
End Sub

Sub cMapNetworkDrive(strDriveLetter, strPath)
    on error resume next
    wshNetwork.RemoveNetworkDrive strDriveLetter, bForce, bUpdateProfile
    wshNetwork.MapNetworkDrive strDriveLetter, strPath
End Sub

Sub cAddNetworkPrinter(strPath)
    on error resume next
    wshNetwork.AddWindowsPrinterConnection strPath 
End Sub
user78940
  • 473
  • 2
  • 7
0

I really enjoy using Kixtart. It has C like Syntax and you can customize your logon scripts based on AD Membership.

With Kixtart you could do;

If InGroup("group1")
    $rc = AddPrinterConnection("\\server\printer_a")
    $rc = AddPrinterConnection("\\server\printer_b")
    $rc = AddPrinterConnection("\\server\printer_c")
EndIf

If InGroup("group2")
    $rc = AddPrinterConnection("\\server\printer_d")
    $rc = AddPrinterConnection("\\server\printer_e")
    $rc = AddPrinterConnection("\\server\printer_f")
EndIf
CryptoJones
  • 824
  • 1
  • 9
  • 17
  • 1
    I really dislike Kix. It's an extra (unnecessary) step and another thing that can break and must be part of the troubleshooting process. In my opinion, it's a crutch, since everything that it does can be accomplished with GPP+ILT or VBscript, or PowerShell. – MDMarra Mar 22 '13 at 18:26