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
Related
I have a script which has to run from an administrator level powershell/cmd prompt
Why? Because it has to use logman to get windows counters
Problem: The software for which I want to log the windows counters for has to be started with regular user level rights.
I've seen that there are lots of examples on how to run as Administrator
I don't see any on running as Regular User
Launch exe file
Start Logman (Admin level)
Run Bat File to Open Program
Bat File should run with regular user level priv's
I had a look at using RUNAS but that requires password entry, which I don't want.
Is there some other way on windows to delevate?
you could use psexec
psexec -l powershell.exe -executionpolicy unrestricted -noexit -file c:\temp\checkelevated.ps1
-l : Run process as limited user (strips the Administrators group and allows only privileges assigned to the Users group). On Windows Vista the process runs with Low Integrity.
I'm writing a batch script, where I need to check if a specific process is run with admin privileges and I have trouble finding a proper command to do so. Tasklist command does not give me that information.
Is there any way to get info about privileges of given process (not cmd.exe, but any process) with a command (and possibly without 3rd party software)?
Edit:
I don't need to determine which account has launched the process, nor do I need to check if cmd.exe process is running with admin privileges. I need to check if a given process is running with admin privileges or not, because later i want to call program which needs to have the same privileges as a given process.
Admin is easily confirmed by calling a PowerShell script from a .bat file script. Place these two (2) files in the same directory. Running Confirm-Admin.bat will return True in the output and 1 as the ERRORLEVEL if the process is being run as admin. If not being run as admin, it will return False as the output and zero (0) as the ERRORLEVEL.
=== Confirm-Admin.ps1
function ExitWithCode($exitcode) {
$host.SetShouldExit($exitcode)
exit $exitcode
}
$currentPrincipal = New-Object Security.Principal.WindowsPrincipal([Security.Principal.WindowsIdentity]::GetCurrent())
if ($currentPrincipal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)) {
Write-Output "True"
ExitWithCode 1
} else {
Write-Output "False"
ExitWithCode 0
}
=== Confirm-Admin.bat
powershell -NoLogo -NoProfile -File "%~dp0%~n0.ps1"
To run Confirm-Admin.ps1 in PowerShell, invoke another Powershell to run it.
C:>powershell -NoLogo -NoProfile -File "Confirm-Admin.ps1"
True
PS 10:59 C:\src\t
C:>$LASTEXITCODE
1
If you only want to stay in the cmd.exe world, see https://stackoverflow.com/a/11995662/447901
Okay, so after some research and experimenting, I've managed to partially solve my problem.
Firstly, I check if batch script is running with admin privileges:
fsutil dirty query %SYSTEMDRIVE% >nul
if %errorLevel% == 0 (
set isBatchElevated=true
) else (
set isBatchElevated=false
)
Then, I look for a specific process by getting list of all tasks running by current user and finding a process by name:
tasklist /fi "username eq %USERDOMAIN%\%USERNAME%" | find /i "processname" > nul
if errorlevel 1 (
:: batch script doesn't have admin privileges, but the process has
)
So, there are four possible scenarios of running script and process with or without admin privileges.
1) Batch script without admin privileges, process with admin privileges
Running tasklist command won't find the given process with elevated rights and will set exit code to 1. Therefore, you can be 100% sure, that the process is running with elevated privileges, but only if batch script is running without admin privileges.
2) Batch script without admin privileges, process without admin privileges
Running tasklist command will find the given process. Basing on the 1) outcome, you can be 100% sure, that the process is running without elevated privileges, but only if batch script is running without admin privileges.
3)/4) Batch script with admin privileges, process with/without admin privileges
Those are problematic scenarios. When the script is running with elevated privileges, then the given process will be found, but there would be no difference between process with and without elevated rights when running tasklist.
After the privileges check I need to run a program with the same rights as the given process. The difference in the privileges will cause an error and the given won't be running without admin privileges only, so running the batch script without admin rights only won't solve the issue.
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 was trying to test a simple powershell script with task scheduler, the status showed running but the powershell console never showed up.
My ps1 script just contains two simple commands:
dir
pause
Here is my setup:
General
Run whether user is logged on or not (check)
Run with highest privileges (check)
Actions
Action: Start a program
Program/Script: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
Add arguments (optional): -file E:\iQ_Schedule\Untitled1.ps1
This setup works on other computer (Windows 10) but just won't on this one (Windows Server 2012 R2). I am not sure why.
Welcome to Session 0 isolation mode.
When you run your task with "Run whether user logged in or not", it runs in so called session 0. You can check this with your task manager.
Tasks running is Session 0 has restrictions on showing the user interface
This could be due to the user account which is running the script. When the script is running with the SYSTEM account, the script will run in the background.
Try to change the option 'When running the task, use the following user account' to the account you are currently logged on with. Then the PowerShell console should pop up.
It sounds like the Windows Server 2012 R2 could have PSversion 2. The Pause function doesn't exist until PSversion 3.
Could you give the value of this command to us?
$PSVersionTable.PSVersion
Run whether user is logged on or not, will still give you the prompt. If the Hidden option is checked, you will not see the prompt.
I have also seen that the user that is trying to run the PowerShell script inside Task Scheduler doesn't have access to the folder strucutre. Make sure the user that is running the Task Scheduler has access to E:\iQ_Schedule\.
Make sure the user that is running the task scheduler has read access to the file structure you are trying to look up.
You can run as SYSTEM user, but then use the executionpolicy bypass argument
Powershell -ep Bypass 'e:\myPSFile.ps1' -myArg1 'arg1' -myArg2 'arg2'
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.