user3629873
user3629873

Reputation: 91

Get errorlevel in bat from vbscript

I’m trying to determine, whether the user clicked NO in the UAC-prompt and if so to not set up the nul-port.

I'm calling this script form a batch-file, which I'd like to exit, if the user clicked no.

The VBScript:

Option Explicit

Main 

Sub Main

    Dim oShell, objWMIService, servSpooler, objReg, objShellApp, result

    Const PrinterPort = "NUL:"
    Const HKLM = &h80000002

    If Not WScript.Arguments.Named.Exists("elevate") Then
        Set objShellApp = CreateObject("Shell.Application")
        objShellApp.ShellExecute WScript.FullName, WScript.ScriptFullName & " /elevate", "", "runas", 0
        WScript.Quit 
    End If

    result = isElevated()

    If result = True Then
        Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
        set servSpooler = objWMIService.Get("Win32_Service.Name='spooler'")
        Set objReg = GetObject("winmgmts:root\default:StdRegProv")

        servSpooler.StopService
        objReg.SetStringValue HKLM, "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Ports", PrinterPort, ""
        servSpooler.StartService
    Else
        WScript.Quit 1
    End If

End Sub

Function isElevated
    Dim shell, whoami, whoamiOutput, strWhoamiOutput

    Set shell = CreateObject("WScript.Shell")
    Set whoami = shell.Exec("whoami /groups")
    Set whoamiOutput = whoami.StdOut
    strWhoamiOutput = whoamiOutput.ReadAll

    If InStr(1, strWhoamiOutput, "S-1-16-12288", vbTextCompare) Then
        isElevated = True
    Else
        isElevated = False
    End If
End Function

The batch:

cscript "set_port.vbs"
IF ERRORLEVEL 1 (
    ECHO FAIL
    PAUSE
    EXIT
)

Now, I looked at this page:

http://www.robvanderwoude.com/errorlevel.php

and some others and I feel like I tried every possible combination. Probably, I just haven’t had the correct combination yet. Some tips and help would be highly appreciated!

The basic goal: Determine, whether the user clicked NO in the UAC-prompt and then end the VBScript and batch-file.

UPDATE:

Okay, thanks for all the answers so far. I'm pretty certain now it's the script. I use the errorlevel again in the batch-file and there it works just fine now.

As for the VBScript: In Order to have an error code of let's say 1 when the user clicks NO in the UAC prompt (meaning the current file is not elevated), I need to put it like this:

If result = True Then
    Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
    set servSpooler = objWMIService.Get("Win32_Service.Name='spooler'")
    Set objReg = GetObject("winmgmts:root\default:StdRegProv")

    servSpooler.StopService
    objReg.SetStringValue HKLM, "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Ports", PrinterPort, ""
    servSpooler.StartService
    WScript.Quit(0)
Else
    WScript.Quit(1)
End If

But: in the first WScript.Quit after the ShellExecute, I also need to put WScript.Quit(1), right? Because otherwise I never get an error to be passed to errorlevel (or at least not greater than 0).

So:

    objShellApp.ShellExecute WScript.FullName, WScript.ScriptFullName & " /elevate", "", "runas", 0
    WScript.Quit(1)

The big problen, I guess, is that clicking NO on the UAC promtp doesnt eally cause an error, so I need to put WSCript.Quit(1) there.

OR i do it the other way round and say: WScript.Quit(1) when the user clicked YES and the script is elevated and put WScript.Quit(0) everyhwere else.

However, in the first case I always get errorlevel 1 and in the second case always errorlevel 0.

----------- UPDATE:

My VBScript file looks like this now:

    Option Explicit

    Main 

    Sub Main

    Dim objShell, objWMIService, servSpooler, objReg, objShellApp, result, oShell
    Dim whoami, strWhoamiOutput, whoamiOutput

        Const PrinterPort = "NUL:"
        Const HKLM = &h80000002

    If Not WScript.Arguments.Named.Exists("elevate") Then
            Set objShellApp = CreateObject("Shell.Application")
            objShellApp.ShellExecute WScript.FullName, WScript.ScriptFullName & " /elevate", "", "runas", 0
            WScript.Quit 10
WScript.Echo("Done")
    Else

        Set oShell = CreateObject("WScript.Shell")
        Set whoami = oShell.Exec("whoami /groups")
        Set whoamiOutput = whoami.StdOut
        strWhoamiOutput = whoamiOutput.ReadAll

        If InStr(1, strWhoamiOutput, "S-1-16-12288", vbTextCompare) Then
            Wscript.Echo("ADMIN")
            WScript.Echo("Port")
            Set objWMIService = GetObject("winmgmts:{impersonationLevel=impersonate}!\\.\root\cimv2")
            set servSpooler = objWMIService.Get("Win32_Service.Name='spooler'")
            Set objReg = GetObject("winmgmts:root\default:StdRegProv")

            servSpooler.StopService
            objReg.SetStringValue HKLM, "SOFTWARE\Microsoft\Windows NT\CurrentVersion\Ports", PrinterPort, ""
            servSpooler.StartService
            WScript.Quit 1
        End if
        WScript.Echo("Done 2")

    End If

    End Sub

And a test batch:

@echo off
cscript "test.vbs"
ECHO %errorlevel%
PAUSE

The errorlevel output is 10 and not 1, although the script is quit as intended and the message "Done" is never shown.

Upvotes: 3

Views: 7541

Answers (1)

foxidrive
foxidrive

Reputation: 41234

Debugging technique:

Write a VBS script that just sets the errorlevel and quits - and get that working with your batch script.

Then you can massage your full vbs script.

Upvotes: 0

Related Questions