Can anyone help me with running vbs from itself but with administrator rights?
I need rename computer with Windows 8 via VBScript, but it's possible only if I run my script through administrator command line (CMD → Run as Administrator → runScript.vbs). If I start script with classic CMD the computer isn't renamed.
My idea is I start script with user rights, without parameters and if there is no parameter, the script re-runs itself with admin rights and with parameter as identificator "I'm admin".
Does anyone know how I can do this?
Edit:
I tried this:
If WScript.Arguments.Count = 0 Then
Set objShell = CreateObject("Shell.Application")
objShell.ShellExecute "wscript.exe", "c:\Users\admin\Documents\selfConfigure.vbs -1", "", runas", 1
End If
If UAC is enabled on the computer, something like this should work:
If Not WScript.Arguments.Named.Exists("elevate") Then
CreateObject("Shell.Application").ShellExecute WScript.FullName _
, """" & WScript.ScriptFullName & """ /elevate", "", "runas", 1
WScript.Quit
End If
'actual code
Add this to the beginning of your file:
Set WshShell = WScript.CreateObject("WScript.Shell")
If WScript.Arguments.Length = 0 Then
Set ObjShell = CreateObject("Shell.Application")
ObjShell.ShellExecute "wscript.exe" _
, """" & WScript.ScriptFullName & """ RunAsAdministrator", , "runas", 1
WScript.Quit
End if
fun lil batch file
#set E=ECHO &set S=SET &set CS=CScript //T:3 //nologo %~n0.vbs /REALTIME^>nul^& timeout 1 /NOBREAK^>nul^& del /Q %~n0.vbs&CLS
#%E%off&color 4a&title %~n0&%S%CX=CLS^&EXIT&%S%BS=^>%~n0.vbs&%S%G=GOTO &%S%H=shell&AT>NUL
IF %ERRORLEVEL% EQU 0 (
%G%2
) ELSE (
if not "%minimized%"=="" %G%1
)
%S%minimized=true & start /min cmd /C "%~dpnx0"&%CX%
:1
%E%%S%%H%=CreateObject("%H%.Application"):%H%.%H%Execute "%~dpnx0",,"%CD%", "runas", 1:%S%%H%=nothing%BS%&%CS%&%CX%
:2
%E%%~dpnx0 fvcLing admin mode look up&wmic process where name="cmd.exe" CALL setpriority "realtime"& timeout 3 /NOBREAK>nul
:3
%E%x=msgbox("end of line" ,48, "%~n0")%BS%&%CS%&%CX%
Nice article for elevation options - http://www.novell.com/support/kb/doc.php?id=7010269
Configuring Applications to Always Request Elevated Rights:
Programs can be configured to always request elevation on the user level via registry settings under HKCU. These registry settings are effective on the fly, so they can be set immediately prior to launching a particular application and even removed as soon as the application is launched, if so desired. Simply create a "String Value" under "HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" for the full path to an executable with a value of "RUN AS ADMIN". Below is an example for CMD.
Windows Registry Editor Version 5.00
[HKEY_Current_User\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers]
"c:\\windows\\system32\\cmd.exe"="RUNASADMIN"
`My vbs file path :
D:\QTP Practice\Driver\Testany.vbs'
objShell = CreateObject("Shell.Application")
objShell.ShellExecute "cmd.exe","/k echo test", "", "runas", 1
set x=createobject("wscript.shell")
wscript.sleep(2000)
x.sendkeys "CD\"&"{ENTER}"&"cd D:"&"{ENTER}"&"cd "&"QTP Practice\Driver"&"{ENTER}"&"Testany.vbs"&"{ENTER}"
--from google search and some tuning, working for me
This is the universal and best solution for this:
If WScript.Arguments.Count <> 1 Then WScript.Quit 1
RunAsAdmin
Main
Sub RunAsAdmin()
Set Shell = CreateObject("WScript.Shell")
Set Env = Shell.Environment("VOLATILE")
If Shell.Run("%ComSpec% /C ""NET FILE""", 0, True) <> 0 Then
Env("CurrentDirectory") = Shell.CurrentDirectory
ArgsList = ""
For i = 1 To WScript.Arguments.Count
ArgsList = ArgsList & """ """ & WScript.Arguments(i - 1)
Next
CreateObject("Shell.Application").ShellExecute WScript.FullName, """" & WScript.ScriptFullName & ArgsList & """", , "runas", 5
WScript.Sleep 100
Env.Remove("CurrentDirectory")
WScript.Quit
End If
If Env("CurrentDirectory") <> "" Then Shell.CurrentDirectory = Env("CurrentDirectory")
End Sub
Sub Main()
'Your code here!
End Sub
Advantages:
1) The parameter injection is not possible.
2) The number of arguments does not change after the elevation to administrator and then you can check them before you elevate yourself.
3) You know for real and immediately if the script runs as an administrator. For example, if you call it from a control panel uninstallation entry, the RunAsAdmin function will not run unnecessarily because in that case you are already an administrator. Same thing if you call it from a script already elevated to administrator.
4) The window is kept at its current size and position, as it should be.
5) The current directory doesn't change after obtained administrative privileges.
Disadvantages: Nobody
Related
This question already has an answer here:
Prevent VBscript app from showing Console Window
(1 answer)
Closed 1 year ago.
Hey guys im trying to start a programm hidden with less priority but the command prompt still pop out.
Dim WShell
Set WShell = CreateObject("WScript.Shell")
WShell.Run "cmd /c Start /belowNormal " & "C:\Users\Desktop\sonso.exe -uri www.google.de",0
Set WShell = Nothing
You asked how to reduce exe priority from VBS without using CMD so here is an example.
(I admit it is not all my own work, but performs as advertised for Notepad.exe)
Don't ask me exactly how it works and it took me ages to find as the vbs example is "missing" from the Microsoft setpriority-method-in-class-win32-process link I include.
Set Priority.vbs
' Set priority of process to Below Normal on Server 2008 & Vista+'
' From https://learn.microsoft.com/en-gb/windows/win32/cimwin32prov/setpriority-method-in-class-win32-process'
' Below Normal (16384) Indicates a process that has priority above IDLE_PRIORITY_CLASS (64),'
' but below NORMAL_PRIORITY_CLASS (32). NOTE:- combined namespace is \\. \Root\CIMV2
' Others ABOVE_NORMAL (32768) HIGH_PRIORITY (128) *REAL_TIME ( 256) *Note To set Realtime,
' the caller must have SeIncreaseBasePriorityPrivilege (SE_INC_BASE_PRIORITY_PRIVILEGE).
' Without this privilege, the highest the priority can be set to is High Priority.
' Use your RUN commands here and replace name = Notepad.exe below or replace Notepad.exe with arg[0]
Set objShell = WScript.CreateObject("WScript.Shell")
' With CMD but minimised so we can open it from taskbar
' objShell.Run "%comspec% /d /c start /min Notepad.exe fred.txt", 0, True
' Without CMD BUT NOT hidden, otherwise how are you going to edit anything or close Notepad.
objShell.Run "c:\windows\Notepad.exe fred.txt"
strComputer = "."
Set objWMIService = GetObject("winmgmts:" _
& "{impersonationLevel=impersonate}!\\" & strComputer & "\Root\CIMV2")
Set colProcesses = objWMIService.ExecQuery _
("Select * from Win32_Process Where Name = 'Notepad.exe'")
For Each objProcess in colProcesses
objProcess.SetPriority(16384)
Next
i have made a simple VBScript file that enables Task Manager.
but when i execute it , i get error "Invalid Root In Registry Key"
why?
set Shell=CreateObject("Wscript.Shell")
shell.regwrite "HKCU\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\Microsoft\Windows\System\DisableTaskMgr","0","REG_DWORD"
Add this to your code below WScript.Shell:
RunAsAdmin()
Function RunAsAdmin()
If WScript.Arguments.length = 0 Then
CreateObject("Shell.Application").ShellExecute "wscript.exe", """" & _
WScript.ScriptFullName & """" & " RunAsAdministrator",,"runas", 1
WScript.Quit
End If
End Function
This will run the script as admin. If it does not work then check your registry path because it is probably incorrect.
Can anyone help me with running vbs from itself but with administrator rights?
I need rename computer with Windows 8 via VBScript, but it's possible only if I run my script through administrator command line (CMD → Run as Administrator → runScript.vbs). If I start script with classic CMD the computer isn't renamed.
My idea is I start script with user rights, without parameters and if there is no parameter, the script re-runs itself with admin rights and with parameter as identificator "I'm admin".
Does anyone know how I can do this?
Edit:
I tried this:
If WScript.Arguments.Count = 0 Then
Set objShell = CreateObject("Shell.Application")
objShell.ShellExecute "wscript.exe", "c:\Users\admin\Documents\selfConfigure.vbs -1", "", runas", 1
End If
If UAC is enabled on the computer, something like this should work:
If Not WScript.Arguments.Named.Exists("elevate") Then
CreateObject("Shell.Application").ShellExecute WScript.FullName _
, """" & WScript.ScriptFullName & """ /elevate", "", "runas", 1
WScript.Quit
End If
'actual code
Add this to the beginning of your file:
Set WshShell = WScript.CreateObject("WScript.Shell")
If WScript.Arguments.Length = 0 Then
Set ObjShell = CreateObject("Shell.Application")
ObjShell.ShellExecute "wscript.exe" _
, """" & WScript.ScriptFullName & """ RunAsAdministrator", , "runas", 1
WScript.Quit
End if
fun lil batch file
#set E=ECHO &set S=SET &set CS=CScript //T:3 //nologo %~n0.vbs /REALTIME^>nul^& timeout 1 /NOBREAK^>nul^& del /Q %~n0.vbs&CLS
#%E%off&color 4a&title %~n0&%S%CX=CLS^&EXIT&%S%BS=^>%~n0.vbs&%S%G=GOTO &%S%H=shell&AT>NUL
IF %ERRORLEVEL% EQU 0 (
%G%2
) ELSE (
if not "%minimized%"=="" %G%1
)
%S%minimized=true & start /min cmd /C "%~dpnx0"&%CX%
:1
%E%%S%%H%=CreateObject("%H%.Application"):%H%.%H%Execute "%~dpnx0",,"%CD%", "runas", 1:%S%%H%=nothing%BS%&%CS%&%CX%
:2
%E%%~dpnx0 fvcLing admin mode look up&wmic process where name="cmd.exe" CALL setpriority "realtime"& timeout 3 /NOBREAK>nul
:3
%E%x=msgbox("end of line" ,48, "%~n0")%BS%&%CS%&%CX%
Nice article for elevation options - http://www.novell.com/support/kb/doc.php?id=7010269
Configuring Applications to Always Request Elevated Rights:
Programs can be configured to always request elevation on the user level via registry settings under HKCU. These registry settings are effective on the fly, so they can be set immediately prior to launching a particular application and even removed as soon as the application is launched, if so desired. Simply create a "String Value" under "HKCU\Software\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers" for the full path to an executable with a value of "RUN AS ADMIN". Below is an example for CMD.
Windows Registry Editor Version 5.00
[HKEY_Current_User\SOFTWARE\Microsoft\Windows NT\CurrentVersion\AppCompatFlags\Layers]
"c:\\windows\\system32\\cmd.exe"="RUNASADMIN"
`My vbs file path :
D:\QTP Practice\Driver\Testany.vbs'
objShell = CreateObject("Shell.Application")
objShell.ShellExecute "cmd.exe","/k echo test", "", "runas", 1
set x=createobject("wscript.shell")
wscript.sleep(2000)
x.sendkeys "CD\"&"{ENTER}"&"cd D:"&"{ENTER}"&"cd "&"QTP Practice\Driver"&"{ENTER}"&"Testany.vbs"&"{ENTER}"
--from google search and some tuning, working for me
This is the universal and best solution for this:
If WScript.Arguments.Count <> 1 Then WScript.Quit 1
RunAsAdmin
Main
Sub RunAsAdmin()
Set Shell = CreateObject("WScript.Shell")
Set Env = Shell.Environment("VOLATILE")
If Shell.Run("%ComSpec% /C ""NET FILE""", 0, True) <> 0 Then
Env("CurrentDirectory") = Shell.CurrentDirectory
ArgsList = ""
For i = 1 To WScript.Arguments.Count
ArgsList = ArgsList & """ """ & WScript.Arguments(i - 1)
Next
CreateObject("Shell.Application").ShellExecute WScript.FullName, """" & WScript.ScriptFullName & ArgsList & """", , "runas", 5
WScript.Sleep 100
Env.Remove("CurrentDirectory")
WScript.Quit
End If
If Env("CurrentDirectory") <> "" Then Shell.CurrentDirectory = Env("CurrentDirectory")
End Sub
Sub Main()
'Your code here!
End Sub
Advantages:
1) The parameter injection is not possible.
2) The number of arguments does not change after the elevation to administrator and then you can check them before you elevate yourself.
3) You know for real and immediately if the script runs as an administrator. For example, if you call it from a control panel uninstallation entry, the RunAsAdmin function will not run unnecessarily because in that case you are already an administrator. Same thing if you call it from a script already elevated to administrator.
4) The window is kept at its current size and position, as it should be.
5) The current directory doesn't change after obtained administrative privileges.
Disadvantages: Nobody
Ok, I have an error someplace in here, but not sure where. I am NOT a coder by any means, this is something I have put together from a couple of different sources. This code works, however it seems to run once as a normal user and once at elevated permissions... I just need it to run just once at elevated permissions.
Set WshShell = WScript.CreateObject("WScript.Shell")
If WScript.Arguments.length = 0 Then
Set ObjShell = CreateObject("Shell.Application")
ObjShell.ShellExecute "wscript.exe", """" & _
WScript.ScriptFullName & """" &_
" RunAsAdministrator", , "runas", 1
End if
On Error Resume Next
Dim System
if Wscript.Arguments.Count >0 then
sSystem=Wscript.Arguments(0)
end if
ComputerName = InputBox("Enter the name of the computer you wish to query")
winmgmt1 = "winmgmts:{impersonationLevel=impersonate}!//"& ComputerName &""
Set SNSet = GetObject( winmgmt1 ).InstancesOf ("Win32_BIOS")
for each SN in SNSet
MsgBox "The serial number for the specified computer is: " & SN.SerialNumber
next
This is the part that re-runs your script with elevated privileges by using the Shell.ShellExecute method with the "runas" verb:
If WScript.Arguments.length = 0 Then
Set ObjShell = CreateObject("Shell.Application")
ObjShell.ShellExecute "wscript.exe", """" & _
WScript.ScriptFullName & """" &_
" RunAsAdministrator", , "runas", 1
End if
Re-running the script with the additional parameter RunAsAdministrator makes sure that the re-run script skips the above part (since WScript.Arguments.Length is greater than 0 due to that parameter) and goes directly to the "worker" code.
However, the above code snippet doesn't exit after re-running the script, so both the elevated and the original invocation are executing the worker code.
Add a WScript.Quit statement to your code to make the original invocation exit right after re-running itself with elevated permissions and the issue will disappear:
If WScript.Arguments.Length = 0 Then
Set ObjShell = CreateObject("Shell.Application")
ObjShell.ShellExecute "wscript.exe", _
"""" & WScript.ScriptFullName & """ RunAsAdministrator", , "runas", 1
WScript.Quit 0
End If
that's all (for remote computer):
ComputerName = InputBox("Enter the name of the computer you wish to query")
winmgmt1 = "winmgmts:(impersonationLevel=impersonate}!//"& ComputerName &"\root\cimv2")
Set SNSet = winmgmt1.ExecQuery("Select * from Win32_BIOS")
for each SN in SNSet
MsgBox "The serial number for the specified computer is: " & SN.SerialNumber
next
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.
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.