[VBS and Batch] Elevate program as admin with full arguments and special chars (incl Quote), no TMP.

Discussion in 'Scripting' started by hearywarlot, May 20, 2017.

  1. hearywarlot

    hearywarlot MDL Member

    Jul 31, 2015
    110
    111
    10
    #1 hearywarlot, May 20, 2017
    Last edited: Jul 25, 2017
    This is a VBS which can be used to elevate programs as admin and pass arguments with special characters (including quotes).

    When you want to use your Batch script to automatically install packages, access privileged folders and do certain stuff with your OS, you would need to elevate it's privileges to runas Admin.
    However, this may be tiring or annoying so you may wish to do this automatically upon running the script, problem though is CMD has no capability at all for this, so we need something more, such as VBS.

    While this will work easily using 'Shell.Application' object, you may want to pass arguments with quotes and spaces.
    This however is pretty annoying to deal with, actually quotes in arguments I heard to be impossible to deal with, forcing people to have to use a substitute in arguments that the script must turn into a quote.
    So basically can not pass some arguments as is and have to deal with messy code.

    So I wrote a script people can use to easily elevate their script and pass any arguments as is, as long as it is valid enough to not break batch.


    Usage:
    There is only a single required switch:

    • /File:"<File>"
    You should make sure to always include the '/File' just before your arguments and to use it exactly like described with quotes (obviously substituting '<File>' with the file you wanna elevate).
    This is because that parameter will be used to split the script part and your arguments.

    You can execute the VBS from a script or from CMD.
    Code:
    Code:
    elevate.vbs /File:"test.cmd" "Welcome" NextAEscapedQuote ^^^^^^^" NextupSomeSpecialChars "!@#$%^^&*()_+-="";\|/?" "What about This?" That's Enough ^^^^^^^".

    Code:
    In case you only want the VBS code, use the code below.

    elevate.vbs
    Code:
    Set strArg=WScript.Arguments.Named
    
    If Not strArg.Exists("File") Then
        Wscript.Echo "Switch /File:<File> is missing."
        WScript.Quit 1
    End If
    
    Set strRdlproc = CreateObject("WScript.Shell").Exec("rundll32 kernel32,Sleep")
    With GetObject("winmgmts:\\.\root\CIMV2:Win32_Process.Handle='" & strRdlproc.ProcessId & "'")
        With GetObject("winmgmts:\\.\root\CIMV2:Win32_Process.Handle='" & .ParentProcessId & "'")
            If InStr (.CommandLine, WScript.ScriptName) <> 0 Then
                strLine = Mid(.CommandLine, InStr(.CommandLine , "/File:") + Len(strArg("File")) + 8)
            End If
        End With
        .Terminate
    End With
    
    CreateObject("Shell.Application").ShellExecute "cmd", "/c " & chr(34) & chr(34) & strArg("File") & chr(34) & " " & strLine & chr(34), "", "runas", 1

    In case you want the VBS code without the pass argument part, use the code below.

    elevate_no-arguments.vbs
    Code:
    Set strArg = WScript.Arguments.Named
    If Not strArg.Exists("File") Then
       Wscript.Echo "Switch /File:<File> is missing."
       WScript.Quit 1
    End If
    CreateObject("Shell.Application").ShellExecute strArg("File"), ELAV, "", "runas", 1

    In case you want to use a single Hybrid Batch/VBS file without TMP files, Checkout the code below.
    This the sample file I use for Elevate script examples, edit to your needs.
    Note: the first line is part of the script, it tells WSH this is a Job script, so the VBS is executed without TMP.

    elevate.cmd
    Code:
    <!-- : Begin batch script
    
    @ECHO OFF
    
    FSUTIL dirty query "%SYSTEMDRIVE%" >NUL || (
       ECHO(*************************************
       ECHO(Invoking UAC for Privilege Escalation
       ECHO(*************************************
       CSCRIPT //nologo "%~f0?.wsf" //job:ELAV /File:"%~f0" ^^^^^^^& Wscript.Echo hacked? "Haha Nope" --file "Moz Fir.exe" nextsomespecialsymbols "!@#$%^^&*()_+-="";\|/?"  ^^^^^^^"
       EXIT /B
    )
    
    ECHO Running as elevated user
    ECHO(
    ECHO(%1
    ECHO(%2
    ECHO(%3
    ECHO(%4
    ECHO(%5
    ECHO(%6
    ECHO(%7
    ECHO(%8
    ECHO(%9
    ECHO(%*
    PAUSE
    EXIT /B
    
    ----- Begin wsf script --->
    <package>
       <job id="ELAV">
           <script language="VBScript">
               Set strArg=WScript.Arguments.Named
    
               If Not strArg.Exists("File") Then
                   Wscript.Echo "Switch /File:<File> is missing."
                   WScript.Quit 1
               End If
    
               Set strRdlproc = CreateObject("WScript.Shell").Exec("rundll32 kernel32,Sleep")
               With GetObject("winmgmts:\\.\root\CIMV2:Win32_Process.Handle='" & strRdlproc.ProcessId & "'")
                   With GetObject("winmgmts:\\.\root\CIMV2:Win32_Process.Handle='" & .ParentProcessId & "'")
                       If InStr (.CommandLine, WScript.ScriptName) <> 0 Then
                           strLine = Mid(.CommandLine, InStr(.CommandLine , "/File:") + Len(strArg("File")) + 8)
                       End If
                   End With
                   .Terminate
               End With
    
              CreateObject("Shell.Application").ShellExecute "cmd", "/c " & chr(34) & chr(34) & strArg("File") & chr(34) & " " & strLine & chr(34), "", "runas", 1
           </script>
       </job>
    </package>

    If you find any bugs and also have a solution, please post so I can try solve it :).
    I hope it will be a good contribution to the internet, since I have tried making a end of all scripts solution.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...