I recently needed a user-friendly approach and I came up with this, based on valuable insights from contributors here and elsewhere. Simply put this line at the top of your .bat script. Feedback welcome.
@pushd %~dp0 & fltmc | find "." && (powershell start '%~f0' ' %*' -verb runas 2>nul && exit /b)
Intrepretation:
@pushd %~dp0
ensures a consistant working directory relative to this batch file; supports UNC pathsfltmc
a native windows command that outputs an error if run unelevated| find "."
makes the error prettier, and causes nothing to output when elevated&& (
if we successfully got an error because we're not elevated, do this...powershell start
invoke PowerShell and call the Start-Process cmdlet (start is an alias)'%~f0'
pass in the full path and name of this .bat file. Single quotes allow spaces in the path/file name' %*'
pass in any and all arguments to this .bat file. Funky quoting and escape sequences probably won't work, but simple quoted strings should. The leading space is needed to prevent breaking things if no arguments are present-verb runas
don't just start this process...RunAs Administrator!2>nul
discard PowerShell's unsightly error output if the UAC prompt is canceled/ignored.&&
if we successfully invoked ourself with PowerShell, then...
&&
allows the .bat to continue running without elevation, such that any commands that require it will fail but others will work just fine. If you want the script to simply exit instead of running unelevated, make this a single ampersand: &
exit /b)
exits the initial .bat processing, because we don't need it anymore; we have a new elevated process currently running out .bat. Adding /b allows cmd.exe to remain open if the .bat was started from the command line...it has no effect if the .bat was double-clicked