I have to create a script which updates a system environment variable (based on a command line parameter) before launching a program.
In Windows 7, updating the system environment variable is denied. I would like to perform a privilege elevation for just the setting of the env. var. But run the program as a normal user.
How to do it?
Note:
I've tried the following solution:
Using 2 scripts:
1 master which get all information from command line, which call the slave script to change the system env. var., and which finally launch the program
1 slave script that update the system env. var.
the master script tries to call the slave script using privilege elevation, but that does not work
I've try 2 solutions for the privilage elevation:
Using the "runas /User:Administrator ..." command but it ask for the Administrator password: Fail
Using the "ShellExecute ...., "runas"" command but it tells me that my script is not an application: Fail
I found a way that is working at least on Windows 7 (don't know if it will work on the few Windows XP hat we still have around).
I did the following from the main script:
currentDirectory = left(WScript.ScriptFullName,(Len(WScript.ScriptFullName))-(len(WScript.ScriptName)))
Set UAC = WScript.CreateObject("Shell.Application")
UAC.ShellExecute "wscript.exe", currentDirectory + "my-script.vbs /Param1:Value1 ...", "", "runas", 0
And the my-script is doing the sys var env update.
Note: My fist experience with ShellExecute failed because I was trying to execute the script. Instead of "wscript.exe" I had "my-script.vbs" for the executable name.
IMHO, disable UAC, it's just a pain in the *
But if you can't (like me 8<), you can use
psexec.exe -d -u userid -p password CMD /c program_with_path
You (or the user where the sript runs) will have to confirm the prompt though.
Related
I am writing a Dockerfile on top of mcr.microsoft.com/windows/servercore which is supposed to run a script in administrator mode and then start CMD. The CMD shell should not be elevated. How do I achieve the same?
If I add USER ContainerAdministrator to my Dockerfile, the first script is run without any issues but the CMD shell is then elevated.
The other option might have been to use USER ContainerAdministrator and then spawn CMD with runas /user:ContainerUser, but runas needs password to be entered via a prompt (or using /savecred but that won't work here), so it's not possible either.
Thanks in advance!
Today I do e.g.:
Set WshShell = CreateObject("WScript.Shell")
Call WshShell.Run("psexec -u administrator -p pw1234 cmd /c netsh interface ip show address > C:\Output.txt", 2, True)
This works, but the command prompt window is always visible for a short time.
I've been searching the web and I've tried everything I could possibly think of to hide/minimize this window, but unfortunately without success.
So I'm afraid that there's no way to run psexec in a hidden/minimized window.
But is there perhaps another way to execute a privilege command in VBScript with a normal user where no command prompt window is visible?
Running tcl 8.4.13, I have a tcl script to execute my NSIS installation application (duly signed by microsoft) that used to work but now fails (windows 7 and 10), maybe because of windows security update or something? The same tcl script works fine when the target is a local/renamed copy of notepad.exe. The NSIS application works fine when run from from the command line.
The tcl script looks like the following, run via tclkit-win32 tclmnu.tcl, where tclmnu.tcl looks like this:
#! /bin/sh -x
# \
exec wish "$0" "$#"
#
package require Tk
#set runcmd notepad_local_copy.exe
set runcmd my_nsis_app.exe # this doesn't work
# this works with the notepad_local_copy.exe (above) but not my_nsis_app.exe
set catchcode [ catch { exec ${runcmd} } result ]
# also tried this, doesn't work either
#set catchcode [ catch { exec "runas /usr:administrator: ${runcmd}" } result ]
tk_messageBox -type ok -icon error -message "DEBUG: catchcode=${catchcode}"
# catchcode is 0 when runas=notepad_local_copy.exe, 1 when it's my_nsis_app.exe
Well, I solved it by adding cmd /c, as in
set catchcode [ catch { cmd /c exec ${runcmd} } result ]
I don't know why it needs that, nor why it seemed to work before and not now.
I don't know anything about TCL but I'm assuming that exec calls CreateProcess. When UAC was added to Vista it seems Microsoft deemed CreateProcess too low-level to be able to perform elevation.
Dealing with Administrator and standard user’s context:
CreateProcess and CreateProcessWithLogonW do not have new flags to launch the child process as elevated. Internally, CreateProcess() checks whether the target application requires elevation by looking for a manifest, determining if it is an installer, or if it has an app compat shim. If CreateProcess() determines the target application requires elevation, it simply fails with ERROR_ELEVATION_REQUIRED(740). It will not contact the AIS to perform the elevation prompt or run the app. If CreateProcess() determines the application doesn’t require elevation, it will spawn it as a new process.
ShellExecute[Ex] however is able to contact the UAC service and display the UAC elevation dialog:
To programmatically launch a child process as an elevated process, two things must occur: first, the executable of the child process needs to be identified as needing elevation, and second, the parent process needs to use ShellExecute() or ShellExecuteEx().
It seems there are multiple ways to get TCL to call ShellExecute:
eval exec [auto_execok start] {""} [list [file nativename $filename]] ;# http://wiki.tcl.tk/2809
or
twapi::shell_execute -path filename.exe ;# http://www.magicsplat.com/blog/how-do-i-exec-thee/
You can also request elevation of executables even if they are not marked as requiring elevation:
twapi::shell_execute -path filename.exe -verb runas
(The runas verb is not the same thing as runas.exe)
NSIS scripts use the RequestExecutionLevel attribute to mark the executable with the desired UAC elevation level.
Using cmd /c is a bit of a hack and will probably display a console window for a brief period of time. cmd /c first tries CreateProcess and then falls back to ShellExecuteEx if elevation was required. I'm not sure if this is documented behavior.
I have a batch file to start an application as a Windows service. It is called start.bat
#ECHO off
START c:\Ruby193\bin\ruby c:\Ruby193\bin\thin start -R c:\coolapp\config.ru -p 4321 -a localhost -e production
My challenge is that this program only runs properly if it is "Run as Administrator" with admin privileges. So, I would like to add a line to check if this script is actually run with administrative privileges, and only execute if it is being run as administrator.
How can I do that from within the script?
Something like this might be what you need:
set isadmin=0
whoami /all | findstr /c:" S-1-16-12288 ">nul && set isadmin=1
That should result in the %isadmin% variable being either 1 or 0 depending on whether the shell was run as administrator or not.
This assumes the existance of the whoami utility which won't necessarily be available on older versions of Windows - I believe it was included from Windows Vista onwards though.
Two options:
Provoke elevation from a WSH script, like documented in the blog post Scripting Elevation on Vista.
Use an external executable that provokes the UAC prompt, such as Elevate32.exe/Elevate64.exe.
For your scenario, #2 may be preferable because you can detect whether the elevation prompt was canceled (exit code 1223) and you can also wait for the launched executable to finish before continuing (-w parameter).
Bill
It would probably be easier to convert the script to VBScript, then you can more easily check for Admin privileges and even elevate the script to Admin.
See here for how to do the check in VBScript: VBScript: Check if the script has administrative permissions
I am logging into the server as Administrator to winserver2008.
I created a script called: vbscript.vbs
The purpose of this script is to auto login to linux via putty, then perform command line task.
Dim Shell
Set Shell = CreateObject("WScript.Shell")
output = Shell.Run("C:\putty.exe 1.2.3.4 9321")
wscript.sleep(500)
Shell.Sendkeys "root" & VBCrLf
wscript.sleep(30)
Shell.Sendkeys "password" & VBCrLf
wscript.sleep(30)
When I manually click on vbscript.vbs to execute it, vbscript will fill in root and password to putty.
When I use windows scheduler call to vbscript.vbs to execute it, vbscript won't fill in root and password to putty.
I suspect some permission issue.
I already set putty.exe to run as administrator, allow administrator, administrators group permission for it, but still fail to work when call via windows scheduler.
=====
I just tried with the second scenario, send 2 to the windows calculator, fail too..
testcalc.vbs
Set objShell = WScript.CreateObject("WScript.Shell")
objShell.Run "Calc.exe"
objShell.AppActivate "Calculator"
objShell.SendKeys "2"
Give up on trying to get SendKeys to work from a scheduled task, it's not going to happen. Instead simply pass the login and password on the command line:
output = Shell.Run("C:\putty.exe -l root -pw password 1.2.3.4 9321")
Alternatively do it with a session file and use -load.
If you are then going to execute commands over this connection then I believe you actually want plink rather than putty.