Cara meminta akses Administrator di dalam file batch

179

Saya mencoba menulis file batch untuk dijalankan oleh pengguna dari mesin Vista mereka dengan UAC. File ini sedang menulis ulang file host mereka, sehingga harus dijalankan dengan izin Administrator. Saya harus dapat mengirim email kepada mereka dengan tautan ke file .bat. Perilaku yang diinginkan adalah ketika mereka mengklik kanan pada file dan mengatakan Open, mereka akan mendapatkan salah satu dialog UAC yang membuat layar menjadi gelap dan memaksa mereka untuk menjawab apakah mereka ingin memberikan izin aplikasi untuk dijalankan sebagai administrator. Sebaliknya, mereka hanya melihat "Akses ditolak" di jendela baris perintah.

Apakah ini mungkin dilakukan secara berbeda?

skb
sumber
2
Jika Anda menemukan ini dan, seperti saya, senang menggunakan PowerShell, jangan lewatkan one-liner dari @ toster-cx. Sempurna!
Michael Repucci

Jawaban:

352

Script ini berhasil! Cukup rekatkan ke bagian atas file bat Anda. Jika Anda ingin meninjau output skrip Anda, tambahkan perintah "jeda" di bagian bawah file batch Anda.

PEMBARUAN: Skrip ini sekarang sedikit diedit untuk mendukung argumen baris perintah dan OS 64 bit.

Eneerge @ https://sites.google.com/site/eneerge/scripts/batchgotadmin

@echo off

:: BatchGotAdmin
:-------------------------------------
REM  --> Check for permissions
    IF "%PROCESSOR_ARCHITECTURE%" EQU "amd64" (
>nul 2>&1 "%SYSTEMROOT%\SysWOW64\cacls.exe" "%SYSTEMROOT%\SysWOW64\config\system"
) ELSE (
>nul 2>&1 "%SYSTEMROOT%\system32\cacls.exe" "%SYSTEMROOT%\system32\config\system"
)

REM --> If error flag set, we do not have admin.
if '%errorlevel%' NEQ '0' (
    echo Requesting administrative privileges...
    goto UACPrompt
) else ( goto gotAdmin )

:UACPrompt
    echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
    set params= %*
    echo UAC.ShellExecute "cmd.exe", "/c ""%~s0"" %params:"=""%", "", "runas", 1 >> "%temp%\getadmin.vbs"

    "%temp%\getadmin.vbs"
    del "%temp%\getadmin.vbs"
    exit /B

:gotAdmin
    pushd "%CD%"
    CD /D "%~dp0"
:--------------------------------------    
    <YOUR BATCH SCRIPT HERE>
Ben Gripka
sumber
22
Aku benci harus melakukan ini omong kosong dos batch omong kosong tetapi kadang-kadang Anda dipaksa dan ini bekerja hebat. Bersulang!
Matt burns
4
Metode ini tidak meneruskan argumen. Apakah Anda tahu bagaimana itu bisa dilakukan? Pada dasarnya yang saya amati adalah bahwa pada baris pertama% 1 memiliki beberapa nilai dan pada baris terakhir% 1 adalah nol. Saya perlu meneruskan argumen.
Cabang
3
Sama seperti FYI ini diuji bekerja di Windows 8 Embedded
Robert Snyder
6
Ini melempar mesin saya ke dalam spiral jendela perintah membuka dan menutup secara diagonal di layar. Satu-satunya cara untuk menghentikannya adalah dengan menghapus file batch asli. Ini berulang kali menjalankan file batch saya dan menulis file vbs. Pertama kali meminta otorisasi, tetapi setelah itu hanya loop.
TomDestry
2
Saya mengalami masalah yang sama persis seperti TomDestry dengan infinite loop dan mengembalikan kode 2. Ini ada di Windows 8.1. Saya tahu itu bekerja pada Windows 8.0, dan tidak bisa mengatakan dengan pasti apakah itu pembaruan 8.1 atau sesuatu yang menyebabkan penerbitan. Solusi yang berhasil bagi saya adalah tidak menggunakan cacls.exe (atau icacls), melainkan: sesi bersih> nul 2> & 1 JIKA ERRORLEVEL 1 goto UACPrompt ...
crig
55

Ini adalah one-liner yang telah saya gunakan:

@echo off
if not "%1"=="am_admin" (powershell start -verb runas '%0' am_admin & exit /b)

echo main code here
pause

Catatan:

  • Hanya diuji pada windows 7 dan 10, Anda mungkin harus dipusingkan dengan penawaran
  • Tidak mendukung menyampaikan argumen untuk saat ini
toster-cx
sumber
1
Jika Anda tahu berapa banyak params yang ada, Anda dapat melewati parameter dengan memasukkannya setelah am_admin if not "%1"=="am_admin" (powershell start -verb runas '%0' 'am_admin "%~1" "%~2"' & exit)Params akan menjadi satu di atas di mana mereka berada
Tony Brix
Juga mungkin digunakan 'am_admin %*'untuk melewatkan semuanya, tidak bermain dengan baik dengan tanda kutip dan spasi tho: / Anda dapat menggunakan shiftdalam batch untuk memunculkan argumen pertama, sehingga memperbaiki semua argumen kecuali %0.
toster-cx
Ini adalah jawaban yang baik, tetapi tidak boleh diterima, karena ia TIDAK memeriksa apakah pada saat PERTAMA dijalankan dengan ADMIN privilege atau tidak.
T.Todua
Untuk menjaga direktori yang berfungsi tambahkan cd /D %~dp0setelahif not "%1"=="am_admin" (powershell start -verb runas '%0' am_admin & exit /b)
Pedro Duarte
Jawaban yang bagus. Cukup berfungsi saat skrip VB membuat loop tak terbatas, bahkan dengan izin tulis untuk% temp%.
Twonky
19

Ini kode saya! Ini terlihat besar tetapi sebagian besar baris komentar (baris dimulai dengan: :).

Fitur:

  • Penerusan argumen penuh
  • Tidak mengubah folder yang berfungsi
  • Menangani kesalahan
  • Menerima jalur dengan tanda kurung (kecuali untuk map% TEMP%)
  • Mendukung jalur UNC
  • Pemeriksaan folder yang dipetakan (Peringatkan Anda jika admin tidak dapat mengakses drive yang dipetakan)

  • Dapat digunakan sebagai perpustakaan eksternal (periksa posting saya di topik ini: https://stackoverflow.com/a/30417025/4932683 )

  • Dapat dipanggil kapan / jika dibutuhkan di mana saja dalam kode Anda

Cukup lampirkan ini di akhir file batch Anda, atau simpan sebagai perpustakaan (centang di atas)

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
:RequestAdminElevation FilePath %* || goto:eof
:: 
:: By:   Cyberponk,     v1.5 - 10/06/2016 - Changed the admin rights test method from cacls to fltmc
::          v1.4 - 17/05/2016 - Added instructions for arguments with ! char
::          v1.3 - 01/08/2015 - Fixed not returning to original folder after elevation successful
::          v1.2 - 30/07/2015 - Added error message when running from mapped drive
::          v1.1 - 01/06/2015
:: 
:: Func: opens an admin elevation prompt. If elevated, runs everything after the function call, with elevated rights.
:: Returns: -1 if elevation was requested
::           0 if elevation was successful
::           1 if an error occured
:: 
:: USAGE:
:: If function is copied to a batch file:
::     call :RequestAdminElevation "%~dpf0" %* || goto:eof
::
:: If called as an external library (from a separate batch file):
::     set "_DeleteOnExit=0" on Options
::     (call :RequestAdminElevation "%~dpf0" %* || goto:eof) && CD /D %CD%
::
:: If called from inside another CALL, you must set "_ThisFile=%~dpf0" at the beginning of the file
::     call :RequestAdminElevation "%_ThisFile%" %* || goto:eof
::
:: If you need to use the ! char in the arguments, the calling must be done like this, and afterwards you must use %args% to get the correct arguments:
::      set "args=%* "
::      call :RequestAdminElevation .....   use one of the above but replace the %* with %args:!={a)%
::      set "args=%args:{a)=!%" 
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
setlocal ENABLEDELAYEDEXPANSION & set "_FilePath=%~1"
  if NOT EXIST "!_FilePath!" (echo/Read RequestAdminElevation usage information)
  :: UAC.ShellExecute only works with 8.3 filename, so use %~s1
  set "_FN=_%~ns1" & echo/%TEMP%| findstr /C:"(" >nul && (echo/ERROR: %%TEMP%% path can not contain parenthesis &pause &endlocal &fc;: 2>nul & goto:eof)
  :: Remove parenthesis from the temp filename
  set _FN=%_FN:(=%
  set _vbspath="%temp:~%\%_FN:)=%.vbs" & set "_batpath=%temp:~%\%_FN:)=%.bat"

  :: Test if we gave admin rights
  fltmc >nul 2>&1 || goto :_getElevation

  :: Elevation successful
  (if exist %_vbspath% ( del %_vbspath% )) & (if exist %_batpath% ( del %_batpath% )) 
  :: Set ERRORLEVEL 0, set original folder and exit
  endlocal & CD /D "%~dp1" & ver >nul & goto:eof

  :_getElevation
  echo/Requesting elevation...
  :: Try to create %_vbspath% file. If failed, exit with ERRORLEVEL 1
  echo/Set UAC = CreateObject^("Shell.Application"^) > %_vbspath% || (echo/&echo/Unable to create %_vbspath% & endlocal &md; 2>nul &goto:eof) 
  echo/UAC.ShellExecute "%_batpath%", "", "", "runas", 1 >> %_vbspath% & echo/wscript.Quit(1)>> %_vbspath%
  :: Try to create %_batpath% file. If failed, exit with ERRORLEVEL 1
  echo/@%* > "%_batpath%" || (echo/&echo/Unable to create %_batpath% & endlocal &md; 2>nul &goto:eof)
  echo/@if %%errorlevel%%==9009 (echo/^&echo/Admin user could not read the batch file. If running from a mapped drive or UNC path, check if Admin user can read it.)^&echo/^& @if %%errorlevel%% NEQ 0 pause >> "%_batpath%"

  :: Run %_vbspath%, that calls %_batpath%, that calls the original file
  %_vbspath% && (echo/&echo/Failed to run VBscript %_vbspath% &endlocal &md; 2>nul & goto:eof)

  :: Vbscript has been run, exit with ERRORLEVEL -1
  echo/&echo/Elevation was requested on a new CMD window &endlocal &fc;: 2>nul & goto:eof
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Contoh tentang cara menggunakannya

:EXAMPLE
@echo off

 :: Run this script with elevation
 call :RequestAdminElevation "%~dpfs0" %* || goto:eof

  echo/I now have Admin rights!
  echo/
  echo/Arguments using %%args%%:    %args%
  echo/Arguments using %%*: %*
  echo/%%1= %~1
  echo/%%2= %~2
  echo/%%3= %~3

  echo/
  echo/Current Directory: %CD%
  echo/
  echo/This file: %0
  echo/

pause &goto:eof

[here you paste the RequestAdminElevation function code]
cyberponk
sumber
Bekerja dengan baik tetapi saya harus mengubah jalur untuk membuatnya bekerja. The &fc;: 2>nuldi set "_FN=_%~ns1" & echo/%TEMP%| findstr /C:"(" >nul && (echo/ERROR: %%TEMP%% path can not contain parenthesis &pause &endlocal &fc;: 2>nul & goto:eof)terbenam errorlevel untuk 1. saya dihapus sedikit itu dan itu bekerja sempurna. Saya menggunakan Windows 10 Home.
Knyri
Apakah folder% temp% Anda memiliki tanda kurung di jalurnya? Hanya dalam kasus ini tingkat kesalahan 1 seharusnya diatur.
cyberponk
Nggak. Apakah perlu fc;:sejak itu berlalu: setelah tepat? Saya juga tidak yakin mengapa hal itu menyebabkan masalah, karena itu harus dieksekusi.
Knyri
"fc ;: 2> nul" ada di sana dengan sengaja mengatur ERRORLEVEL 1 sebelum keluar, untuk memberi sinyal kesalahan. Bisakah Anda menghapus @echo off dan menjalankan dan mengirim saya output dalam pesan pribadi? Terima kasih!
cyberponk
Lagi pula, echo/%TEMP%| findstr /C:"(" >nultes jika ada variabel lingkungan (char Anda %temp%, dan hanya akan menjalankan bagian setelah &&jika positif. Aneh mengapa (tes Anda kembali positif.
cyberponk
7

Pendekatan lain adalah dengan

  • buat pintasan secara lokal dan atur untuk meminta izin Admin [Properti, Lanjut, Jalankan sebagai Admin]

lalu

  • kirim pengguna Anda pintasan [atau tautan ke pintasan daripada satu ke file kumpulan itu sendiri].

Denis

[Ditambahkan setelah itu - Ya, saya tidak memperhatikan tanggal utas ini.]

Tryx3
sumber
6

Solusi Ben Gripka menyebabkan loop tak terbatas. Batch-nya berfungsi seperti ini (kode semu):

IF "no admin privileges?"
    "write a VBS that calls this batch with admin privileges"
ELSE
    "execute actual commands that require admin privileges"

Seperti yang Anda lihat, ini menyebabkan loop tak terbatas, jika VBS gagal meminta hak admin.

Namun, loop tak terbatas dapat terjadi, meskipun hak admin telah berhasil diminta.

Pemeriksaan dalam file kumpulan Ben Gripka hanya rawan kesalahan. Saya bermain-main dengan batch dan mengamati bahwa hak istimewa admin tersedia meskipun cek gagal. Menariknya, cek berfungsi seperti yang diharapkan, jika saya memulai file batch dari windows explorer, tetapi tidak ketika saya mulai dari IDE.

Jadi saya sarankan untuk menggunakan dua file batch terpisah. Yang pertama menghasilkan VBS yang memanggil file batch kedua:

@echo off

echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\getadmin.vbs"
set params = %*:"=""
echo UAC.ShellExecute "cmd.exe", "/c ""%~dp0\my_commands.bat"" %params%", "", "runas", 1 >> "%temp%\getadmin.vbs"

"%temp%\getadmin.vbs"
del "%temp%\getadmin.vbs"

Yang kedua, bernama "my_commands.bat" dan terletak di direktori yang sama dengan yang pertama berisi perintah Anda yang sebenarnya:

pushd "%CD%"
CD /D "%~dp0"
REM Your commands which require admin privileges here

Ini tidak menyebabkan loop tak terbatas dan juga menghapus pemeriksaan hak admin rawan kesalahan.

tulang ikan
sumber
Bekerja untukmu? Sedih bagi saya, ini dan semua yang lain di sini dan dari utas lainnya gagal karena masalah mendasar yang sama. Parm "runas" (atau perintah) gagal setiap kali Obyek Shell dibuat secara tidak langsung dari dalam program lain. Utas menarik di sini .
Laurie Stearn
Bekerja untuk saya :)
Sritam Jagadev
6

Solusi PowerShell Lain ...

Ini bukan tentang menjalankan skrip batch sebagai admin per, tetapi bagaimana meningkatkan program lain dari batch ...

Saya memiliki file batch "pembungkus" untuk exe. Mereka memiliki "nama file root" yang sama, tetapi ekstensi alternatif. Saya dapat meluncurkan exe sebagai admin, dan mengatur direktori kerja ke yang berisi skrip, dengan satu baris berikut memohon doa:

@powershell "Start-Process -FilePath '%~n0.exe' -WorkingDirectory '%~dp0' -Verb RunAs"

Info lebih lanjut

Ada banyak Start-Processpilihan tambahan yang bisa Anda terapkan! Lihat: https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.management/start-process?view=powershell-6

Perhatikan bahwa saya menggunakan @awalan. Itu setara dengan @echo offuntuk satu baris. Saya menggunakan di %~n0sini untuk mendapatkan "nama root" dari skrip batch, kemudian saya menyatukannya .exeuntuk menunjukkannya biner yang berdekatan. Penggunaan %~dp0menyediakan path lengkap ke direktori tempat batch. Dan, tentu saja, yang -Verb RunAsparameter menyediakan elevasi .

Terima kasih
sumber
4

Saya tahu ini bukan solusi untuk OP, tetapi karena saya yakin ada banyak kasus penggunaan lain di sini, saya pikir saya akan berbagi.

Saya mengalami masalah dengan semua contoh kode dalam jawaban ini, tetapi kemudian saya menemukan: http://www.robotronic.de/runasspcEn.html

Itu tidak hanya memungkinkan Anda untuk menjalankan sebagai admin, itu memeriksa file untuk memastikan itu belum dirusak dan menyimpan informasi yang dibutuhkan dengan aman. Saya akui itu bukan alat yang paling jelas untuk mengetahui cara menggunakan tetapi bagi kita yang menulis kode itu harus cukup sederhana.

trex005
sumber
3

@echo offdan titledapat muncul sebelum kode ini:

net session>nul 2>&1
if %errorlevel%==0 goto main
echo CreateObject("Shell.Application").ShellExecute "%~f0", "", "", "runas">"%temp%/elevate.vbs"
"%temp%/elevate.vbs"
del "%temp%/elevate.vbs"
exit

:main
    <code goes here>
exit

Banyak jawaban lain yang berlebihan jika Anda tidak perlu khawatir tentang yang berikut:

  • Parameter
  • Direktori Kerja ( cd %~dp0akan berubah menjadi direktori yang berisi file batch)
FluorescentGreen5
sumber
3
@echo off 
Net session >nul 2>&1 || (PowerShell start -verb runas '%~0' &exit /b)
Echo Administrative privileges have been got. & pause

Di atas berfungsi pada Windows 10 Version 1903 saya

Matthew Wai
sumber
1

Karena saya memiliki masalah dengan skrip ini muncul prompt perintah baru dengan sendirinya berjalan lagi, dalam loop tak terbatas (menggunakan Win 7 Pro), saya sarankan Anda mencoba pendekatan lain: Bagaimana saya dapat secara otomatis meningkatkan file batch saya, sehingga permintaan dari Hak administrator UAC jika diperlukan?

Hati-hati, Anda harus menambahkan ini di akhir skrip, sebagaimana dinyatakan dalam edit, sehingga Anda kembali ke direktori skrip setelah hak istimewa ditingkatkan: cd / d% ~ dp0

barbara.post
sumber
Periksa jawaban saya untuk pertanyaan ini. Ini menangani semua masalah ini.
cyberponk
1

Berdasarkan posting oleh toster-cx dan posting menarik lainnya di halaman ini, saya mendapat wawasan tentang cara mengkonfigurasi dan menyelesaikan masalah saya. Saya memiliki masalah serupa di mana saya berharap utilitas Disk Cleanup berjalan setiap minggu dua kali pada hari Senin dan Kamis selama jam makan siang (misalnya jam 14:00). Namun, ini membutuhkan hak yang lebih tinggi.

Berbagi file batch yang mungkin membantu pemula lain seperti saya -

@echo off
echo  Welcome to scheduling 'PC Maintenance Activity'
ping localhost -n 3 >nul
echo -- Step - 1 of 3 : Please give 'Admin' rights on next screen
ping localhost -n 5 >nul
if not "%1"=="am_admin" (powershell start -verb runas '%0' am_admin & exit)
cls
echo -- Step - 2 of 3 : In next screen, select temp areas for cleaning 
during routine scheduled activity
ping localhost -n 3 >nul
C:\Windows\System32\cleanmgr.exe /sageset:112
cls
echo    Now scheduling maintenance activity...
SchTasks /Create /SC WEEKLY /D MON,THU /TN PC_Cleanup /TR 
"C:\Windows\System32\cleanmgr.exe "/sagerun:112 /ST 14:00

cls

echo                         -- Thanks for your co-operation --
echo                    -- Maintenance activity is scheduled for --
echo                       -- Every Monday and Thursday at 2 pm --

ping localhost -n 10 >nul

Terima kasih banyak untuk forum ini dan Rems POST di sini [ https://www.petri.com/forums/forum/windows-scripting/general-scripting/32313-schtasks-exe-need-to-pass-parameters-to-script ] [1]

Posnya membantu untuk mengonfigurasi argumen opsional saat menjadwalkan tugas.

Anand
sumber
1

Ada juga permintaan FSUTIL dari posting ini yang juga ditautkan di ss64.com yang memiliki kode berikut:

@Echo Off
Setlocal
:: First check if we are running As Admin/Elevated
FSUTIL dirty query %SystemDrive% >nul
if %errorlevel% EQU 0 goto START

::Create and run a temporary VBScript to elevate this batch file
   Set _batchFile=%~f0
   Set _Args=%*
   :: double up any quotes
   Set _batchFile=""%_batchFile:"=%""
   Set _Args=%_Args:"=""%

   Echo Set UAC = CreateObject^("Shell.Application"^) > "%temp%\~ElevateMe.vbs"
   Echo UAC.ShellExecute "cmd", "/c ""%_batchFile% %_Args%""", "", "runas", 1 >> "%temp%\~ElevateMe.vbs"

   cscript "%temp%\~ElevateMe.vbs" 
   Exit /B

:START
:: set the current directory to the batch file location
cd /d %~dp0
:: Place the code which requires Admin/elevation below
Echo We are now running as admin [%1] [%2]
pause

Selama FSUTIL ada, itu merupakan alternatif yang dapat diandalkan.

Laurie Stearn
sumber
0

Anda tidak dapat meminta hak admin dari file batch, tetapi Anda bisa menulis skrip host skrip windows di% temp% dan menjalankannya (dan itu menjalankan batch Anda sebagai admin) Anda ingin memanggil metode ShellExecute di Shell. Aplikasi objek dengan "runas" sebagai kata kerja

Anders
sumber
0

Gunakan mshtauntuk meminta hak admin:

@echo off
net session >nul 2>&1 && goto :admintasks
MSHTA "javascript: var shell = new ActiveXObject('shell.application'); shell.ShellExecute('%~nx0', '', '', 'runas', 1);close();"
exit /b
:admintasks
rem ADMIN TASKS HERE

Atau, menggunakan PowerShell:

powershell -c Start-Process "%~nx0" -Verb runas
HackingAddict1337
sumber
-5

gunakan perintah runas. Tapi, saya rasa Anda tidak dapat mengirim email file bat dengan mudah.

Josh
sumber
6
Jawaban ini salah. The runasperintah tidak dapat digunakan untuk memprovokasi elevasi.
Bill_Stewart