Announcement

Collapse
No announcement yet.

VBS GPO Logon Script Not Executing Properly

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • VBS GPO Logon Script Not Executing Properly

    Hello. I have been having an issue that I am hoping someone can help me with. I wrote two scripts, one for logon and one for logoff, to create and remove a virtual dummy printer for users. I am posting this in the AD section as these scripts work perfectly when launched as the user on an XP based workstation. However, when launched via GPO the scripts run, but nothing happens. I have confimed they are running, because I added in echo statements as a test and all expected message boxes popped up. However, the printer does not actually get created or removed. I even tried creating a batch file that called each vbs script via wscript. If anyone can offer any insight as to why this may be occurring, it would be greatly appreciated. Again, when launched manually by double-clicking on the machine in question, each script works flawlessly. Only when launched via GPO do they run but do not perform the expected actions. I have included a copy of the scripts below.

    #1 Logon Script. Creates a port, printer and sets default printer.
    Code:
     
    On Error Resume Next
     
    Dim objNetwork,objWMIService,objNewPort,oShell,objPrinter
    Set shell = WScript.CreateObject( "WScript.Shell" )
    CompName = shell.ExpandEnvironmentStrings("%COMPUTERNAME%")
    Set WSHNetwork = WScript.CreateObject("WScript.Network")
    Set objWMIService = GetObject("winmgmts:\\" & CompName & "\root\cimv2")
    Set objNewPort = objWMIService.Get("Win32_TCPIPPrinterPort").SpawnInstance_
    Set oShell = WScript.CreateObject("WScript.shell")
    Set objPrinter = objWMIService.Get("Win32_Printer").SpawnInstance_
    Set objNetwork = createobject("Wscript.Network")
     
    '----------------------------------------------
    'Add Printer Port (port name and ip address)
    '----------------------------------------------
    createPort "Virtual Printer", "127.0.0.1"
     
    '----------------------------------------------
    ' Add Printer (printer driver, port name and printer name)
    '----------------------------------------------
    addPrinter "HP Laserjet 5","Virtual Printer","Training Room Virtual Printer"
    'MsgBox ("Printer installation complete")
    objNetwork.SetDefaultPrinter "Virtual Printer"
     
    sub createPort (name, ip)
    objNewPort.Name = name
    objNewPort.Protocol = 1
    objNewPort.HostAddress = ip
    objNewPort.SNMPEnabled = False
    objNewPort.Put_
    end Sub
     
    sub addPrinter (driver, port, name)
    objPrinter.DriverName = driver
    objPrinter.PortName = port
    objPrinter.DeviceID = name
    objPrinter.Location = "Training Room"
    objPrinter.Network = True
    objPrinter.Shared = False
    objPrinter.ShareName = ""
    objPrinter.Put_
    end Sub
     
    WScript.Quit
    #2 Clear all print jobs, remove printer
    Code:
     
    On Error Resume Next
     
    Dim objWMIService,strArgument
     
    Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
    Set colInstalledPrinters = objWMIService.ExecQuery ("Select * from Win32_Printer")
     
    For Each objPrinter in colInstalledPrinters
    objPrinter.CancelAllJobs()
    Next
     
    Set objShell = CreateObject("Wscript.Shell")
    strArgument = "c:\windows\system32\rundll32.exe printui.dll,PrintUIEntry /dl /n " & chr(34) & "Training Room Virtual Printer" & chr(34)
    objShell.Run strArgument
     
    WScript.Quit
    Last edited by Rems; 4th November 2010, 13:06. Reason: added [CODE]-tags around code parts

  • #2
    Re: VBS GPO Logon Script Not Executing Properly

    When you setup the policy to run the scripts, did you set it up under the Computer Configuration or the User Configuration? If you set it up under the Computer Configuration, I'd speculate that it's setting up a printer for the computer account instead of the user account.

    Assuming the scripts were setup to run under the Computer Configuration section of the GPO, I try setting it up under the User Configuration.

    Comment


    • #3
      Re: VBS GPO Logon Script Not Executing Properly

      Hi Scott. Thank you for the reply. This is truly baffling me as from everything I can tell, it should work. It is indeed set up as a user logon and logoff script and linked to the OU that the user accounts reside in. Also, as I stated before, the script is running because the echo statements I placed as a test each come up on logon. However, the port or printer never gets created. Also, if the printer is already setup prior to logging in, the logon script will successfully set the default printer as expected. And the thing that kills me most is that if i just run the scripts manually, everything works perfect.

      Comment


      • #4
        Re: VBS GPO Logon Script Not Executing Properly

        For the "Creates a port and printer" script to run successful the user must have local admin privileges. Mostlikely that most users are regular users therefore the logon script will not run sucessfully.

        Use a computer startup script for creating the tcpip printer port and adding the local printer.

        Then use a logonscript to make it the default printer for the user.


        \Rems

        This posting is provided "AS IS" with no warranties, and confers no rights.

        __________________

        ** Remember to give credit where credit's due **
        and leave Reputation Points for meaningful posts

        Comment


        • #5
          Re: VBS GPO Logon Script Not Executing Properly

          Hi Rems. The users in question are local admins, but locked down through GPOs. I am almost wondering if there is a setting that is locking down the user experience preventing this action from occurring. That is the current theory I am investigating. Thanks for the reply.

          Comment


          • #6
            Re: VBS GPO Logon Script Not Executing Properly

            For the clients, use a GPO to enable the policy "Always wait for the network at computer startup and logon"
            => Computer configuration / Administrative Templates / System / Logon

            It has to be enabled! (This policy might already have been enabled on your client because you have confirmed the scripts are running. Just check it anyway on a client)

            next,
            Configure the logon and logoff script in a user policy. Point to the vbs scripts directly (do not use an other script/batch that will launch the printer vbscripts).
            On the test client run gpupdate /force then reboot and log on.

            It should work for administrators - I have tested it with the two scripts below,

            # Logon (admin) script:
            Code:
            Dim oService, strPortName, strPortIP
            
            With CreateObject("WbemScripting.SWbemLocator")
               set oService = .ConnectServer(".", "\root\cimv2")
               oService.Security_.impersonationlevel = 3
               oService.Security_.Privileges.AddAsString _
                 "SeLoadDriverPrivilege", True 
            End With
            
            strPortName = "Virtual Printer"
            strPortIP = "127.0.0.1"
            
            '----------------------------------------------
            'Add Printer Port (port name and ip address)
            '----------------------------------------------
            createPort strPortName, strPortIP
            
            '----------------------------------------------
            ' Add Printer (printer driver, port name and printer name)
            '----------------------------------------------
            addPrinter "HP Laserjet 5", strPortName, "Training Room Virtual Printer"
            
            WScript.Quit 0
            
            Sub createPort (name, ip)
               Dim objNewPort: Set objNewPort = _
                 oService.Get("Win32_TCPIPPrinterPort").SpawnInstance_
               objNewPort.Name = name
               objNewPort.Protocol = 1
               objNewPort.HostAddress = ip
               objNewPort.PortNumber = 9100
               objNewPort.SNMPEnabled = False
               objNewPort.Put_
            End Sub
             
            Sub addPrinter (driver, port, name)
               Dim objPrinter: Set objPrinter = _
                 oService.Get("Win32_Printer").SpawnInstance_
               objPrinter.DriverName = driver
               objPrinter.PortName = port
               objPrinter.DeviceID = name
               objPrinter.Location = "Training Room"
               objPrinter.Network = True
               objPrinter.Shared = False
               rem objPrinter.ShareName =
               objPrinter.Put_
               objPrinter.SetDefaultPrinter()
            End Sub
            # Logoff (admin) script:
            Code:
            Dim oService, colInstalledPrinters, colPorts
            Dim strPortName, bSet
             
            With CreateObject("WbemScripting.SWbemLocator")
               set oService = .ConnectServer(".", "\root\cimv2")
               oService.Security_.impersonationlevel = 3
               oService.Security_.Privileges.AddAsString _
                 "SeLoadDriverPrivilege", True
            End With
            
            strPortName = "Virtual Printer"
            
            Set colInstalledPrinters = oService.ExecQuery _
               ("Select * from Win32_Printer",,48)
            
            Set colPorts = oService.ExecQuery _
               ("Select * from Win32_TCPIPPrinterPort where " _
               & "Name = '" & strPortName & "'",,48)
            
            For Each objPrinter in colInstalledPrinters
               objPrinter.CancelAllJobs()
               If UCase(objPrinter.PortName) = UCase(strPortName) Then
                 objPrinter.Delete_
               Else
                 If not bSet = True Then
                   objPrinter.SetDefaultPrinter()
                   bSet = True
                 End If
               End If
            Next
            
            For Each objPort in colPorts
               If UCase(objPort.Name) = UCase(strPortName) _
                 Then ObjPort.Delete_
            Next
            
            WScript.Quit 0

            This posting is provided "AS IS" with no warranties, and confers no rights.

            __________________

            ** Remember to give credit where credit's due **
            and leave Reputation Points for meaningful posts

            Comment


            • #7
              Re: VBS GPO Logon Script Not Executing Properly

              Rems, I checked the computer setting you mentioned and already have it set in the computer GPO applied to my test machines. I am now currently testing your scripts via the user GPO and they appear to be working as expected. Thanks so much for your assistance! Was there anything you noticed that may have been causing the issue via my original scripts? I noticed you tweaked the scripts to do the same thing, but a little differently. I am just curious if there is something inherently wrong with the way I attempted to implement it? Again, thanks so much. I really appreciate your assistance!

              Comment


              • #8
                Re: VBS GPO Logon Script Not Executing Properly

                Originally posted by nelks View Post
                I noticed you tweaked the scripts to do the same thing, but a little differently. I am just curious if there is something inherently wrong with the way I attempted to implement it? Again, thanks so much. I really appreciate your assistance!
                The most important change was adding objWMIService.Security_.Privileges.AddAsString "SeLoadDriverPrivilege" to the scripts.

                SeLoadDriverPrivilege gives service privilege to load and unload device drivers, what is required to perform administrative tasks on the spooler service.


                \Rems



                Originally posted by msdn.microsoft.com: [url=http://msdn.microsoft.com/en-us/library/Aa394363]Win32_Printer Class[/url]

                Remarks

                The Win32_Printer class is derived from CIM_Printer.
                Before calling SWbemObject.Put_ or IWbemServices::PutInstance for a Win32_Printer instance, the SeLoadDriverPrivilege privilege (wbemPrivilegeLoadDriver for Visual Basic and LoadDriver for scripting monikers) must be enabled.
                For more information, see Privilege Constants and Executing Privileged Operations.

                The following VBScript code example shows how to enable the SeLoadDriverPrivilege privilege in script.
                Code:
                Set objPrinter = GetObject( _
                    "winmgmts:{impersonationLevel=Impersonate ," _
                    & "(LoadDriver)}!//./root/cimv2:Win32_Printer")

                _

                The Win32_TCPIPPrinterPort class is derived from CIM_ServiceAccessPoint which derives from CIM_LogicalElement.
                The SeLoadDriverPrivilege privilege is required to delete an instance of this WMI class.

                The following script snippet demonstrates how to make a connection to WMI that uses this privilege.
                Code:
                Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate, (LoadDriver)}")
                _

                This posting is provided "AS IS" with no warranties, and confers no rights.

                __________________

                ** Remember to give credit where credit's due **
                and leave Reputation Points for meaningful posts

                Comment


                • #9
                  Re: VBS GPO Logon Script Not Executing Properly

                  Thanks again for the help and all the info you provided Rems. Scripts appear to be working very well. Only issue I ran into was that after throwing a couple jobs in the virtual queue, the logoff script does not appear to be able to delete the port, which is not a major issue as the jobs still get cleared and printer gets removed. I get an error message stating "Object doesn't support this property or method: 'objPort.delete' " From doing a little research it looked like that may not have been a valid method of removing that port, even though I see it mentioned in some other scripts. Curious if you ran into this as well? Again, thanks!!

                  Comment


                  • #10
                    Re: VBS GPO Logon Script Not Executing Properly

                    Originally posted by nelks View Post
                    Thanks again for the help and all the info you provided Rems. Scripts appear to be working very well. Only issue I ran into was that after throwing a couple jobs in the virtual queue, the logoff script does not appear to be able to delete the port, which is not a major issue as the jobs still get cleared and printer gets removed. I get an error message stating "Object doesn't support this property or method: 'objPort.delete' " From doing a little research it looked like that may not have been a valid method of removing that port, even though I see it mentioned in some other scripts. Curious if you ran into this as well? Again, thanks!!
                    Two different issues,
                    1. you made a typo, it should be objPort.delete_ trailed by the underscore.
                    This method is working fine. The port should be deleted without error.

                    2. when there still are printjobs in the spooldirectory when the logoff script is running, the port cannot be deleted. An error will raise.

                    A possible solution that tackles the 2nd issue is,
                    - cleanup any left behind printjobs before trying to delete the port.

                    For easy cleanup, It would be nice to use for this printer a specific spool directory instead of using the default spool directory that is also used by other printers on this computer.

                    Therefore you have to make a few changes to the admin logon script as well,
                    Code:
                    Dim oService
                    Dim strPrnDriver, strPrinterName, strPortName, strPortIP
                    
                    strPrnDriver = "HP Laserjet 5"
                    strPrinterName = "Training Room Virtual Printer"
                    strPortName = "Virtual Printer"
                    strPortIP = "127.0.0.1"
                    
                    On Error Resume Next
                    
                    With CreateObject("WbemScripting.SWbemLocator")
                       set oService = .ConnectServer(".", "\root\cimv2")
                       oService.Security_.impersonationlevel = 3
                       oService.Security_.Privileges.AddAsString _
                         "SeLoadDriverPrivilege", True 
                    End With
                    
                    '----------------------------------------------
                    'Add Printer Port (port name and ip address)
                    '----------------------------------------------
                    createPort strPortName, strPortIP
                    
                    '----------------------------------------------
                    ' Add Printer (printer driver, port name and printer name)
                    '----------------------------------------------
                    addPrinter strPrnDriver, strPortName, strPrinterName
                    
                    '----------------------------------------------
                    ' Set custom Spool folder for this printer
                    '----------------------------------------------
                    SetOwnSpoolDirectory() 
                    
                    WScript.Quit 0
                    
                    Sub createPort (name, ip)
                       Dim objNewPort: Set objNewPort = _
                         oService.Get("Win32_TCPIPPrinterPort").SpawnInstance_
                       objNewPort.Name = name
                       objNewPort.Protocol = 1
                       objNewPort.HostAddress = ip
                       objNewPort.PortNumber = 9100
                       objNewPort.SNMPEnabled = False
                       objNewPort.Put_
                    End Sub
                     
                    Sub addPrinter (driver, port, name)
                       Dim objPrinter: Set objPrinter = _
                         oService.Get("Win32_Printer").SpawnInstance_
                       objPrinter.DriverName = driver
                       objPrinter.PortName = port
                       objPrinter.DeviceID = name
                       objPrinter.Location = "Training Room"
                       objPrinter.Network = True
                       objPrinter.Shared = False
                       rem objPrinter.ShareName =
                       objPrinter.Put_
                       objPrinter.SetDefaultPrinter()
                    End Sub
                    
                    Sub SetOwnSpoolDirectory()
                       Dim objFSO, objFolder
                       Dim RegPath, strDefaultSpoolDirectory
                    
                       Set objFSO = CreateObject("Scripting.FileSystemObject")
                    
                       On Error Resume next
                       WaitUntilService "Spooler", "Stopped"
                    
                       With CreateObject("Wscript.shell")
                         RegPath = "HKLM\SYSTEM\CurrentControlSet\Control\Print\Printers"
                         strDefaultSpoolDirectory = .RegRead(RegPath & "\DefaultSpoolDirectory")
                         objFSO.CreateFolder(strDefaultSpoolDirectory & "\" & strPortName)
                         .RegWrite RegPath & "\"  & strPrinterName & "\SpoolDirectory", strDefaultSpoolDirectory & "\" & strPortName
                       End With
                    
                       WaitUntilService "Spooler", "Running"
                    End Sub
                    
                    Sub WaitUntilService(service, state)
                       Dim objSpoolSv
                       ' values for 'state' are
                       ' "Stopped" or "Running".
                    
                       Set objSpoolSv = oService.Get("Win32_Service.Name='" _
                         & service & "'")
                       If UCase(state)="STOPPED" then
                         objSpoolSv.StopService()
                       ElseIf UCase(state)="RUNNING" then
                         objSpoolSv.StartService()
                       Else
                         exit Sub
                       End If
                       Do until lcase(objSpoolSv.state) = lcase(state)
                         Set objSpoolSv = oService.Get("Win32_Service.Name='" _
                           & service & "'")
                         wsh.sleep 50
                       Loop
                    End Sub
                    And, this would then be the admin logoff script,
                    Code:
                    Dim oService, colInstalledPrinters, prnPort, objPrinter
                    Dim strPrinterName, strPortName, bSet
                    Dim objFSO, RegPath, strSpoolDirectory
                    
                    strPrinterName = "Training Room Virtual Printer"
                    strPortName = "Virtual Printer"
                    
                    On Error Resume next
                    
                    Set objFSO = CreateObject("Scripting.FileSystemObject")
                    
                    With CreateObject("WbemScripting.SWbemLocator")
                       set oService = .ConnectServer(".", "\root\cimv2")
                       oService.Security_.impersonationlevel = 3
                       oService.Security_.Privileges.AddAsString _
                         "SeLoadDriverPrivilege", True
                    End With
                    
                    Set prnPort = oService.Get("Win32_TCPIPPrinterPort.Name='" & strPortName & "'")
                    
                    With CreateObject("Wscript.shell")
                       RegPath = "HKLM\SYSTEM\CurrentControlSet\Control\Print\Printers"
                       strSpoolDirectory = .RegRead(RegPath & "\"  & strPrinterName & "\SpoolDirectory")
                    End With
                    
                    Set colInstalledPrinters = oService.ExecQuery _
                       ("Select * from Win32_Printer",,48)
                    
                    For Each objPrinter in colInstalledPrinters
                       objPrinter.CancelAllJobs()
                       If UCase(objPrinter.PortName) = UCase(strPortName) Then
                         objPrinter.Delete_
                       Else
                         If not bSet = True Then
                           objPrinter.SetDefaultPrinter()
                           bSet = True
                         End If
                       End If
                    Next
                    
                    RemoveOwnSpoolerFiles(strSpoolDirectory)
                    
                    prnPort.Delete_
                    
                    objFSO.DeleteFolder(strSpoolDirectory),True
                    
                    WScript.Quit 0
                    
                    Sub RemoveOwnSpoolerFiles(strSpoolDirectory)
                       Dim objFld, oFile
                    
                       WaitUntilService "Spooler", "Stopped"
                       WaitUntilService "Spooler", "Running"
                    
                       On Error Resume Next
                       WaitUntilService "Spooler", "Stopped"
                       Set objFld = objFSO.GetFolder(strSpoolDirectory)
                       For Each oFile In objFld.Files
                         oFile.Delete True
                       Next
                       WaitUntilService "Spooler", "Running"
                    End Sub
                    
                    Sub WaitUntilService(service, state)
                       Dim objSpoolSv
                       ' values for 'state' are
                       ' "Stopped" or "Running".
                    
                       Set objSpoolSv = oService.Get("Win32_Service.Name='" _
                         & service & "'")
                       If UCase(state)="STOPPED" then
                         objSpoolSv.StopService()
                       ElseIf UCase(state)="RUNNING" then
                         objSpoolSv.StartService()
                       Else
                         exit Sub
                       End If
                       Do until lcase(objSpoolSv.state) = lcase(state)
                         Set objSpoolSv = oService.Get("Win32_Service.Name='" _
                           & service & "'")
                         wsh.sleep 50
                       Loop
                    End Sub
                    \Rems

                    This posting is provided "AS IS" with no warranties, and confers no rights.

                    __________________

                    ** Remember to give credit where credit's due **
                    and leave Reputation Points for meaningful posts

                    Comment


                    • #11
                      Re: VBS GPO Logon Script Not Executing Properly

                      Thanks again for all your help Rems. I've been out of the office for a few days, but I will give this a try now that I'm back. Your help has been greatly appreciated!!

                      Comment

                      Working...
                      X