Answered VBScript - Shell.run with spaces - prnmngr.vbs

  • quarta-feira, 2 de setembro de 2009 02:11
     
     

    The following script does nothing.  I believe server & share names are correct.   I believe the problem is spaces in the path for oWshShell.run but I haven't been able to figure out the correct syntax.   When I try various combinations of double quotes: 
         oWshShell.Run ""..."" , etc
    then I can generate errors but no execution. 

    Script is intended to run on Server 03, XP, Vista, Server 08, I am testing on Vista.  I am logged in as a user with local Admin rights, UAC is disabled.


    Thanks for any suggestions or improvements.


    =============================================================
    =============================================================
    Option Explicit
    On Error Resume Next

    '=================== Declare Constants / Variables ======================
    'Variables
    Dim sComputer
    Dim sScriptsPath
    Dim sScriptsPathVista
    Dim sPrintServer1
    Dim sPrintShare1
    Dim sPrintShare2
    Dim sPrintShare3
    DIM sWinDir

    'Objects
    Dim oFolder
    Dim oFSO
    Dim iOSVer
    Dim oWshNetwork
    Dim oWshShell

    'Constants
    Dim ADD_NTWKPRTR_DEFAULT
    Dim ADD_NTWKPRTR 

    sComputer = "."       
    sScriptsPath = "\System32"    
    sScriptsPathVista = "\System32\Printing_Admin_Scripts\en-US"
              
    sPrintServer1 = "\\Serv1"    
    sPrintShare1 = "\HP_ColorLaser_2550" 
    sPrintShare2 = "\HP_Deskjet_6980"  
    sPrintShare3 = ""      
              
    'Constants
    ADD_NTWKPRTR_DEFAULT = "\prnmngr.vbs -ac -p -t "
    ADD_NTWKPRTR = "\prnmngr.vbs -ac -p "

    '=================== Object Creation ======================================
    set oWshNetwork = CreateObject("Wscript.Network")
    set oFSO = CreateObject("Scripting.FileSystemObject")
    set oWshShell = WScript.CreateObject("WScript.Shell")
     
    '=================== Main Logic ===========================================
    'Get WinDir =================
    sWinDir = oWshShell.ExpandEnvironmentStrings("%WinDir%")

    'Get the OS Version for pathing
    GetOS
    Sub GetOS
    DIM oWMIService
    DIM oOS
    DIM cOSes
    Set oWMIService = GetObject("winmgmts:" _
        & "{impersonationLevel=impersonate}!\\" & sComputer & "\root\cimv2")
     Set cOSes = oWMIService.ExecQuery("Select * from Win32_OperatingSystem")
     For Each oOS in cOSes
      iOSVer = oOS.Version
     Next
    End Sub

    'If OS ver >=6 then change change path to Vista/Server08===============
    If CInt(Left(iOSVER,2)) >= 6 Then
     sScriptsPath = sWinDir & sScriptsPathVista
     Else
     sScriptsPath = sWinDir & sScriptsPath
    End If

    'Add Printer #1 & set as default

    oWshShell.Run sPrinterScriptsPath & ADD_NTWKPRTR_DEFAULT & sPrintServer1 & sPrintShare1

    QuitScript

    '============================================
    'Sub QuitScript
    Sub QuitScript
     Set oFolder = Nothing
     Set oFSO = Nothing
     Set oWMIService = Nothing
     Set oWshNetwork = Nothing
     Set oWshShell = Nothing
     Wscript.Quit
    End Sub
    '============================================

Todas as Respostas

  • quarta-feira, 2 de setembro de 2009 12:27
    Moderador
     
     
    I see an additional problem to the one of getting the correct quotes.  That is, the Run statement uses a variable named sPrinterScriptsPath, which is undefined in the code you posted.  Did you mean it to be sScriptsPath, which is defined?

    Then to get the proper quoting, you will need to separate the script's switches from its name or include a double quote in the definition of ADD_NTWKPRTR_DEFAULT & ADD_NTWKPRTR.  I would do it by separating the switches, something like this ...

    sScriptName = "\prnmngr.vbs"
    ADD_NTWKPRTR_DEFAULT = " -ac -p -t "
    ADD_NTWKPRTR = " -ac -p "

    then in the later IF statement ...

    If CInt(Left(iOSVER,2)) >= 6 Then
     sScriptsPath = sWinDir & sScriptsPathVista & sScriptName
     Else
     sScriptsPath = sWinDir & sScriptsPath & sScriptName
    End If

    and finally, the Run statement becomes ...

    oWshShell.Run Chr(34) & sScriptsPath & Chr(34) & ADD_NTWKPRTR_DEFAULT & sPrintServer1 & sPrintShare1

    Where Chr(34) returns a double quote character. However, unless the WINDIR definition includes a space, the double quote marks really aren't needed, with the paths you have shown.  None of them contain a delimiter to make it necessary - so, your problem may just be the variable name mismatch.

    Finally, the QuitScript routine seems unnecessary to me, since the normal exit of a script performs all of those things automatically. 
    Tom Lavedas
  • quarta-feira, 2 de setembro de 2009 13:31
    Moderador
     
      Contém Código
    Hey Tom

    You could insert Character codes to place quotes in a string (but the chances are you probably won't remember what the code Chr(34) means next time your reviewing the script) so here is a really simple function I thought i'd share with you that has saved me heaps of time and trouble with command syntax.
    '----------------------------------------------------------------------------------------------------------------------------
    'Name       : DQ          -> Place double quotes around a string and replace double quotes
    '           :             -> within the string with pairs of double quotes.
    'Parameters : stringValue -> String value to be double quoted
    'Return     : DQ          -> Double quoted string.
    '----------------------------------------------------------------------------------------------------------------------------
    Function DQ(ByVal stringValue)
       If stringValue <> "" Then
          DQ = """" & Replace (stringValue, """", """""") & """"
       Else
          DQ = """"""
       End If
    End Function
    '----------------------------------------------------------------------------------------------------------------------------
    The your code becomes a lot more readable...For example

    wshShell.Run DQ(scriptPath) & ADD_NTWKPRTR_DEFAULT & printServer1 & printServer2

    And the next time you every have trouble with a command syntax requiring double quotes just call the function.

    Hope that's useful

    Cheers

    Matt :)
  • quarta-feira, 2 de setembro de 2009 20:06
     
     

    Thanks very much for the reply.   The undefined variable was definitely part of problem, dohhh!  I have cleaned it up and made the other suggested changes, new code is below.  Using wscript.echo I'm not seeing any spaces where I don't expect them. 

    The code below, run on Vista and XP from a cmd prompt as "cscript.ext test1.vbs", returns a Windows Script Host Error "This script should be executed from the Command Prompt using CScript.exe."  That seems like a big clue....?

    The wscript.echo output is:

    "C:\Windows\System32\Printing_Admin_Scripts\en-US\Prnmngr.vbs" -ac -p -t \\Serv1\HP_ColorLaser_2550

    I have tried adding/moving quotes/Chr(34) around but can't find the correct combination.

    "C:\Windows\System32\Printing_Admin_Scripts\en-US\Prnmngr.vbs -ac -p -t" "\\Serv1\HP_ColorLaser_2550"
    Returns:
    '"C:\Windows\System32\Printing_Admin_Scripts\en-US\Prnmngr.vbs -ac -p -t"' is not recognized as an internal or external command,
    operable program or batch file.

    Suggestions appreciated.

    =============================================================
    =============================================================
    Option Explicit
    On Error Resume Next

    '=================== Declare Constants / Variables ======================
    'Variables
    Dim sComputer
    Dim bDFS
    Dim sScriptName
    Dim sScriptPath
    Dim sScriptPathVista
    Dim sPrintServer1
    Dim sPrintShare1
    Dim sPrintShare2
    Dim sPrintShare3
    Dim sWinDir

    'Objects
    Dim oFolder
    Dim oFSO
    Dim iOSVer
    Dim oWshNetwork
    Dim oWshShell

    'Constants
    Dim ADD_NTWKPRTR
    Dim ADD_NTWKPRTR_DEFAULT
    Dim DFS_ROOT      

    Dim DOMAIN_NAME      
    Dim DRIVER_SOURCE_DIR
    Dim FILE_SERVER
    Dim PRINTSCRIPT1
    Dim PRINTSCRIPT2
    Dim PRINTSCRIPT3
    Dim PRINTSCRIPT4
    Dim PRINTSCRIPT5
    Dim PRINTSCRIPT6
    Dim SOURCEPATH

    '=================== Set Values / Create Objects ===========================
    '
    'Variables
    bDFS = False       
    sComputer = "."
    sScriptPath = "\System32"
    sScriptPathVista = "\System32\Printing_Admin_Scripts\en-US"
    sPrintServer1 = "\\Serv1"
    sPrintShare1 = "\HP_ColorLaser_2550"
    sPrintShare2 = "\HP_Deskjet_6980"
    sPrintShare3 = ""
              
    'Constants
    ADD_NTWKPRTR_DEFAULT = " -ac -p -t "
    ADD_NTWKPRTR = " -ac -p "
    PRINTSCRIPT1 = "\Prncnfg.vbs"
    PRINTSCRIPT2 = "\Prndrvr.vbs"
    PRINTSCRIPT3 = "\Prnjobs.vbs"
    PRINTSCRIPT4 = "\Prnmngr.vbs"
    PRINTSCRIPT5 = "\Prnport.vbs"
    PRINTSCRIPT6 = "\Prnqctl.vbs"

    '==================Object Creation========================================
    set oWshNetwork = CreateObject("Wscript.Network")
    set oFSO = CreateObject("Scripting.FileSystemObject")
    set oWshShell = WScript.CreateObject("WScript.Shell")
     
    '==================Main Logic=============================================
    '==================Get WinDir=============================================
    sWinDir = oWshShell.ExpandEnvironmentStrings("%WinDir%")

    '==================Get the OS Version=====================================
    GetOS
    Sub GetOS
    DIM oWMIService
    DIM oOS
    DIM cOSes
    Set oWMIService = GetObject("winmgmts:" _
        & "{impersonationLevel=impersonate}!\\" & sComputer & "\root\cimv2")
     Set cOSes = oWMIService.ExecQuery("Select * from Win32_OperatingSystem")
     For Each oOS in cOSes
      iOSVer = oOS.Version
     Next
    End Sub

    '==================Change root path if Vista/Server08=====================
    If CInt(Left(iOSVER,2)) >= 6 Then
     sScriptPath = sWinDir & sScriptPathVista
     Else
     sScriptPath = sWinDir & sScriptPath
    End If
    '=========================================================================
    '==================Add Network Printer Connections========================
    sScriptPath = sScriptPath & PRINTSCRIPT4

    'Add Printer #1 & Set As Default
    wscript.echo Chr(34) & sScriptPath & Chr(34) & ADD_NTWKPRTR_DEFAULT & sPrintServer1 & sPrintShare1
    oWshShell.Run Chr(34) & sScriptPath & Chr(34) & ADD_NTWKPRTR_DEFAULT & sPrintServer1 & sPrintShare1

    'Add Printer #2
    '
    'Add Printer #3
    '
    '=========================================================================
    '==================Delete Network Printer Connection======================
    'sScriptPath = sScriptPath & PRINTSCRIPT4
    '
    '=========================================================================
    '==================Install Local Printer & Driver=========================
    'sScriptPath = sScriptPath &
    '=========================================================================
    '==================Clear Printer Q, Unpause Q & Resume====================
    'sScriptPath = sScriptPath &
    '=========================================================================
    '==================Delete Local Printer===================================
    'sScriptPath = sScriptPath &
    '=========================================================================

    Wscript.Quit

  • quarta-feira, 2 de setembro de 2009 21:32
    Moderador
     
     
    Try this ...

    Add Printer #1 & Set As Default
    sCmd = "cscript.exe " & Chr(34) & sScriptPath & Chr(34)
    wscript.echo sCmd & ADD_NTWKPRTR_DEFAULT & sPrintServer1 & sPrintShare1
    oWshShell.Run sCmd & ADD_NTWKPRTR_DEFAULT & sPrintServer1 & sPrintShare1

    Tom Lavedas
  • sexta-feira, 4 de setembro de 2009 04:39
     
     

    Tom, thanks very much for your help to date, much appreciated.  I have been testing and your suggestion works well with a minor change:

    oWshShell.Run sCmd & ADD_NTWKPRTR & Chr(34) & sPrintServer1 & sPrintName1 & Chr(34)

    which corresponds to the following output (w/out -t for setting as default):

    cscript.exe "C:\Windows\System32\Printing_Admin_Scripts\en-US\Prnmngr.vbs" -ac -p "\\Serv1\HP_ColorLaser_2550"


    There are a few issues/catches that don't appear related to the original problems: 

    1. For the next person, the correct syntax is "-p \\Server\Printer".  I assumed the switch order didn't matter, but I can see now why it does. 

    2. Setting the default printer w/ "-t" errors out for me with:

    C:\Windows\Systm32\Printing_Admin_Scripts\en-US\Prnmngr.vbs(818, 9) SWbemServicesEx: Not found

    This happens on both XP & Vista.  This was fixed by disabling Point and Print Security with a GP change.  However, I now get a very fast cmd window that doesn't error out but also doesn't install the printer connection.  I am unable to debug it further.

    3. The actuall printer install (w/out -t) takes a bit of time to run so I put in an

    sWaitMessage = "Printer install occurring, please don't close this window."
    wscript.echo sWaitMessage

    assuming it would appear in one of the cmd windows, instead it appears as a popup?

  • sexta-feira, 4 de setembro de 2009 12:40
    Moderador
     
     Respondido
    I'm not certain if I can provide any more assistance, since your problem seems to be related to the functioning of one of the scripts you are executing from this one.  Since I have no visibility into that script, there's no way I can make any specific suggestion.  However, as a general rule it would seem necessary to execute that script manually from a command prompt using the arguments that are being passed from the one you have posted in the situation where it is failing.  That should make it easier to understand what is going on.  Once you get that debugged, you can continue with this one.

    Also, note that your script is not waiting for the called procedures to end before it continues.  Should it?  if so, you need to add two more arguments to the Run statement ...

      bWaitforReturn = true
      oWshShell.Run sCmd & ..., 1, bWaitforReturn

    Also, to help troubleshoot your problems with the called script(s), try adding an explicit call to the command processor with its /K (keep) command line switch, as in ...

      bWaitforReturn = true
      oWshShell.Run "%comspec% /k " & sCmd & ..., 1, bWaitforReturn

    Then the console will remain open at the command prompt after the called script ends until you close it (click the closs box or enter EXIT command at the prompt).  Then you can read any error messages.  You can also put wsh.echo statements in the called script to show its progress to further assist the troubleshooting.

    Finally, since the 'wscript.echo sWaitMessage' output is contained in your main script (run from the Windows GUI under the default wscript.exe host, I assume), its output is directed to that GUI environment.  To have it directed to the command console either run it under cscript.exe from the command console or put the message in the called script.

    HTH


    Tom Lavedas
  • sexta-feira, 18 de setembro de 2009 17:31
     
     
    Thanks for all of your help, I had to move on to another issue but I will look at this again and will try your suggestions.

    Best Regards.