VBS GPO Logon Script Not Executing Properly

Home Forums Scripting Windows Script Host VBS GPO Logon Script Not Executing Properly

This topic contains 10 replies, has 4 voices, and was last updated by Avatar spinmind 9 years, 1 month ago.

Viewing 11 posts - 1 through 11 (of 11 total)
  • Author
    Posts
  • Avatar
    nelks
    Member
    #151787

    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.

    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 & “rootcimv2”)
    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
    [/CODE]
    #2 Clear all print jobs, remove printer[CODE]

    On Error Resume Next

    Dim objWMIService,strArgument

    Set objWMIService = GetObject(“winmgmts:{impersonationLevel=impersonate}!\.rootcimv2”)
    Set colInstalledPrinters = objWMIService.ExecQuery (“Select * from Win32_Printer”)

    For Each objPrinter in colInstalledPrinters
    objPrinter.CancelAllJobs()
    Next

    Set objShell = CreateObject(“Wscript.Shell”)
    strArgument = “c:windowssystem32rundll32.exe printui.dll,PrintUIEntry /dl /n ” & chr(34) & “Training Room Virtual Printer” & chr(34)
    objShell.Run strArgument

    WScript.Quit
    [/CODE][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 & “rootcimv2”)
    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
    [/CODE]
    #2 Clear all print jobs, remove printer

    On Error Resume Next

    Dim objWMIService,strArgument

    Set objWMIService = GetObject(“winmgmts:{impersonationLevel=impersonate}!\.rootcimv2”)
    Set colInstalledPrinters = objWMIService.ExecQuery (“Select * from Win32_Printer”)

    For Each objPrinter in colInstalledPrinters
    objPrinter.CancelAllJobs()
    Next

    Set objShell = CreateObject(“Wscript.Shell”)
    strArgument = “c:windowssystem32rundll32.exe printui.dll,PrintUIEntry /dl /n ” & chr(34) & “Training Room Virtual Printer” & chr(34)
    objShell.Run strArgument

    WScript.Quit
    [/CODE][CODE]

    On Error Resume Next

    Dim objWMIService,strArgument

    Set objWMIService = GetObject(“winmgmts:{impersonationLevel=impersonate}!\.rootcimv2”)
    Set colInstalledPrinters = objWMIService.ExecQuery (“Select * from Win32_Printer”)

    For Each objPrinter in colInstalledPrinters
    objPrinter.CancelAllJobs()
    Next

    Set objShell = CreateObject(“Wscript.Shell”)
    strArgument = “c:windowssystem32rundll32.exe printui.dll,PrintUIEntry /dl /n ” & chr(34) & “Training Room Virtual Printer” & chr(34)
    objShell.Run strArgument

    WScript.Quit
    [/CODE]

    Avatar
    ScottMcD
    Member
    #352876

    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.

    Avatar
    spinmind
    Member
    #378515

    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.

    Rems
    Rems
    Moderator
    #227875

    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

    Avatar
    spinmind
    Member
    #378516

    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.

    Rems
    Rems
    Moderator
    #227876

    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(“.”, “rootcimv2”)
    oService.Security_.impersonationlevel = 3
    oService.Security_.Privileges.AddAsString _
    “SeLoadDriverPrivilege”, True
    End With

    strPortName = “[COLOR=”Blue”]Virtual Printer[/COLOR]”
    strPortIP = “[COLOR=”blue”]127.0.0.1[/COLOR]”

    ‘———————————————-
    ‘Add Printer Port (port name and ip address)
    ‘———————————————-
    createPort strPortName, strPortIP

    ‘———————————————-
    ‘ Add Printer (printer driver, port name and printer name)
    ‘———————————————-
    addPrinter “[COLOR=”Blue”]HP Laserjet 5[/COLOR]”, strPortName, “[COLOR=”blue”]Training Room Virtual Printer[/COLOR]”

    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 = “[COLOR=”Blue”]Training Room[/COLOR]”
    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(“.”, “rootcimv2”)
    oService.Security_.impersonationlevel = 3
    oService.Security_.Privileges.AddAsString _
    “SeLoadDriverPrivilege”, True
    End With

    strPortName = “[COLOR=”blue”]Virtual Printer[/COLOR]”

    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

    Avatar
    spinmind
    Member
    #378517

    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! :-D

    Rems
    Rems
    Moderator
    #227884

    Re: VBS GPO Logon Script Not Executing Properly

    nelks;222954 wrote:
    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! :-D

    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

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

    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.
    [COLOR=”DarkSlateGray”]Set objPrinter = GetObject( _
    “winmgmts:{impersonationLevel=Impersonate ,” _
    & “([B]LoadDriver[/B])}!//./root/cimv2:Win32_Printer”)[/COLOR][/CODE][/COLOR]
    _

    [COLOR=”DarkSlateGray”]The [B]Win32_TCPIPPrinterPort class[/B] is derived from [URL=”http://msdn.microsoft.com/en-us/library/aa388447(v=VS.85).aspx”]CIM_ServiceAccessPoint[/URL] which derives from [URL=”http://msdn.microsoft.com/en-us/library/aa387892(v=VS.85).aspx”]CIM_LogicalElement[/URL].
    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][COLOR=”DarkSlateGray”]Set objWMIService = GetObject(“winmgmts:{impersonationLevel=impersonate, ([B]LoadDriver[/B])}”)[/COLOR][/CODE][/COLOR]_[/QUOTE][CODE]Set objPrinter = GetObject( _
    “winmgmts:{impersonationLevel=Impersonate ,” _
    & “(LoadDriver)}!//./root/cimv2:Win32_Printer”)
    [/CODE]
    _

    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.
    [COLOR=”DarkSlateGray”]Set objWMIService = GetObject(“winmgmts:{impersonationLevel=impersonate, ([B]LoadDriver[/B])}”)[/COLOR][/CODE][/COLOR]_[/QUOTE][CODE]Set objWMIService = GetObject(“winmgmts:{impersonationLevel=impersonate, (LoadDriver)}”)[/CODE]_

    Avatar
    spinmind
    Member
    #378518

    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!! :-D

    Rems
    Rems
    Moderator
    #227886

    Re: VBS GPO Logon Script Not Executing Properly

    nelks;222977 wrote:
    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!! :-D

    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 = “[COLOR=”Blue”]HP Laserjet 5[/COLOR]”
    strPrinterName = “[COLOR=”blue”]Training Room Virtual Printer[/COLOR]”
    strPortName = “[COLOR=”blue”]Virtual Printer[/COLOR]”
    strPortIP = “[COLOR=”blue”]127.0.0.1[/COLOR]”

    On Error Resume Next

    With CreateObject(“WbemScripting.SWbemLocator”)
    set oService = .ConnectServer(“.”, “rootcimv2”)
    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 = “[COLOR=”blue”]Training Room[/COLOR]”
    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 = “HKLMSYSTEMCurrentControlSetControlPrintPrinters”
    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 = “[COLOR=”blue”]Training Room Virtual Printer[/COLOR]”
    strPortName = “[COLOR=”blue”]Virtual Printer[/COLOR]”

    On Error Resume next

    Set objFSO = CreateObject(“Scripting.FileSystemObject”)

    With CreateObject(“WbemScripting.SWbemLocator”)
    set oService = .ConnectServer(“.”, “rootcimv2”)
    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 = “HKLMSYSTEMCurrentControlSetControlPrintPrinters”
    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

    Avatar
    spinmind
    Member
    #378519

    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!!

Viewing 11 posts - 1 through 11 (of 11 total)

You must be logged in to reply to this topic.