Bagaimana saya bisa meningkatkan file batch saya secara otomatis, sehingga meminta dari hak administrator UAC jika diperlukan?

209

Saya ingin file batch saya hanya berjalan tinggi. Jika tidak meningkat, berikan opsi bagi pengguna untuk meluncurkan kembali batch sebagai peningkatan.

Saya sedang menulis file batch untuk mengatur variabel sistem, menyalin dua file ke lokasi Program Files , dan memulai penginstal driver. Jika pengguna Windows 7 / Windows Vista ( UAC diaktifkan dan bahkan jika mereka adalah admin lokal) menjalankannya tanpa mengklik kanan dan memilih "Run as Administrator", mereka akan mendapatkan 'Akses Ditolak' menyalin dua file dan menulis variabel sistem .

Saya ingin menggunakan perintah untuk secara otomatis memulai ulang bets sebagai peningkatan jika pengguna sebenarnya adalah seorang administrator. Kalau tidak, jika mereka bukan administrator, saya ingin memberi tahu mereka bahwa mereka memerlukan hak administrator untuk menjalankan file batch. Saya menggunakan xcopy untuk menyalin file dan REG ADD untuk menulis variabel sistem. Saya menggunakan perintah itu untuk menangani kemungkinan mesin Windows XP. Saya telah menemukan pertanyaan serupa tentang topik ini, tetapi tidak ada yang berhubungan dengan meluncurkan kembali file batch yang meningkat.

PDixon724
sumber
2
Lihat apa yang telah saya posting - Anda tidak memerlukan alat eksternal, skrip secara otomatis memeriksa hak admin dan menaikkan otomatis sendiri jika diperlukan.
Matt
1
Harap pertimbangkan apakah jawaban Matt adalah jawaban yang dicentang? Sepertinya bagi saya.
akauppi
Silakan perhatikan petunjuk Windows 10 baru di bagian komentar dari skrip kumpulan yang telah saya posting.
Matt
4
Dari cmd: @powershell Start-Process cmd -Verb runas. Dari Powershell jatuhkan saja @powershell. Ini dimulai cmd dengan hak tinggi.
BrunoLM

Jawaban:

20

Anda dapat memiliki script panggilan itu sendiri dengan PsExec 's -hpilihan untuk menjalankan ditinggikan.

Saya tidak yakin bagaimana Anda akan mendeteksi jika sudah berjalan sebagai ditinggikan atau tidak ... mungkin coba lagi dengan perms tinggi hanya jika ada kesalahan Akses Ditolak?

Atau, Anda bisa saja memiliki perintah untuk xcopydan reg.exeselalu dijalankan psexec -h, tetapi akan mengganggu bagi pengguna akhir jika mereka perlu memasukkan kata sandi setiap kali (atau tidak aman jika Anda memasukkan kata sandi dalam skrip) ...

ewall
sumber
10
Terima kasih atas tanggapannya. Sayangnya, saya tidak berpikir saya dapat menggunakan alat apa pun di luar stok Windows Vista / 7 karena ini akan keluar untuk pelanggan di luar kantor saya. Saya rasa saya tidak bisa mendistribusikan PSExec secara legal.
PDixon724
2
Yup, saya pikir Anda benar tentang itu - meskipun PSExec sekarang menjadi alat Microsoft (karena mereka membeli Sysinternals guys!) EULA tidak melarang distribusi :(
ewall
2
Saya pikir opsi saya sangat terbatas. Jika saya tahu cara membuat kode di VB, saya bisa membuatnya menjadi exe dengan manifes admin, tetapi saya bahkan tidak tahu harus mulai dari mana. Saya kira saya hanya akan memperingatkan pada awal batch untuk dijalankan sebagai admin jika mereka menjalankan Windows Vista / 7. Terima kasih semuanya.
PDixon724
1
Alat pihak ke-3 lain yang mungkin dapat didistribusikan ulang secara bebas dan mudah diintegrasikan dan dipelajari adalah AutoIt ; halaman ini menunjukkan bagaimana skrip meminta hak yang lebih tinggi.
ewall
4
psexec -htidak berfungsi: 'Tidak dapat menginstal layanan PSEXESVC: Akses ditolak.' Anda harus sudah memiliki hak administrator untuk menjalankan psexec.
Nicolas
319

Ada cara mudah tanpa perlu menggunakan alat eksternal - ini berjalan dengan baik dengan Windows 7, 8, 8.1 dan 10 dan juga kompatibel-mundur (Windows XP tidak memiliki UAC, sehingga peningkatan tidak diperlukan - dalam hal itu huruf skrip hanya melanjutkan).

Lihatlah kode ini (saya terinspirasi oleh kode oleh NIronwolf yang diposting di File Batch utas - "Akses Ditolak" Pada Windows 7? ), Tapi saya telah memperbaikinya - dalam versi saya tidak ada direktori yang dibuat dan dihapus untuk periksa hak administrator):

::::::::::::::::::::::::::::::::::::::::::::
:: Elevate.cmd - Version 4
:: Automatically check & get admin rights
:: see "https://stackoverflow.com/a/12264592/1016343" for description
::::::::::::::::::::::::::::::::::::::::::::
 @echo off
 CLS
 ECHO.
 ECHO =============================
 ECHO Running Admin shell
 ECHO =============================

:init
 setlocal DisableDelayedExpansion
 set cmdInvoke=1
 set winSysFolder=System32
 set "batchPath=%~0"
 for %%k in (%0) do set batchName=%%~nk
 set "vbsGetPrivileges=%temp%\OEgetPriv_%batchName%.vbs"
 setlocal EnableDelayedExpansion

:checkPrivileges
  NET FILE 1>NUL 2>NUL
  if '%errorlevel%' == '0' ( goto gotPrivileges ) else ( goto getPrivileges )

:getPrivileges
  if '%1'=='ELEV' (echo ELEV & shift /1 & goto gotPrivileges)
  ECHO.
  ECHO **************************************
  ECHO Invoking UAC for Privilege Escalation
  ECHO **************************************

  ECHO Set UAC = CreateObject^("Shell.Application"^) > "%vbsGetPrivileges%"
  ECHO args = "ELEV " >> "%vbsGetPrivileges%"
  ECHO For Each strArg in WScript.Arguments >> "%vbsGetPrivileges%"
  ECHO args = args ^& strArg ^& " "  >> "%vbsGetPrivileges%"
  ECHO Next >> "%vbsGetPrivileges%"

  if '%cmdInvoke%'=='1' goto InvokeCmd 

  ECHO UAC.ShellExecute "!batchPath!", args, "", "runas", 1 >> "%vbsGetPrivileges%"
  goto ExecElevation

:InvokeCmd
  ECHO args = "/c """ + "!batchPath!" + """ " + args >> "%vbsGetPrivileges%"
  ECHO UAC.ShellExecute "%SystemRoot%\%winSysFolder%\cmd.exe", args, "", "runas", 1 >> "%vbsGetPrivileges%"

:ExecElevation
 "%SystemRoot%\%winSysFolder%\WScript.exe" "%vbsGetPrivileges%" %*
 exit /B

:gotPrivileges
 setlocal & cd /d %~dp0
 if '%1'=='ELEV' (del "%vbsGetPrivileges%" 1>nul 2>nul  &  shift /1)

 ::::::::::::::::::::::::::::
 ::START
 ::::::::::::::::::::::::::::
 REM Run shell as admin (example) - put here code as you like
 ECHO %batchName% Arguments: P1=%1 P2=%2 P3=%3 P4=%4 P5=%5 P6=%6 P7=%7 P8=%8 P9=%9
 cmd /k

Script mengambil keuntungan dari fakta yang NET FILEmembutuhkan hak administrator dan kembali errorlevel 1jika Anda tidak memilikinya. Ketinggian dicapai dengan membuat skrip yang meluncurkan kembali file batch untuk mendapatkan hak istimewa. Ini menyebabkan Windows menyajikan dialog UAC dan meminta Anda untuk akun administrator dan kata sandi.

Saya telah mengujinya dengan Windows 7, 8, 8.1, 10 dan dengan Windows XP - ini berfungsi dengan baik untuk semua. Keuntungannya adalah, setelah titik awal Anda dapat menempatkan apa pun yang memerlukan hak administrator sistem, misalnya, jika Anda ingin menginstal ulang dan menjalankan kembali layanan Windows untuk keperluan debugging (diasumsikan bahwa mypackage.msi adalah paket pemasang layanan) :

msiexec /passive /x mypackage.msi
msiexec /passive /i mypackage.msi
net start myservice

Tanpa skrip pengangkat hak istimewa ini, UAC akan meminta Anda tiga kali untuk pengguna dan kata sandi administrator Anda - sekarang Anda hanya diminta satu kali di awal, dan hanya jika diperlukan.


Jika skrip Anda hanya perlu menampilkan pesan kesalahan dan keluar jika tidak ada hak administrator, bukan pengangkatan otomatis, ini bahkan lebih sederhana: Anda dapat mencapainya dengan menambahkan yang berikut di awal skrip Anda:

@ECHO OFF & CLS & ECHO.
NET FILE 1>NUL 2>NUL & IF ERRORLEVEL 1 (ECHO You must right-click and select &
  ECHO "RUN AS ADMINISTRATOR"  to run this batch. Exiting... & ECHO. &
  PAUSE & EXIT /D)
REM ... proceed here with admin rights ...

Dengan cara ini, pengguna harus mengklik kanan dan memilih "Run as administrator" . Script akan dilanjutkan setelah REMpernyataan jika mendeteksi hak administrator, jika tidak keluar dengan kesalahan. Jika Anda tidak memerlukannya PAUSE, hapus saja. Penting: NET FILE [...] EXIT /D) harus di jalur yang sama. Ini ditampilkan di sini dalam beberapa baris untuk keterbacaan yang lebih baik!


Pada beberapa mesin, saya mengalami masalah, yang sudah diselesaikan pada versi baru di atas. Salah satunya adalah karena penanganan penawaran ganda yang berbeda, dan masalah lainnya adalah karena fakta bahwa UAC dinonaktifkan (diatur ke level terendah) pada mesin Windows 7, karenanya skrip menyebut dirinya berulang kali.

Saya telah memperbaikinya sekarang dengan menghilangkan tanda kutip di jalur dan menambahkannya kembali nanti, dan saya telah menambahkan parameter tambahan yang ditambahkan ketika skrip diluncurkan kembali dengan hak yang ditingkatkan.

Kutipan ganda dihapus oleh yang berikut (detail ada di sini ):

setlocal DisableDelayedExpansion
set "batchPath=%~0"
setlocal EnableDelayedExpansion

Anda kemudian dapat mengakses jalur dengan menggunakan !batchPath!. Itu tidak mengandung tanda kutip ganda, jadi aman untuk mengatakannya "!batchPath!"nanti dalam skrip.

Garis

if '%1'=='ELEV' (shift & goto gotPrivileges)

memeriksa apakah skrip telah dipanggil oleh skrip VBScript untuk meningkatkan hak, sehingga menghindari rekursi yang tak ada habisnya. Ini menghapus parameter menggunakan shift.


Memperbarui:

  • Untuk menghindari harus mendaftarkan .vbsekstensi di Windows 10 , saya telah mengganti baris
    "%temp%\OEgetPrivileges.vbs"
    dengan
    "%SystemRoot%\System32\WScript.exe" "%temp%\OEgetPrivileges.vbs"
    skrip di atas; juga ditambahkan cd /d %~dp0seperti yang disarankan oleh Stephen (jawaban terpisah) dan oleh Tomáš Zato (komentar) untuk menetapkan direktori skrip sebagai default.

  • Sekarang skrip menghormati parameter baris perintah yang diteruskan ke sana. Berkat jxmallet, TanisDLJ dan Peter Mortensen untuk pengamatan dan inspirasi.

  • Menurut petunjuk Artjom B., saya menganalisanya dan telah menggantinya SHIFTdengan SHIFT /1, yang mempertahankan nama file untuk %0parameter

  • Ditambahkan del "%temp%\OEgetPrivileges_%batchName%.vbs"ke :gotPrivilegesbagian untuk membersihkan (sebagai MLT disarankan). Ditambahkan %batchName%untuk menghindari dampak jika Anda menjalankan batch berbeda secara paralel. Perhatikan bahwa Anda perlu menggunakan foruntuk dapat memanfaatkan fungsi string lanjutan, seperti %%~nk, yang mengekstrak hanya nama file.

  • Struktur skrip yang dioptimalkan, perbaikan (variabel tambahan vbsGetPrivilegesyang sekarang direferensikan di mana-mana memungkinkan untuk mengubah jalur atau nama file dengan mudah, hanya menghapus .vbsfile jika batch perlu ditingkatkan)

  • Dalam beberapa kasus, sintaks panggilan yang berbeda diperlukan untuk elevasi. Jika skrip tidak berfungsi, periksa parameter berikut:
    set cmdInvoke=0
    set winSysFolder=System32
    Ubah parameter 1 ke set cmdInvoke=1dan periksa apakah sudah memperbaiki masalah. Ini akan menambah cmd.exeskrip yang melakukan elevasi.
    Atau coba ubah parameter ke-2 winSysFolder=Sysnative, ini mungkin membantu (tetapi dalam banyak kasus tidak diperlukan) pada sistem 64 bit. (ADBailey telah melaporkan ini). "Sysnative" hanya diperlukan untuk meluncurkan aplikasi 64-bit dari host skrip 32-bit (mis. Proses pembuatan Visual Studio, atau permintaan skrip dari aplikasi 32-bit lainnya).

  • Untuk membuatnya lebih jelas bagaimana parameter ditafsirkan, saya menampilkannya sekarang seperti P1=value1 P2=value2 ... P9=value9. Ini sangat berguna jika Anda perlu menyertakan parameter seperti jalur dalam tanda kutip ganda, misalnya "C:\Program Files".

  • Jika Anda ingin men-debug skrip VBS, Anda dapat menambahkan //Xparameter ke WScript.exe sebagai parameter pertama, seperti yang disarankan di sini (dijelaskan untuk CScript.exe, tetapi juga berfungsi untuk WScript.exe).

Tautan yang bermanfaat:

Mat
sumber
9
Jawaban yang bagus, walaupun sedikit mengherankan saya bahwa Anda harus melakukan semua itu untuk melakukan sesuatu yang jelas diperlukan dalam beberapa kasus.
jcoder
50
Memang, perintah seperti ELEVATE jelas hilang dalam bahasa batch Windows.
Matt
2
Mungkin lebih mudah dengan PowerShell yang tampaknya menjadi lanaguge scripting yang disetujui untuk hal-hal yang lebih kompleks, tapi saya tidak pernah repot-repot mempelajarinya sejauh ini :(
jcoder
1
Sintaks dalam PowerShell benar-benar berbeda (sintaksis kata kerja), tetapi memungkinkan Anda untuk memanggil .NET assemblies dengan mudah. Tetapi sedikit lebih sulit untuk menanganinya (menandatangani skrip dll).
Matt
2
@ Matt Bisakah Anda memeriksa apakah ada kebenaran di balik pengeditan yang ditolak ini pada jawaban Anda?
Artjom B.
41

Seperti yang disebutkan jcoder dan Matt, PowerShell membuatnya mudah, dan itu bahkan bisa tertanam dalam skrip batch tanpa membuat skrip baru.

Saya memodifikasi skrip Matt:

:: Check privileges 
net file 1>NUL 2>NUL
if not '%errorlevel%' == '0' (
    powershell Start-Process -FilePath "%0" -ArgumentList "%cd%" -verb runas >NUL 2>&1
    exit /b
)

:: Change directory with passed argument. Processes started with
:: "runas" start with forced C:\Windows\System32 workdir
cd /d %1

:: Actual work
Ir Relevan
sumber
3
Anda benar, jika PowerShell diinstal, Anda dapat menggunakannya untuk menjalankan file batch dengan elevasi (terima kasih atas potongan kode!). Dan ya, label itu tidak diperlukan. Terima kasih atas petunjuknya, ini bernilai +1 ... :-)
Matt
2
Ketika dipanggil dari cmd Powershell.exe tidak memiliki opsi -verb runas. Itu ada jika Anda sudah berada di PowerShell.
Adil Hindistan
1
Saya sangat suka solusi ini, bekerja sangat baik untuk saya. Pada Windows 8.1 saya memang membutuhkan label: gotPrivileges agar bisa berfungsi.
ShaunO
Saya memukul masalah jika file batch ini jauh di jalur UNC.
Ryan Beesley
Saya menambahkan direktori perubahan saat start, menyederhanakan aliran dan membersihkan sedikit. Perintah kerja tidak dapat diubah melalui WorkingDirectoryparameter Start-Processkarena alasan keamanan dalam runasproses
ceztko
28

Saya menggunakan jawaban Matt yang sangat baik, tetapi saya melihat perbedaan antara sistem Windows 7 dan Windows 8 saya ketika menjalankan skrip yang ditinggikan.

Setelah skrip diangkat pada Windows 8, direktori saat ini diatur ke C:\Windows\system32. Untungnya, ada solusi yang mudah dengan mengubah direktori saat ini ke jalur skrip saat ini:

cd /d %~dp0

Catatan: Gunakan cd /duntuk memastikan huruf drive juga berubah.

Untuk menguji ini, Anda dapat menyalin yang berikut ini ke skrip. Jalankan secara normal di kedua versi untuk melihat hasil yang sama. Jalankan sebagai Admin dan lihat perbedaan pada Windows 8:

@echo off
echo Current path is %cd%
echo Changing directory to the path of the current script
cd %~dp0
echo Current path is %cd%
pause
Stephen Klancher
sumber
1
Petunjuk yang bagus, Stephen. Jadi skrip harus diakhiri dengan cd %~dp0mempertahankan jalurnya saat ini (saya berasumsi ini berfungsi di Win7 juga, jadi perintah yang sama dapat digunakan meskipun hanya diperlukan untuk Win8 +). +1 untuk ini!
Matt
2
Dari catatan ini juga diperlukan pada sistem saya yang menjalankan Windows 7.
meh-uk
1
atau gunakan pushd %~dp0saja ... mengapa? karenapopd
Jaroslav Záruba
27

Saya melakukannya dengan cara ini:

NET SESSION
IF %ERRORLEVEL% NEQ 0 GOTO ELEVATE
GOTO ADMINTASKS

:ELEVATE
CD /d %~dp0
MSHTA "javascript: var shell = new ActiveXObject('shell.application'); shell.ShellExecute('%~nx0', '', '', 'runas', 1);close();"
EXIT

:ADMINTASKS
(Do whatever you need to do here)
EXIT

Dengan cara ini sederhana dan hanya menggunakan perintah standar windows. Ini bagus jika Anda perlu mendistribusikan file batch Anda.

CD /d %~dp0Setel direktori saat ini ke direktori file saat ini (jika belum, terlepas dari drive file yang ada, berkat /dopsi).

%~nx0 Mengembalikan nama file saat ini dengan ekstensi (Jika Anda tidak menyertakan ekstensi dan ada exe dengan nama yang sama pada folder, itu akan memanggil exe).

Ada begitu banyak balasan pada posting ini, saya bahkan tidak tahu apakah balasan saya akan terlihat.

Lagi pula, saya menemukan cara ini lebih sederhana daripada solusi lain yang diusulkan pada jawaban lain, saya harap ini membantu seseorang.

Matheus Rocha
sumber
4
cd% ~ dp0 tidak akan berfungsi pada drive jaringan, gunakan pushd% ~ dp0 sebagai gantinya.
Stavm
1
Saya suka kesederhanaan jawaban ini. Dan akhirnya alasan untuk menggunakan Jscript!
Joe Coder
1
Sihir! Terima kasih banyak.
Daniele Orlando
1
@ Serigala Saya mengetik jawaban besar hanya untuk menyadari bahwa saya salah mengerti Anda ... Saya mengerti maksud Anda sekarang. Saya akan mengeditnya untuk memasukkan /d. Terima kasih sobat :) (PS: Pianis di sini juga!)
Matheus Rocha
1
Ini berfungsi dengan baik, tetapi mungkin ide yang baik untuk memindahkan cdperintah ke awal (ini memastikan bahwa path juga tersedia untuk skrip yang ditinggikan - jika skrip yang ditinggikan hanya berjalan dari system32). Anda juga harus mengarahkan ulang perintah net ke nul untuk menyembunyikan outputnya:net session >nul 2>&1
Nulano
23

Matt memiliki jawaban yang bagus, tetapi menghapus semua argumen yang dilewatkan ke skrip. Ini modifikasi saya yang menyimpan argumen. Saya juga memasukkan perbaikan Stephen untuk masalah direktori kerja di Windows 8.

@ECHO OFF
setlocal EnableDelayedExpansion

NET FILE 1>NUL 2>NUL
if '%errorlevel%' == '0' ( goto START ) else ( goto getPrivileges ) 

:getPrivileges
if '%1'=='ELEV' ( goto START )

set "batchPath=%~f0"
set "batchArgs=ELEV"

::Add quotes to the batch path, if needed
set "script=%0"
set script=%script:"=%
IF '%0'=='!script!' ( GOTO PathQuotesDone )
    set "batchPath=""%batchPath%"""
:PathQuotesDone

::Add quotes to the arguments, if needed.
:ArgLoop
IF '%1'=='' ( GOTO EndArgLoop ) else ( GOTO AddArg )
    :AddArg
    set "arg=%1"
    set arg=%arg:"=%
    IF '%1'=='!arg!' ( GOTO NoQuotes )
        set "batchArgs=%batchArgs% "%1""
        GOTO QuotesDone
        :NoQuotes
        set "batchArgs=%batchArgs% %1"
    :QuotesDone
    shift
    GOTO ArgLoop
:EndArgLoop

::Create and run the vb script to elevate the batch file
ECHO Set UAC = CreateObject^("Shell.Application"^) > "%temp%\OEgetPrivileges.vbs"
ECHO UAC.ShellExecute "cmd", "/c ""!batchPath! !batchArgs!""", "", "runas", 1 >> "%temp%\OEgetPrivileges.vbs"
"%temp%\OEgetPrivileges.vbs" 
exit /B

:START
::Remove the elevation tag and set the correct working directory
IF '%1'=='ELEV' ( shift /1 )
cd /d %~dp0

::Do your adminy thing here...
jxmallett
sumber
1
Ini jawaban yang bermanfaat. Namun ECHO UAC.ShellExecute....sejalan, "batchArgs!"tidak akan memperluas variabel. Gunakan "!batchArgs!". Hasil edit saya ditolak, jadi saya berkomentar.
Menerbangkan bawang
1
@ fliedonion terlihat dengan baik! Saya tidak yakin mengapa hasil edit Anda ditolak karena pasti kesalahan ketik dan perbaikan Anda berhasil. Membuat perubahan sendiri dan mengujinya di Win 8.1. Sekarang untuk menemukan semua skrip tempat saya menggunakan kode ini ....
jxmallett
2
Script pecah ketika menggunakan argumen yang dikutip, seperti test.bat "a thing"atau "test script.bat" arg1 arg2. Semua sudah diperbaiki sekarang.
jxmallett
Saya berhasil memecahkannya (karena kesalahan saya: menjalankan skrip dari drive jaringan yang dipetakan, karena admin dan pengguna normal tidak memiliki pemetaan yang sama). Namun: apakah ada cara untuk melihat hasilnya? Bagi saya, saya harus menemukan .vbs dan mengubah / c menjadi / K dan kemudian melihatnya secara manual.
Andreas Reiff
21

Saya menggunakan PowerShell untuk meluncurkan kembali script yang ditinggikan jika tidak. Letakkan baris ini di bagian paling atas dari skrip Anda.

net file 1>nul 2>nul && goto :run || powershell -ex unrestricted -Command "Start-Process -Verb RunAs -FilePath '%comspec%' -ArgumentList '/c %~fnx0 %*'"
goto :eof
:run
:: TODO: Put code here that needs elevation

Saya menyalin metode 'nama bersih' dari jawaban @ Matt. Jawabannya jauh lebih baik didokumentasikan dan memiliki pesan kesalahan dan sejenisnya. Yang ini memiliki keunggulan bahwa PowerShell sudah diinstal dan tersedia pada Windows 7 dan yang lebih tinggi. Tidak ada file VBScript (* .vbs) sementara, dan Anda tidak perlu mengunduh alat.

Metode ini harus berfungsi tanpa konfigurasi atau pengaturan apa pun, selama izin eksekusi PowerShell Anda tidak dikunci.

Ryan Bemrose
sumber
ketika memberikan daftar spasi terpisah argumen yang dikelilingi oleh tanda kutip untuk membuatnya diperlakukan sebagai satu, /c %~fnx0 %*'bagian tampaknya meninggalkan setiap bagian selain yang pertama. Misalnya dari test.bat "arg1 arg2 arg3"hanya arg1 yang diteruskan
Nicolas Mommaerts
Tampaknya apa pun yang terjadi, Proses Mulai menghapus semua tanda kutip ganda dalam daftar argumen ..
Nicolas Mommaerts
Bekerja untukku! Saya menggunakannya untuk netsh int set int %wifiname% Enable/Disable.
Marslo
2
Saya memiliki masalah yang sama dengan Nicolas Mommaerts di atas. Saya tidak mengerti mengapa ini bekerja (jenis perbaikan terbaik), tetapi yang berikut berfungsi seperti seharusnya (perhatikan semua tanda kutip tambahan di akhir): net file 1>nul 2>nul && goto :run || powershell -ex unrestricted -Command "Start-Process -Verb RunAs -FilePath '%comspec%' -ArgumentList '/c ""%~fnx0""""'"
gempa
Masalah lain (ketidaknyamanan) adalah skrip berhenti (menunggu input pengguna) jika layanan server tidak berjalan (saya menonaktifkannya karena alasan). Saya biasanya menguji perms admin dengan mencoba menulis ke lokasi file HOSTS , tapi mungkin lebih baik untuk memanggil perintah powershell - Verb runas , daripada mengandalkan layanan windows yang diaktifkan atau mencoba menulis file.
script'n'code
15

Untuk beberapa program, pengaturan __COMPAT_LAYERvariabel lingkungan super rahasia RunAsInvoker akan berfungsi. Periksa ini:

set "__COMPAT_LAYER=RunAsInvoker"
start regedit.exe

Meskipun seperti ini tidak akan ada UAC yang meminta pengguna akan melanjutkan tanpa izin admin.

npocmaka
sumber
1
Tautan ke situs Microsoft tidak lagi berfungsi, jadi saya mengubahnya ke konten di archive.org. Jika ada yang bisa menemukan tautan yang berfungsi untuk konten di situs Microsoft, tetapi semua sarana, harap perbarui untuk itu.
RockPaperLizard
1
masih dalam integritas sedang yang tidak ditingkatkan , jadi Anda tidak dapat mengedit HKLM di regedit. Itu hanya melewatkan uac.
HackingAddict1337
5

Saya menempelkan ini di awal skrip:

:: BatchGotAdmin
:-------------------------------------
REM  --> Check for permissions
>nul 2>&1 "%SYSTEMROOT%\system32\icacls.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"
    echo args = "" >> "%temp%\getadmin.vbs"
    echo For Each strArg in WScript.Arguments >> "%temp%\getadmin.vbs"
    echo args = args ^& strArg ^& " "  >> "%temp%\getadmin.vbs"
    echo Next >> "%temp%\getadmin.vbs"
    echo UAC.ShellExecute "%~s0", args, "", "runas", 1 >> "%temp%\getadmin.vbs"

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

:gotAdmin
    if exist "%temp%\getadmin.vbs" ( del "%temp%\getadmin.vbs" )
    pushd "%CD%"
    CD /D "%~dp0"
:--------------------------------------
TanisDLJ
sumber
2
Saya suka pemrosesan arg di skrip Anda. Tetapi perhatikan bahwa caclssudah usang di Windows 7 dan versi windows yang lebih baru.
Mat
Fsutil kotor bahkan lebih baik
Serigala
1
Apakah Anda tahu bahwa baris pushd "%CD%"menyimpan direktori kerja saat ini dan perubahan ke direktori kerja saat ini?
Wolf
3

Saya menulis gsudo, a sudofor windows : yang naik di konsol saat ini (tidak ada konteks beralih ke jendela baru), dengan cache kredensial (mengurangi popup UAC), dan juga meninggikan perintah PowerShell .

Ini memungkinkan untuk meninggikan perintah yang memerlukan hak admin, atau seluruh kumpulan, jika Anda mau. Hanya tambahkan gsudo sebelum apa pun yang perlu dijalankan ditinggikan.

Contoh file batch yang naik sendiri menggunakan gsudo:

EDIT: Versi one liner baru yang berfungsi dengan bahasa windows apa pun dan menghindari masalah whoami :

net session >nul 2>nul & net session >nul 2>nul || gsudo "%~f0" && exit /b || exit /b
:: This will run as admin ::

Alternatif (versi asli):

@echo off
  rem Test if current context is already elevated:
  whoami /groups | findstr /b BUILTIN\Administrators | findstr /c:"Enabled group" 1> nul 2>nul && goto :isadministrator
  echo You are not admin. (yet)
  :: Use gsudo to launch this batch file elevated.
  gsudo "%~f0"
  goto end
:isadministrator
  echo You are admin.
  echo (Do admin stuff now).
:end

Install:

Lihat gsudo sedang beraksi: demo gsudo

Gerardo Grignoli
sumber
Keren. Terima kasih. Pada versi Windows manakah fungsinya?
RockPaperLizard
Suite tes berjalan di Server 2019 dan kotak dev lokal saya adalah Windows 10 1909. Maaf saya belum menguji kompatibilitas dengan OS lama lainnya.
Gerardo Grignoli
Terima kasih Gerardo. Jika ada yang mencobanya di versi Windows lain, silakan kirim hasil Anda.
RockPaperLizard
Saya baru saja menguji gsudo v0.7 pada Windows 8.1 dan berfungsi. Tidak sepele untuk menginstal di .Net Framework 4.6sana. Untungnya choco install dotnet4.6.2membawa beberapa dependensi yang sulit didapat. Kemudian gsudo config Prompt "$p# "memperbaiki masalah dengan ConHostmenampilkan prompt yang salah (escape sequence chars bukannya red sharp). @RockPaperLizard
Gerardo Grignoli
Terima kasih banyak Gerardo. Bisakah itu dikompilasi ulang untuk bekerja dengan versi .Net Framework sebelum 4.6, atau apakah itu tergantung pada beberapa fungsi khusus untuk 4.6?
RockPaperLizard
2

Meskipun tidak secara langsung berlaku untuk pertanyaan ini, karena ingin beberapa informasi untuk pengguna, google membawa saya ke sini ketika saya ingin menjalankan file .bat saya yang diangkat dari penjadwal tugas.

Pendekatan yang paling sederhana adalah membuat pintasan ke file .bat, karena untuk pintasan Anda dapat mengatur Run as administratorlangsung dari properti tingkat lanjut.

Menjalankan pintasan dari penjadwal tugas, menjalankan file .bat terangkat.

Hugo Delsing
sumber
1

Jika Anda tidak perlu melewati argumen maka inilah skrip prompt UAC ringkas yang panjangnya satu baris. Ini melakukan hal yang sama dengan skrip elevasi di bagian atas memilih jawaban tetapi tidak lolos argumen karena tidak ada cara mudah untuk melakukan itu yang menangani setiap kombinasi yang mungkin dari karakter racun.

@echo off
net sess>nul 2>&1||(echo(CreateObject("Shell.Application"^).ShellExecute"%~0",,,"RunAs",1:CreateObject("Scripting.FileSystemObject"^).DeleteFile(wsh.ScriptFullName^)>"%temp%\%~nx0.vbs"&start wscript.exe "%temp%\%~nx0.vbs"&exit)

:: Your batch file goes here
pengguna8922283
sumber
0

Menggunakan PowerShell.

Jika file cmd panjang, saya menggunakan yang pertama membutuhkan elevasi dan kemudian memanggil yang melakukan pekerjaan yang sebenarnya.

Jika skrip adalah perintah sederhana semuanya mungkin muat pada satu file cmd. Jangan lupa menyertakan path pada file skrip.

Templat:

@echo off
powershell -Command "Start-Process 'cmd' -Verb RunAs -ArgumentList '/c " comands or another script.cmd go here "'"

Contoh 1:

@echo off
powershell -Command "Start-Process 'cmd' -Verb RunAs -ArgumentList '/c "powershell.exe -NoProfile -ExecutionPolicy Bypass -File C:\BIN\x.ps1"'"

Contoh 2:

@echo off
powershell -Command "Start-Process 'cmd' -Verb RunAs -ArgumentList '/c "c:\bin\myScript.cmd"'"
Manuel Alves
sumber
0

Coba ini:

@echo off
CLS
:init
setlocal DisableDelayedExpansion
set cmdInvoke=1
set winSysFolder=System32
set "batchPath=%~0"
for %%k in (%0) do set batchName=%%~nk
set "vbsGetPrivileges=%temp%\OEgetPriv_%batchName%.vbs"
setlocal EnableDelayedExpansion
:checkPrivileges
NET FILE 1>NUL 2>NUL
if '%errorlevel%' == '0' ( goto gotPrivileges ) else ( goto getPrivileges )
:getPrivileges
if '%1'=='ELEV' (echo ELEV & shift /1 & goto gotPrivileges)
ECHO.
ECHO Set UAC = CreateObject^("Shell.Application"^) > "%vbsGetPrivileges%"
ECHO args = "ELEV " >> "%vbsGetPrivileges%"
ECHO For Each strArg in WScript.Arguments >> "%vbsGetPrivileges%"
ECHO args = args ^& strArg ^& " "  >> "%vbsGetPrivileges%"
ECHO Next >> "%vbsGetPrivileges%"
if '%cmdInvoke%'=='1' goto InvokeCmd 
ECHO UAC.ShellExecute "!batchPath!", args, "", "runas", 1 >> "%vbsGetPrivileges%"
goto ExecElevation
:InvokeCmd
ECHO args = "/c """ + "!batchPath!" + """ " + args >> "%vbsGetPrivileges%"
ECHO UAC.ShellExecute "%SystemRoot%\%winSysFolder%\cmd.exe", args, "", "runas", 1 >> "%vbsGetPrivileges%"
:ExecElevation
"%SystemRoot%\%winSysFolder%\WScript.exe" "%vbsGetPrivileges%" %*
exit /B
:gotPrivileges
setlocal & cd /d %~dp0
if '%1'=='ELEV' (del "%vbsGetPrivileges%" 1>nul 2>nul  &  shift /1)
REM Run shell as admin (example) - put here code as you like
ECHO %batchName% Arguments: P1=%1 P2=%2 P3=%3 P4=%4 P5=%5 P6=%6 P7=%7 P8=%8 P9=%9
cmd /k

Jika Anda memerlukan informasi tentang file kumpulan itu, jalankan Cuplikan HTML / JS / CSS:

document.getElementsByTagName("data")[0].innerHTML="ElevateBatch, version 4, release<br>Required Commands:<ul><li>CLS</li><li>SETLOCAL</li><li>SET</li><li>FOR</li><li>NET</li><li>IF</li><li>ECHO</li><li>GOTO</li><li>EXIT</li><li>DEL</li></ul>It auto-elevates the system and if the user presses No, it just doesn't do anything.<br>This CANNOT be used to create an Elevated Explorer.";
data{font-family:arial;text-decoration:none}
<data></data>


sumber
-3

Solusi berikut ini bersih dan berfungsi dengan baik.

  1. Unduh Tinggikan file zip dari https://www.winability.com/download/Elevate.zip

  2. Di dalam zip Anda harus menemukan dua file: Elevate.exe dan Elevate64.exe. (Yang terakhir adalah kompilasi 64-bit asli, jika Anda mengharuskan itu, meskipun versi 32-bit reguler, Elevate.exe, harus bekerja dengan baik dengan versi Windows 32-dan 64-bit)

  3. Salin file Elevate.exe ke folder di mana Windows selalu dapat menemukannya (seperti C: / Windows). Atau Anda lebih baik Anda dapat menyalin di folder yang sama di mana Anda berencana untuk menyimpan file bat Anda.

  4. Untuk menggunakannya dalam file batch, cukup tambahkan perintah yang ingin Anda jalankan sebagai administrator dengan perintah elevate, seperti ini:

 elevate net start service ...
Vaibhav Jain
sumber
2
Perintah itu hanya membuka dialogwindow apa yang meminta pengguna jika perintah ini diizinkan untuk dieksekusi. Jadi Anda tidak dapat menggunakan perintah ini dalam batchfile apa yang harus dijalankan TANPA interaksi pengguna.
Radon8472
Jika memungkinkan untuk meningkatkan TANPA interaksi pengguna, itu akan menjadi lubang keamanan yang besar, bukan? Setiap virus akan mulai menggunakan metode itu untuk meningkatkan dirinya sendiri tanpa persetujuan pengguna.
Andrei Belogortseff