Toplu iş dosyası içinde Yönetici erişimi nasıl istenir


179

Kullanıcılarımın Vista makinelerinden UAC ile çalışması için bir toplu iş dosyası yazmaya çalışıyorum. Dosya kendi hosts dosyasını yeniden yazıyor, bu yüzden Yönetici izinleriyle çalıştırılması gerekiyor. Onlara .bat dosyasına bağlantı içeren bir e-posta gönderebilmem gerekiyor. İstenen davranış, dosyaya sağ tıklayıp Aç dediklerinde, ekranın kararmasını sağlayan ve uygulamaya yönetici olarak çalışmasına izin vermek isteyip istemediklerini yanıtlamaya zorlayan UAC iletişim kutularından birini almalarıdır. Bunun yerine, komut satırı penceresinde yalnızca "Erişim reddedildi" ifadesini görüyorlar.

Farklı yapmak mümkün mü?


2
Buna rastladıysanız ve benim gibi PowerShell'i kullanmaktan memnunsanız, @ toster-cx'teki tek astarı kaçırmayın. Mükemmel!
Michael Repucci

Yanıtlar:


353

Bu script hile yapıyor! Sadece bat dosyanızın üstüne yapıştırın. Komut dosyanızın çıktısını gözden geçirmek istiyorsanız, toplu iş dosyanızın altına bir "duraklat" komutu ekleyin.

GÜNCELLEME: Bu komut dosyası artık komut satırı argümanlarını ve 64 bit işletim sistemini desteklemek için biraz düzenlenmiştir.

Teşekkür ederim 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>

22
Bu pis dos toplu saçma yapmak zorunda kalmaktan nefret ediyorum ama bazen zorla ve bu harika çalışıyor. Şerefe!
matt

4
Bu yöntem bağımsız değişkenleri iletmez. Bunun nasıl yapılabileceğini biliyor musunuz? Temel olarak gözlemlediğim şey,% 1 ilk satırında bir değer ve son satırda% 1 boştur. Argümanları iletmem gerekiyor.
Ocak'ta çatallar

3
Tıpkı bir FYI gibi, Windows 8 Embedded'de çalıştığı test edilmiştir
Robert Snyder

6
Bu, makinemi ekran boyunca çapraz olarak açılıp kapanan bir komut penceresi sarmalına atar. Durdurmanın tek yolu orijinal toplu iş dosyasını silmektir. Art arda toplu iş dosyamı çalıştırıyor ve vbs dosyası yazıyor. İlk kez yetkilendirme istedi, ancak bundan sonra sadece döngüler.
TomDestry

2
Ben sonsuz döngü ve dönüş kodu 2 ile TomDestry aynı sorunla karşılaştı. Bu Windows 8.1 idi. Windows 8.0 üzerinde çalıştığını biliyorum ve 8.1 güncellemesi mi, yoksa soruna neden olan başka bir şey mi olduğunu söyleyemem. Benim için çalışan çözüm cacls.exe (veya icacls) kullanmak değildi, bunun yerine: net session> nul 2> & 1 ERRORLEVEL 1 EĞER UACPrompt ...
23

55

İşte kullandığım bir astar:

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

echo main code here
pause

Notlar:

  • Sadece Windows 7 ve 10'da test edildi, alıntılarla uğraşmak zorunda kalabilirsiniz
  • Şimdilik argümanların aktarılmasını desteklemiyor

1
Kaç param olabileceğini biliyorsanız, parametreleri sonra dahil ederek parametreleri iletebilirsiniz am_admin if not "%1"=="am_admin" (powershell start -verb runas '%0' 'am_admin "%~1" "%~2"' & exit). Params, bulundukları yerin üstünde bir tane olacak
Tony Brix

Ayrıca 'am_admin %*'her şeyi geçmek için kullanmak mümkün , tırnak ve boşluklarla iyi oynamıyor tho: / shiftİlk arg kapalı pop toplu olarak kullanabilirsiniz , böylece hariç tüm argümanlar sabitleme %0.
toster-cx

Bu iyi bir cevaptır, ancak kabul edilmemelidir, çünkü İLK çalıştırmada ADMIN ayrıcalığı ile çalıştırılıp çalıştırılmadığını kontrol etmez.
T.Todua

Çalışma dizini eklenti tutmak için cd /D %~dp0sonraif not "%1"=="am_admin" (powershell start -verb runas '%0' am_admin & exit /b)
Pedro Duarte

İyi cevap. VB komut dosyası,% temp% için yazma izniyle bile sonsuz bir döngü oluştururken çalışır.
Twonky

19

İşte kodum! Büyük görünüyor ama çoğunlukla yorum satırları (ile başlayan satırlar: :).

Özellikleri:

  • Tam argüman iletme
  • Çalışma klasörünü değiştirmez
  • Hata yönetimi
  • Parantezli yolları kabul eder (% TEMP% klasörü hariç)
  • UNC yollarını destekler
  • Eşlenmiş klasör kontrolü (Yönetici eşlenen sürücüye erişemiyorsa sizi uyarır)

  • Harici kütüphane olarak kullanılabilir (bu konudaki yazımı kontrol edin: https://stackoverflow.com/a/30417025/4932683 )

  • Kodunuzda herhangi bir yerde / gerektiğinde çağrılabilir

Bunu toplu iş dosyanızın sonuna ekleyin veya kitaplık olarak kaydedin (yukarıya bakın)

:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
: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
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::

Nasıl kullanılacağı ile ilgili örnek

: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]

Harika çalışıyor ama işe yaraması için bir hattı değiştirmek zorunda kaldım. &fc;: 2>nulİçinde set "_FN=_%~ns1" & echo/%TEMP%| findstr /C:"(" >nul && (echo/ERROR: %%TEMP%% path can not contain parenthesis &pause &endlocal &fc;: 2>nul & goto:eof)1'e errorlevel batıyordu ben o bölümü kaldırılmış ve mükemmel çalıştı. Windows 10 Home kullanıyorum.
Knyri

% Temp% klasörünüzün yolunda parantez var mı? Sadece bu durumda hata seviyesi 1'in ayarlanması gerekir.
cyberponk

Hayır! fc;:Gittiği günden bu yana ihtiyacı var mı : hemen sonra? Bu biraz da soruna neden neden olduğundan emin değilim, çünkü yürütülmeli.
Knyri

"fc ;: 2> nul" kasıtlı olarak bir hata sinyali vermek için çıkmadan önce ERRORLEVEL 1'i ayarlamak içindir. Lütfen @echo dosyasını çıkarıp bir koşu yapıp çıktıyı bana özel bir mesajla gönderebilir misiniz? Teşekkürler!
cyberponk

Her neyse, ortam değişkeninizde echo/%TEMP%| findstr /C:"(" >nulbir (karakter varsa testler %temp%ve sadece &&eğer pozitif sonra parçayı çalıştırmak gerekir . Testinizin neden (olumlu geri döndüğü garip .
cyberponk

7

Başka bir yaklaşım

  • yerel olarak bir kısayol oluşturun ve Yönetici izni için çağrılacak şekilde ayarlayın (Özellikler, Gelişmiş, Yönetici Olarak Çalıştır)

ve sonra

  • kullanıcılarınıza kısayolu (veya toplu iş dosyasının kendisine değil kısayolun bağlantısını) gönderin.

6

Ben Gripka'nın çözümü sonsuz döngülere neden oluyor. Onun toplu iş böyle çalışır (sözde kod):

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

Gördüğünüz gibi, VBS yönetici ayrıcalıkları istemezse bu sonsuz bir döngüye neden olur.

Bununla birlikte, yönetici ayrıcalıkları başarıyla istendi, ancak sonsuz döngü oluşabilir.

Ben Gripka'nın toplu iş dosyasındaki check sadece hataya açıktır. Parti ile oynadım ve kontrol başarısız olmasına rağmen yönetici ayrıcalıklarının mevcut olduğunu gözlemledim. İlginç bir şekilde, toplu iş dosyasını Windows Gezgini'nden başlatırsam, beklendiği gibi çalıştı, ancak IDE'imden başlattığımda olmadı.

Bu yüzden iki ayrı toplu iş dosyası kullanmanızı öneririm. Birincisi, ikinci toplu iş dosyasını çağıran VBS'yi oluşturur:

@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"

"My_commands.bat" adlı ve birinciyle aynı dizinde bulunan ikincisi gerçek komutlarınızı içerir:

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

Bu sonsuz döngüye neden olmaz ve hataya açık yönetici ayrıcalık denetimini de kaldırır.


Senin için mi çalıştın? Ne yazık ki benim için, bu ve diğer tüm iş parçacığı burada ve tüm diğer aynı sorun nedeniyle başarısız. Kabuk Nesnesi başka bir programın içinden dolaylı olarak oluşturulduğunda "runas" parm (veya command) başarısız olur . İlgi Konu burada .
Laurie Stearn

Worked for me :)
Sritam Jagadev

6

Başka Bir PowerShell Çözümü ...

Bu, bir toplu iş komut dosyasını yönetici başına çalıştırmakla ilgili değil, başka bir programın toplu işten nasıl yükseltileceğini ...

Bir exe için bir toplu iş dosyası "sarıcı" var. Aynı "kök dosya adına", ancak alternatif uzantılara sahiptirler. Yönetici olarak exe başlatmak ve aşağıdaki bir satır powershell çağırma ile komut dosyası içeren bir çalışma dizini ayarlamak mümkün :

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

Daha fazla bilgi

Uygulayabileceğiniz birçok ek Start-Processseçenek de var! Kontrol edin: https://docs.microsoft.com/tr-tr/powershell/module/microsoft.powershell.management/start-process?view=powershell-6

@Öneki kullandığımı unutmayın . Bu @echo offbir satır için eşdeğerdir . Ben %~n0burada toplu komut dosyasının "kök adı" almak için kullanın , sonra .exebitişik ikili işaret etmek için bitiştirin. Kullanımı %~dp0, toplu işin bulunduğu dizinin tam yolunu sağlar. Ve tabii ki, parametre yükselmesine sağlar .-Verb RunAs


4

Bunun OP için bir çözüm olmadığını biliyorum, ama burada başka birçok kullanım vakası olduğundan eminim, paylaşacağımı düşündüm.

Bu cevaplarda tüm kod örnekleri ile ilgili sorunlar yaşadım ama sonra buldum: http://www.robotronic.de/runasspcEn.html

Sadece yönetici olarak çalışmanıza izin vermez, aynı zamanda kurcalanmadığından emin olmak için dosyayı kontrol eder ve gerekli bilgileri güvenli bir şekilde saklar. Nasıl kullanılacağını anlamanın en belirgin aracı olmadığını itiraf edeceğim, ancak kod yazanlar için yeterince basit olmalı.


3

@echo offve titlebu koddan önce gelebilir:

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

Aşağıdakiler hakkında endişelenmenize gerek yoksa, diğer yanıtların çoğu aşırıya kaçıyor:

  • Parametreler
  • Çalışma Dizini ( cd %~dp0toplu iş dosyasını içeren dizine değişecektir)

3
@echo off 
Net session >nul 2>&1 || (PowerShell start -verb runas '%~0' &exit /b)
Echo Administrative privileges have been got. & pause

Yukarıdaki Windows 10 Sürüm 1903'te çalışıyor


1

Bu komut dosyasıyla kendisiyle yeni bir komut istemi açarken sorun yaşadığımdan, sonsuz döngüde (Win 7 Pro kullanarak) başka bir yaklaşım denemenizi öneririm: Toplu iş dosyamı nasıl otomatik olarak yükseltebilirim, böylece istekleri Gerekirse UAC yönetici hakları?

Dikkatli olun, bunu bir düzenlemede belirtildiği gibi komut dosyasının sonuna eklemelisiniz, böylece ayrıcalıklar yükseltildikten sonra komut dosyası dizinine dönersiniz: cd / d% ~ dp0


Bu soruya cevabımı kontrol et. Tüm bu sorunları halleder.
cyberponk

1

Toster-cx ve bu sayfadaki diğer ilginç yayınların gönderilerine dayanarak, sorunumu nasıl yapılandıracağım ve çözeceğime dair bir fikrim var. Disk Temizleme yardımcı programının her hafta iki saat Pazartesi ve Perşembe günleri öğle saatlerinde (2 pm) çalışmasını diliyorum benzer bir sorun vardı. Ancak, bu hakların yükseltilmesini gerektiriyordu.

Benim gibi diğer yeni başlayanlara yardımcı olabilecek toplu iş dosyasını paylaşma -

@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

Bu forum ve Rems POST için burada çok teşekkürler [ https://www.petri.com/forums/forum/windows-scripting/general-scripting/32313-schtasks-exe-need-to-pass-parameters-to-script ] [1]

Görevi, görevi zamanlarken isteğe bağlı argümanın yapılandırılmasına yardımcı oldu.


1

Bu yazının ayrıca aşağıdaki kodu içeren ss64.com'da da bağlanan FSUTIL sorgusu vardır:

@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

FSUTIL olduğu sürece güvenilir bir alternatiftir.


0

Bir toplu iş dosyasından yönetici hakları isteyemezsiniz, ancak% temp% içinde bir windows komut dosyası ana bilgisayar komut dosyası yazabilir ve bunu çalıştırabilirsiniz (ve bu da toplu işinizi yönetici olarak yürütür) Kabuk'ta ShellExecute yöntemini çağırmak istiyorsunuz. Fiil olarak "runas" içeren uygulama nesnesi


0

mshtaYönetici haklarını istemek için kullanın :

@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

Veya powershell kullanarak:

powershell -c Start-Process "%~nx0" -Verb runas

-6

runas komutunu kullanın. Ancak, bir .bat dosyasını kolayca e-postayla gönderebileceğinizi sanmıyorum.


7
Bu cevap yanlış. runasKomut yükselmesine provoke etmek kullanılamaz.
Bill_Stewart
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.