Gerektiğinde UAC yönetici haklarından istemek için toplu iş dosyamı otomatik olarak nasıl yükseltebilirim?


209

Toplu iş dosyamın yalnızca yükseltilmiş olarak çalışmasını istiyorum. Yükseltilmezse, kullanıcının toplu işi yükseltilmiş olarak yeniden başlatma seçeneği sağlayın.

Bir sistem değişkeni ayarlamak, iki dosyayı bir Program Files konumuna kopyalamak ve bir sürücü yükleyici başlatmak için bir toplu iş dosyası yazıyorum . Bir Windows 7 / Windows Vista kullanıcısı ( UAC etkinleştirilmiş ve yerel bir yönetici olsalar bile) sağ tıklamadan ve "Yönetici Olarak Çalıştır" ı seçmeden çalıştırırsa, iki dosyayı kopyalayıp sistem değişkenini yazma 'Erişim Reddedildi' .

Kullanıcı aslında bir yönetici ise toplu olarak yükseltilmiş olarak otomatik olarak yeniden başlatmak için bir komut kullanmak istiyorum. Aksi takdirde, yönetici değilse, toplu iş dosyasını çalıştırmak için yönetici ayrıcalıklarına ihtiyaç duyduklarını söylemek istiyorum. Ben kullanıyorum xcopy dosyaları kopyalamak için ve REG ADD sistem değişkeni yazmak için. Olası Windows XP makineleriyle uğraşmak için bu komutları kullanıyorum. Bu konuda benzer sorular buldum, ancak bir toplu iş dosyasını yükseltilmiş olarak yeniden başlatmayla ilgili hiçbir şey yok.


2
Ne gönderdiğime göz atın - herhangi bir harici araca ihtiyacınız yoktur, komut dosyası yönetici haklarını otomatik olarak kontrol eder ve gerekirse otomatik olarak yükselir.
Matt

1
Lütfen Matt'in cevabının işaretli olup olmayacağını düşünün. Bana öyle geliyor.
akauppi


Lütfen gönderdiğim toplu komut dosyasının yorum bölümündeki yeni Windows 10 ipuçlarını göz önünde bulundurun .
Matt

4
Gönderen cmd: @powershell Start-Process cmd -Verb runas. Powershell'den sadece düş @powershell. Bu cmd'yi yükseltilmiş haklarla başlar.
BrunoLM

Yanıtlar:


20

Sen ile komut çağrı kendisi olabilir psexec 'ın -hseçeneği yükselmiş çalıştırmak için.

Zaten yükseltilmiş olarak çalışıp çalışmadığını nasıl tespit edeceğinizden emin değilim ... belki sadece bir erişim reddedildi hatası varsa yükseltilmiş izinlerle yeniden deneyin?

Veya, sadece komutları alabilir xcopyve reg.exeher zaman çalıştırılabilir psexec -h, ancak her seferinde şifrelerini girmeleri gerekiyorsa (veya şifreyi betiğe eklediyseniz güvensizdir) son kullanıcı için rahatsız edici olacaktır ...


10
Yanıt için teşekkürler. Ne yazık ki, stoktaki Windows Vista / 7 araçları dışında bir şey kullanabileceğimi sanmıyorum çünkü bu ofisimin dışındaki müşterilere gidecek. PSExec'i yasal olarak dağıtabileceğimi sanmıyorum.
PDixon724

2
Evet, bence bu konuda haklısın - PSExec artık bir Microsoft aracı olmasına rağmen (Sysinternals adamlarını satın aldıkları için!) EULA dağıtımını yasaklıyor :(
ewall

2
Bence seçeneklerim oldukça sınırlı. Eğer VB kodlamak için nasıl bilseydim, ben bir yönetici manifest ile bir exe yapabilirdi, ama nereden başlayacağımı bile bilemezdim. Sanırım Windows Vista / 7 çalıştırıyorlarsa, toplu işin başında yönetici olarak çalışması için uyaracağım. Hepinize teşekkürler.
PDixon724

1
Serbestçe yeniden dağıtılabilen, entegrasyonu ve öğrenmesi kolay olabilecek başka bir üçüncü taraf aracı AutoIt ; bu sayfa komut dosyasının yükseltilmiş ayrıcalıkları nasıl istediğini gösterir.
ewall

4
psexec -hçalışmıyor: 'PSEXESVC hizmeti yüklenemedi: Erişim reddedildi.'. Psexec'i çalıştırmak için yönetici haklarına sahip olmanız gerekir.
Nicolas

319

Harici bir araç kullanmaya gerek kalmadan kolay bir yol vardır - Windows 7, 8, 8.1 ve 10 ile iyi çalışır ve geriye dönük olarak da uyumludur (Windows XP'de UAC yoktur, bu nedenle yükseklik gerekmez - betiğin ilerlemesi durumunda).

Bu kodu göz atın (Ben iş parçacığında yayınlanan NIronwolf tarafından kod esinlenerek Toplu Dosya - "Erişim Engellendi" Windows 7? ), Ama ben geliştirdim - benim sürümde oluşturulan ve kaldırıldı herhangi bir dizin yok yönetici ayrıcalıklarını kontrol edin):

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

Komut dosyası, NET FILEyönetici ayrıcalığı gerektiren errorlevel 1durumdan yararlanır ve sahip değilseniz geri döner . Yükseltme, ayrıcalıklar elde etmek için toplu iş dosyasını yeniden başlatan bir komut dosyası oluşturarak elde edilir. Bu, Windows'un UAC iletişim kutusunu göstermesine neden olur ve yönetici hesabı ve parola ister.

Windows 7, 8, 8.1, 10 ve Windows XP ile test ettim - herkes için iyi çalışıyor. Bunun avantajı, başlangıç ​​noktasından sonra, örneğin bir Windows hizmetini hata ayıklama amacıyla yeniden yüklemek ve yeniden çalıştırmak istiyorsanız (mypackage.msi dosyasının bir hizmet yükleyici paketi olduğu varsayılırsa) sistem yöneticisi ayrıcalıkları gerektiren her şeyi yerleştirebilirsiniz. :

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

Bu ayrıcalık yükseltme betiği olmadan, UAC size yönetici kullanıcı ve şifrenizi üç kez soracaktır - şimdi sizden yalnızca bir kez başlangıçta ve sadece gerekirse istenir.


Komut dosyanızın yalnızca bir hata mesajı göstermesi ve otomatik yükseltme yerine yönetici ayrıcalıkları yoksa çıkması gerekiyorsa , bu daha da basittir: Komut dosyanızın başına aşağıdakileri ekleyerek bunu elde edebilirsiniz:

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

Bu şekilde, kullanıcının sağ tıklaması ve "Yönetici olarak çalıştır" ı seçmesi gerekir . Komut dosyası, REMyönetici haklarını algılarsa ifadeden sonra devam eder, aksi takdirde bir hata ile çıkılır. Gereksinim duymuyorsanız PAUSE, kaldırın. Önemli: NET FILE [...] EXIT /D) aynı satırda olmalıdır. Daha iyi okunabilirlik için burada birden fazla satırda görüntülenir!


Bazı makinelerde, yukarıdaki yeni sürümde çözülen sorunlarla karşılaştım. Birincisi farklı çift tırnak işleminden kaynaklanmıştı ve diğer sorun, UAC'nin bir Windows 7 makinesinde devre dışı bırakılması (en düşük seviyeye ayarlanmış) nedeniyle, betiğin kendisini tekrar tekrar çağırmasıydı.

Ben şimdi tırnak tırnak yolunda sıyırma ve daha sonra yeniden ekleyerek düzeltildi ve komut dosyası yükseltilmiş haklarla yeniden başlatıldığında eklenen ekstra bir parametre ekledim.

Çift tırnak işaretleri aşağıdakiler tarafından kaldırılır (ayrıntılar buradadır ):

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

Ardından yolu kullanarak erişebilirsiniz !batchPath!. Herhangi bir çift tırnak içermez, bu yüzden "!batchPath!"komut dosyasında daha sonra söylemek güvenlidir .

Çizgi

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

betiğin VBScript betiği tarafından hakları yükseltmek için çağrılıp çağrılmadığını kontrol eder , böylece sonsuz özyinelemeleri önler. Kullanarak parametreyi kaldırır shift.


Güncelleme:

  • Kayıt zorunda kalmamak için .vbsuzantı , Windows 10 , ben çizgiyi yerini almıştır
    "%temp%\OEgetPrivileges.vbs"
    tarafından
    "%SystemRoot%\System32\WScript.exe" "%temp%\OEgetPrivileges.vbs"
    komut yukarıdaki; Ayrıca cd /d %~dp0Stephen (ayrı cevap) ve Tomáš Zato (yorum) tarafından önerildiği gibi komut dizini varsayılan olarak ayarlamak için eklendi.

  • Komut dosyası, kendisine iletilen komut satırı parametrelerini onurlandırıyor. Gözlemler ve ilhamlar için jxmallet, TanisDLJ ve Peter Mortensen'e teşekkürler.

  • Artjom B.'nin ipucu göre, bunu analiz ve yerini SHIFTtarafından SHIFT /1dosya adını korur, hangi %0parametre

  • Temizlemek del "%temp%\OEgetPrivileges_%batchName%.vbs"için :gotPrivilegesbölüme eklendi ( mlt önerildiği gibi). Eklenen %batchName%Eğer paralel olarak farklı toplu çalıştırırsanız etkisini önlemek için. Yalnızca dosya adını ayıklayan forgibi gelişmiş dize işlevlerinden yararlanabilmek için kullanmanız gerektiğini unutmayın %%~nk.

  • Optimize edilmiş komut dosyası yapısı, iyileştirmeler ( vbsGetPrivilegesartık her yerde referans verilen ve dosyanın yolunu veya adını kolayca değiştirmeye izin veren değişken eklendi , yalnızca .vbstoplu işin yükseltilmesi gerekiyorsa dosyayı silin )

  • Bazı durumlarda, yükseklik için farklı bir çağrı sözdizimi gerekiyordu. Komut dosyası çalışmazsa, aşağıdaki parametreleri kontrol edin:
    set cmdInvoke=0
    set winSysFolder=System32
    1. parametreyi değiştirin set cmdInvoke=1ve sorunun giderilip giderilmediğini kontrol edin. cmd.exeYüksekliği gerçekleştiren komut dosyasına eklenir .
    Veya 2. parametreyi değiştirmeye çalışın winSysFolder=Sysnative, bu 64 bit sistemlerde yardımcı olabilir (ancak çoğu zaman gerekli değildir). (ADBailey bunu bildirdi). "Sysnative" yalnızca 32-bit komut dosyası ana bilgisayarından 64-bit uygulamaları başlatmak için gereklidir (örneğin, bir Visual Studio oluşturma işlemi veya başka bir 32-bit uygulamadan komut dosyası çağırma).

  • Parametrelerin nasıl yorumlandığını daha açık hale getirmek için, şimdi onu gösteriyorum P1=value1 P2=value2 ... P9=value9. Bu, özellikle yollar gibi parametreleri çift tırnak içine almanız gerektiğinde kullanışlıdır "C:\Program Files".

  • VBS komut dosyasında hata ayıklamak istiyorsanız, //Xparametreyi burada önerildiği gibi ilk parametre olarak WScript.exe dosyasına ekleyebilirsiniz (CScript.exe için açıklanmıştır, ancak WScript.exe için de çalışır).

Kullanışlı bağlantılar:


9
Harika cevap, bazı durumlarda açıkça gerekli olan bir şeyi yapmak için her şeyi yapmanız gerektiğine rağmen beni biraz şaşırtıyor.
jcoder

50
Aslında, ELEVATE gibi bir komut Windows toplu iş dilinde açıkça eksik.
Matt

2
Belki de daha karmaşık şeyler için onaylanmış komut dosyası dili gibi görünen powershell ile daha kolay, ama şimdiye kadar öğrenmek için hiç uğraşmadım :(
jcoder

1
Powershell içindeki sözdizimi tamamen farklıdır (fiil-isim sözdizimi), ancak .NET derlemelerini kolayca çağırmanıza izin verir. Ancak bununla başa çıkmak biraz daha zordur (senaryoları imzalamak vb.).
Matt

2
@Matt Yanıtınızda bu reddedilen düzenlemenin arkasında bir gerçek olup olmadığını kontrol edebilir misiniz ?
Artjom B.

41

Jcoder ve Matt'in belirttiği gibi, PowerShell bunu kolaylaştırdı ve hatta yeni bir komut dosyası oluşturmadan toplu komut dosyasına gömülebilir.

Matt'in senaryosunu değiştirdim:

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

3
Doğru, PowerShell yüklüyse, toplu iş dosyasını yükseklikle çalıştırmak için kullanabilirsiniz (kod snippet'i için teşekkür ederiz!). Ve evet, etikete gerek yok. İpuçları için teşekkürler, +1 değerinde ... :-)
Matt

2
Cmd den çağrıldığında Powershell.exe -verb runas seçeneği yoktur. Zaten PowerShell'deyseniz mevcuttur.
Adil Hindistan

1
Bu çözümü gerçekten seviyorum, benim için harika çalışıyor. Windows 8.1'de çalışması için şunu aldım: gotPrivileges etiketi.
ShaunO

Bu toplu iş dosyası bir UNC yolunda uzaksa bir sorunla karşılaşıyorum.
Ryan Beesley

Başlangıçta değişiklik dizini ekledim, akışı basitleştirdim ve biraz temizledim. İş dir, işlemlerde güvenlik nedeni nedeniyle WorkingDirectoryparametre ile değiştirilemezStart-Processrunas
ceztko

28

Matt'in mükemmel yanıtını kullanıyorum, ancak yükseltilmiş komut dosyalarını çalıştırırken Windows 7 ve Windows 8 sistemlerim arasında bir fark görüyorum.

Komut dosyası Windows 8'de yükseltildiğinde, geçerli dizin olarak ayarlanır C:\Windows\system32. Neyse ki, geçerli dizini geçerli komut dosyasının yoluna değiştirerek kolay bir çözüm vardır:

cd /d %~dp0

Not: cd /dSürücü harfinin de değiştiğinden emin olmak için kullanın .

Bunu test etmek için aşağıdakileri bir komut dosyasına kopyalayabilirsiniz. Aynı sonucu görmek için her iki sürümde de normal şekilde çalıştırın. Yönetici olarak çalıştırın ve Windows 8'deki farkı görün:

@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

1
İyi ipucu, Stephen. Bu yüzden komut dosyası cd %~dp0geçerli yolunu korumak için bitmelidir (Win7'de de çalıştığını varsayıyorum, bu yüzden aynı komut yalnızca Win8 + için gerekli olmasına rağmen kullanılabilir). Bunun için +1!
Matt

2
Bu, Windows 7 çalıştıran sistemimde de gerekliydi.
meh-uk

1
ya da pushd %~dp0bunun yerine ... neden? çünküpopd
Jaroslav Záruba

27

Bunu şu şekilde yaparım:

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

Bu şekilde basittir ve yalnızca Windows varsayılan komutlarını kullanır. Toplu iş dosyasını yeniden dağıtmanız gerekiyorsa harika.

CD /d %~dp0Geçerli dizini dosyanın geçerli dizinine ayarlar (zaten değilse, /dseçenek sayesinde dosyanın bulunduğu sürücüye bakılmaksızın ).

%~nx0 Uzantılı geçerli dosya adını döndürür (Uzantıyı eklemezseniz ve klasörde aynı ada sahip bir exe varsa, exe'yi çağıracaktır).

Bu yazıda o kadar çok cevap var ki cevabımın görülüp görülmeyeceğini bile bilmiyorum.

Her neyse, bu yolu diğer yanıtlarda önerilen diğer çözümlerden daha basit buluyorum, umarım birine yardımcı olur.


4
cd% ~ dp0, Ağ sürücülerinde çalışmaz, bunun yerine% ~ dp0 pushd kullanın.
Stavm

1
Bu cevabın basitliğini seviyorum. Ve son olarak Jscript kullanmak için bir sebep!
Joe Coder

1
Sihirli! Çok teşekkür ederim.
Daniele Orlando

1
@ Kurt Sadece seni yanlış anladığımı anlamak için büyük bir cevap yazdım ... Şimdi ne demek istediğini anladım. Bunu içerecek şekilde düzenleyeceğim /d. Teşekkür ederim dostum :) (PS: Piyanist de burada!)
Matheus Rocha

1
Bu harika çalışıyor, ancak cdkomutu başlangıca taşımak iyi bir fikir olabilir (bu, yolun yükseltilmiş komut dosyası için de kullanılabilir olmasını sağlar - aksi takdirde yükseltilmiş komut dosyası yalnızca system32'den çalışır). Ayrıca net komutunu çıktısını gizlemek için net session >nul 2>&1
nul'a

23

Matt'in harika bir cevabı var, ama senaryoya geçirilen argümanları ortadan kaldırıyor. İşte benim argümanları tutan modifikasyonum. Stephen'ın Windows 8'deki çalışma dizini sorununa yönelik düzeltmesini de dahil ettim.

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

1
Bu yararlı bir cevap. Ancak, ECHO UAC.ShellExecute....çizgi, "batchArgs!"değişkeni genişletmez. Kullanın "!batchArgs!". Düzenlemem reddedildi, bu yüzden yorum yapıyorum.
sinek soğan

1
@fliedonion iyi tespit! Düzenlemenizin neden reddedildiğinden emin değilim, çünkü kesinlikle bir yazım hatasıydı ve düzeltmeniz işe yarıyor. Değişikliği kendim yaptım ve Win 8.1'de test ettim. Şimdi bu kodu kullandığım tüm komut dosyalarını bulmak için ....
jxmallett

2
Komut dosyası test.bat "a thing"veya gibi alıntılanan bağımsız değişkenler kullanılırken bozuldu "test script.bat" arg1 arg2. Şimdi hepsi düzeltildi.
jxmallett

Bunu kırmayı başardım (benim hatamdan dolayı: eşlenen ağ sürücüsünden komut dosyası çalıştırılıyor, çünkü yönetici ve normal kullanıcı aynı haritalamaya sahip değil). Yine de: çıktıyı görmenin bir yolu var mı? Benim için .vbs dosyasını bulup / c'yi a / K olarak değiştirmek zorunda kaldım ve sonra el ile gördüm.
Andreas Reiff

21

Değilse yükseltilmiş komut dosyasını yeniden başlatmak için PowerShell kullanın. Bu satırları senaryonuzun en üstüne koyun.

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

@ Matt'in cevabından 'net name' yöntemini kopyaladım. Cevabı çok daha iyi belgelenmiştir ve hata mesajları ve benzeri vardır. Bu, PowerShell'in zaten Windows 7 ve üzeri sürümlerde yüklü ve kullanılabilir olması avantajına sahiptir. Geçici VBScript (* .vbs) dosyası yoktur ve araçları indirmenize gerek yoktur.

PowerShell yürütme izinleriniz kilitli olmadığı sürece bu yöntem herhangi bir yapılandırma veya kurulum olmadan çalışmalıdır.


bir liste olarak ele alınmak için tırnaklarla çevrelenmiş beyaz boşluklu ayrılmış argümanlar bir liste sağlarken, /c %~fnx0 %*'bölüm birinciden başka her parçayı terk ediyor gibi görünüyor. Örneğin, test.bat "arg1 arg2 arg3"sadece
arg1'den

Ne olursa olsun, Start-Process argüman listesindeki tüm çift tırnak işaretlerini kaldırır ..
Nicolas Mommaerts

Benim için çalışıyor! Bunu için kullanıyorum netsh int set int %wifiname% Enable/Disable.
Marslo

2
Yukarıdaki Nicolas Mommaerts ile aynı problemi yaşadım. Neden çalıştığını anlamıyorum (en iyi düzeltme), ancak aşağıdaki gibi olması gerektiği gibi çalışır (sonunda tüm ekstra tırnak notları not edin): net file 1>nul 2>nul && goto :run || powershell -ex unrestricted -Command "Start-Process -Verb RunAs -FilePath '%comspec%' -ArgumentList '/c ""%~fnx0""""'"
depremler

Başka bir sorun (rahatsızlık) sunucu hizmeti çalışmıyorsa komut dosyası duraklar (kullanıcı girişi için bekler) (ben nedenlerle devre dışı var). Genellikle HOSTS dosya konumuna yazmaya çalışarak yönetici izinleri için test , ancak etkin windows hizmetlerine güvenmek veya dosya yazma girişimleri yerine powershell komutu -Verb runas çağırmak için belki de daha iyidir .
script'n'code

15

Süper gizli ayarı bazı programlar için __COMPAT_LAYERçevre değişkeni RunAsInvoker çalışacaktır olmadýný kontrol edin bu:

set "__COMPAT_LAYER=RunAsInvoker"
start regedit.exe

Buna rağmen, kullanıcıya yönetici izinleri olmadan devam etmesini isteyen hiçbir UAC olmayacaktır.


1
Microsoft sitesine bağlantı artık çalışmadı, bu yüzden onu archive.org'daki içeriğe değiştirdim. Herkes Microsoft'un sitesindeki içeriğe çalışan bir bağlantı bulabilir, ancak her şeye rağmen, lütfen bunu güncelle
RockPaperLizard

1
o hâlâ orta bütünlüğü değil yükseltilmiş böylece düzenlemek HKLM yapamam regedit. Sadece UAC'yi atladı.
HackingAddict1337

5

Ben betiğin başında yapıştırdım:

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

2
Senaryonuzda arg işlemeyi seviyorum. Ama notcacls Windows 7 ve daha yeni pencereler sürümlerinde kaldırılmıştır.
Matt

Fsutil kirli olduğunu daha iyi
Wolf

1
Satırın pushd "%CD%"geçerli çalışma dizinini kaydettiğini ve geçerli çalışma dizinine değiştiğini biliyor musunuz ?
Wolf

3

Yazdığım gsudo, bir sudopencereler için de yükseltip o: Geçerli konsolda bir kimlik önbelleği ile (hiçbir bağlam yeni pencerede geçiş), (UAC pop-up azaltılmış) ve aynı zamanda yükseltir PowerShell komutları .

İsterseniz yönetici ayrıcalıkları veya tüm toplu işlem gerektiren komutların yükseltilmesine izin verir. Sadece başagsudo yükseltilmesi gereken herhangi bir şeyden önce .

Gsudo kullanarak kendisini yükselten örnek toplu iş dosyası:

DÜZENLEME: Herhangi bir pencere dili ile çalışan ve whoami sorunlarını önleyen yeni bir astar sürümü :

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

Alternatif (orijinal sürüm):

@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

Yüklemek:

Gsudo'yu çalışırken görün: gsudo demosu


Güzel. Teşekkürler. Hangi Windows sürümlerinde çalışır?
RockPaperLizard

Test paketi Server 2019'da çalışır ve yerel geliştirici kutum Windows 10 1909'dur. Üzgünüm, diğer eski işletim sistemleriyle uyumluluğu test etmedim.
Gerardo Grignoli

Teşekkürler Gerardo. Herkes Windows'un diğer sürümlerinde denerse, lütfen sonuçlarınızı gönderin.
RockPaperLizard

Az önce Windows 8.1'de gsudo v0.7'yi test ettim ve çalıştım. Oraya kurmak önemsiz değil .Net Framework 4.6. Neyse ki choco install dotnet4.6.2elde edilmesi zor bağımlılıklar getirdi. Ardından , yanlış bir istem (kırmızı keskin yerine kaçış sırası karakterleri) göstermeyle ilgili gsudo config Prompt "$p# "bir sorun düzeltildi ConHost. @RockPaperLizard
Gerardo Grignoli

Çok teşekkürler Gerardo. 4.6'dan önce .Net Framework'ün herhangi bir sürümüyle çalışmak için yeniden derlenebilir mi, yoksa 4.6'ya özgü bazı işlevlere mi bağlı?
RockPaperLizard

2

Bu soruya doğrudan uygulanabilir olmasa da, kullanıcı için bazı bilgiler istediğinden, görev zamanlayıcıdan yükseltilmiş .bat dosyamı çalıştırmak istediğimde google beni buraya getirdi.

En basit yaklaşım .bat dosyasına bir kısayol oluşturmaktı, çünkü bir kısayol için Run as administratordoğrudan gelişmiş özelliklerden ayarlayabilirsiniz .

Kısayolu görev zamanlayıcıdan çalıştırdığınızda, yükseltilmiş .bat dosyasını çalıştırır.


0

Powershell kullanma.

Cmd dosyası uzunsa, yükseklik istemek için bir ilk kullanın ve sonra gerçek işi yapan birini arayın.

Komut dosyası basit bir komutsa, her şey bir cmd dosyasına sığabilir. Komut dosyasını dosya yoluna eklemeyi unutmayın.

Şablon:

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

Örnek 1:

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

Örnek 2:

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

0

Bunu dene:

@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

Bu toplu iş dosyası hakkında bilgiye ihtiyacınız varsa, HTML / JS / CSS Snippet'ini çalıştırın:

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>


0

Argümanları iletmeniz gerekmiyorsa, burada tek satır uzunluğunda küçük bir UAC komut dosyası var. Bu, en çok oy verilen cevaptaki yükseklik betiği ile benzer bir şey yapar, ancak zehir karakterlerinin her olası kombinasyonunu işleyen kusursuz bir yol olmadığı için argümanları iletmez.

@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

-3

Aşağıdaki çözüm temiz ve mükemmel çalışıyor.

  1. Elevate zip dosyasını https://www.winability.com/download/Elevate.zip adresinden indirin.

  2. Zip içinde iki dosya bulmalısınız: Elevate.exe ve Elevate64.exe. (Sonuncusu yerel 64 bit derlemedir, normal 32 bit sürüm olmasına rağmen, Elevate.exe'nin Windows'un 32 ve 64 bit sürümleriyle iyi çalışmasını gerektirir)

  3. Elevate.exe dosyasını Windows'un her zaman bulabileceği bir klasöre kopyalayın (C: / Windows gibi). Veya bat dosyanızı saklamayı planladığınız klasöre kopyalayabilirsiniz.

  4. Bir toplu iş dosyasında kullanmak için, yükselt komutuyla yönetici olarak yürütmek istediğiniz komutu aşağıdaki gibi eklemeniz yeterlidir:

 elevate net start service ...

2
Bu komut yalnızca kullanıcıya bu komutun yürütülmesine izin verilip verilmediğini soran bir iletişim penceresi açar. Bu nedenle, bir toplu iş dosyasında, kullanıcı etkileşimleri OLMADAN ne çalıştırılması gerektiğini bu komutu kullanamazsınız.
Radon8472

Kullanıcı etkileşimi OLMADAN yükseltmek mümkün olsaydı, büyük bir güvenlik açığı olurdu, değil mi? Her virüs, kullanıcı onayı olmadan kendini yükseltmek için bu yöntemi kullanmaya başlar.
Andrei Belogortseff
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.