मैं अपनी बैच फ़ाइल को ऑटो-एलिवेट कैसे कर सकता हूं, ताकि आवश्यकता पड़ने पर यह यूएसी प्रशासक के अधिकारों से अनुरोध करे?


209

मैं चाहता हूं कि मेरा बैच फ़ाइल केवल ऊंचा चले। यदि ऊंचा नहीं किया जाता है, तो उपयोगकर्ता को बैच के रूप में स्थानांतरित करने के लिए एक विकल्प प्रदान करें।

मैं सिस्टम चर सेट करने के लिए एक बैच फ़ाइल लिख रहा हूं, दो फाइलों को प्रोग्राम फाइलों के स्थान पर कॉपी करें , और एक ड्राइवर इंस्टॉलर शुरू करें। अगर एक विंडोज 7 / विंडोज विस्टा यूजर ( UAC) सक्षम और यहां तक ​​कि अगर वे एक स्थानीय व्यवस्थापक हैं) तो इसे राइट-क्लिक के बिना चलाता है और "रन के रूप में प्रशासक" का चयन करता है, तो उन्हें दो फ़ाइलों की प्रतिलिपि बनाने और सिस्टम चर लिखने के लिए 'एक्सेस अस्वीकृत' मिलेगा ।

यदि उपयोगकर्ता वास्तव में एक व्यवस्थापक है तो मैं बैच को स्वचालित रूप से ऊंचा करने के लिए एक कमांड का उपयोग करना चाहूंगा। अन्यथा, यदि वे एक व्यवस्थापक नहीं हैं, तो मैं उन्हें बताना चाहता हूं कि बैच फ़ाइल को चलाने के लिए उन्हें व्यवस्थापक विशेषाधिकारों की आवश्यकता है। मैं फ़ाइलों को कॉपी करने के लिए xcopy का उपयोग कर रहा हूं और सिस्टम चर लिखने के लिए REG ADD । मैं उन आदेशों का उपयोग संभव विंडोज़ एक्सपी मशीनों से निपटने के लिए कर रहा हूं। मुझे इस विषय पर इसी तरह के प्रश्न मिले हैं, लेकिन कुछ भी नहीं जो एक बैच फ़ाइल को ऊंचा करने से संबंधित है।


2
जांचें कि मैंने क्या पोस्ट किया है - आपको किसी बाहरी उपकरण की आवश्यकता नहीं है, यदि आवश्यक हो तो स्क्रिप्ट स्वचालित रूप से व्यवस्थापक अधिकारों और स्वतः-ऊंचाई के लिए जांच करती है।
मैट

1
कृपया विचार करें कि क्या मैट का उत्तर टिक जाएगा? मुझे ऐसा लगता है।
अंकुप्पी


कृपया मेरे द्वारा पोस्ट की गई बैच स्क्रिप्ट के टिप्पणी अनुभाग में नए विंडोज 10 संकेत के बारे में सोचें।
मैट

4
सीएमडी से @powershell Start-Process cmd -Verb runas:। पॉवरशेल से सिर्फ ड्रॉप @powershell। यह ऊंचे अधिकारों के साथ cmd शुरू होता है।
ब्रूनोएलएम

जवाबों:


20

आप स्क्रिप्ट को खुद को उन्नत बनाने के लिए psexec के -hविकल्प के साथ कॉल कर सकते हैं ।

मुझे यकीन नहीं है कि आप कैसे पता लगाएंगे कि यह पहले से ही ऊंचा चल रहा है या नहीं ... हो सकता है कि एलिवेटेड परमिट के साथ फिर से प्रयास करें यदि कोई एक्सेस अस्वीकृत त्रुटि है?

या, आपके पास बस के लिए आदेश हो सकते हैं xcopyऔर reg.exeहमेशा साथ चलते हैं psexec -h, लेकिन यह अंत-उपयोगकर्ता के लिए कष्टप्रद होगा यदि उन्हें हर बार अपना पासवर्ड इनपुट करने की आवश्यकता होती है (या यदि आपने स्क्रिप्ट में पासवर्ड शामिल किया है तो असुरक्षित है ...)


10
जवाब देने के लिए धन्यवाद। दुर्भाग्य से, मुझे नहीं लगता कि मैं विंडोज विस्टा / 7 टूल के बाहर कुछ भी उपयोग कर सकता हूं क्योंकि यह मेरे कार्यालय के बाहर के ग्राहकों के लिए होगा। मुझे नहीं लगता कि मैं कानूनी रूप से PSExec वितरित कर सकता हूं।
PDixon724

2
हाँ, मुझे लगता है कि आप इसके बारे में सही हैं - भले ही PSExec अब एक Microsoft उपकरण है (क्योंकि उन्होंने Sysinternals लोग खरीदे हैं!) EULA वितरण को मना करता है :(
evel

2
मुझे लगता है कि मेरे विकल्प बहुत सीमित हैं। अगर मुझे पता था कि वीबी में कोड कैसे किया जाता है, तो मैं इसे एक एक्सपट्र्स में प्रकट कर सकता हूं, लेकिन मुझे यह भी नहीं पता होगा कि कहां से शुरू किया जाए। मुझे लगता है कि मैं बैच की शुरुआत में व्यवस्थापक के रूप में चलाने के लिए चेतावनी दूंगा अगर वे विंडोज विस्टा / 7 चला रहे हैं। सबको शुक्रीया।
PDixon724

1
एक और 3-पक्ष टूल में स्वतंत्र रूप से पुनर्वितरण और एकीकृत करने के लिए आसान हो सकता है और सीख सकते है AutoIt ; यह पृष्ठ दर्शाता है कि स्क्रिप्ट उन्नत विशेषाधिकार का अनुरोध कैसे करती है।
18/07

4
psexec -hकाम नहीं करता: 'PSEXESVC सेवा स्थापित नहीं कर सका: प्रवेश निषेध है।' आपको पहले से ही psexec चलाने के लिए प्रशासक के अधिकार की आवश्यकता है।
निकोलस

319

बाहरी उपकरण का उपयोग करने की आवश्यकता के बिना एक आसान तरीका है - यह विंडोज 7, 8, 8.1 और 10 के साथ ठीक चलता है और पीछे की ओर भी संगत है (विंडोज एक्सपी में कोई यूएसी नहीं है, इस प्रकार ऊंचाई की आवश्यकता नहीं है - उस में मामला स्क्रिप्ट अभी आगे बढ़ता है)।

इस कोड को देखें (मैं थ्रेड बैच फ़ाइल में पोस्ट किए गए NIronwolf द्वारा कोड से प्रेरित था - "एक्सेस डिनीड ऑन ऑन विंडोज 7? ), लेकिन मैंने इसे सुधार लिया है - मेरे संस्करण में कोई निर्देशिका नहीं बनाई गई है और हटा दी गई है। व्यवस्थापक विशेषाधिकारों के लिए जाँच करें):

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

स्क्रिप्ट इस तथ्य का लाभ उठाती है कि NET FILEव्यवस्थापक विशेषाधिकार की आवश्यकता होती है और errorlevel 1यदि आपके पास नहीं है, तो रिटर्न मिलता है। ऊंचाई एक स्क्रिप्ट बनाकर हासिल की जाती है जो विशेषाधिकारों को प्राप्त करने के लिए बैच फ़ाइल को फिर से लॉन्च करती है। यह विंडोज़ को यूएसी संवाद प्रस्तुत करने का कारण बनता है और आपको व्यवस्थापक खाते और पासवर्ड के लिए पूछता है।

मैंने इसे विंडोज 7, 8, 8.1, 10 और विंडोज एक्सपी के साथ परीक्षण किया है - यह सभी के लिए ठीक काम करता है। लाभ यह है कि, स्टार्ट पॉइंट के बाद आप सिस्टम प्रशासक विशेषाधिकारों की आवश्यकता के लिए कुछ भी रख सकते हैं, उदाहरण के लिए, यदि आप डीबगिंग उद्देश्यों के लिए एक विंडोज सेवा को फिर से स्थापित करने और फिर से चलाने का इरादा रखते हैं (मान लिया कि mypackage.msi एक सर्विस इंस्टॉलर पैकेज है) :

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

इस विशेषाधिकार प्राप्त स्क्रिप्ट के बिना, UAC आपसे आपके व्यवस्थापक उपयोगकर्ता और पासवर्ड के लिए तीन बार पूछेगा - अब आपसे केवल एक बार शुरुआत में पूछा जाता है, और केवल यदि आवश्यक हो।


यदि आपकी स्क्रिप्ट को बस एक त्रुटि संदेश दिखाने की आवश्यकता है और अगर ऑटो-एलिवेटिंग के बजाय कोई व्यवस्थापक विशेषाधिकार नहीं हैं , तो यह और भी सरल है: आप इसे अपनी स्क्रिप्ट की शुरुआत में जोड़कर प्राप्त कर सकते हैं:

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

इस तरह, उपयोगकर्ता को राइट-क्लिक करना होगा और "व्यवस्थापक के रूप में चलाएं" चुनें । स्क्रिप्ट REMविवरण के बाद आगे बढ़ेगी यदि वह व्यवस्थापक अधिकारों का पता लगाती है, अन्यथा एक त्रुटि के साथ बाहर निकलें। यदि आपको आवश्यकता नहीं है PAUSE, तो इसे हटा दें। महत्वपूर्ण: NET FILE [...] EXIT /D) एक ही पंक्ति पर होना चाहिए। बेहतर पठनीयता के लिए इसे कई लाइनों में यहाँ प्रदर्शित किया गया है!


कुछ मशीनों पर, मैंने मुद्दों का सामना किया है, जो पहले से ही नए संस्करण में हल किए गए हैं। एक अलग दोहरी बोली से निपटने के कारण था, और दूसरा मुद्दा इस तथ्य के कारण था कि विंडोज 7 मशीन पर यूएसी अक्षम था (निम्नतम स्तर पर सेट), इसलिए स्क्रिप्ट बार-बार खुद को कॉल करती है।

मैंने इसे अब पथ में उद्धरणों को अलग करके और बाद में उन्हें फिर से जोड़कर तय किया है, और मैंने एक अतिरिक्त पैरामीटर जोड़ा है जो स्क्रिप्ट के ऊंचे अधिकारों के साथ पुन: लॉन्च होने पर जोड़ा जाता है।

निम्नलिखित द्वारा दोहरे उद्धरण हटा दिए गए हैं (विवरण यहां हैं ):

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

तब आप पथ का उपयोग करके पहुँच सकते हैं !batchPath!। इसमें कोई दोहरा उद्धरण नहीं है, इसलिए "!batchPath!"बाद में स्क्रिप्ट में कहना सुरक्षित है ।

रेखा

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

जाँच करता है कि स्क्रिप्ट को पहले से ही VBScript स्क्रिप्ट द्वारा अधिकारों को ऊंचा करने के लिए बुलाया गया है , इसलिए अंतहीन पुनरावृत्ति से बचा जाए। यह प्रयोग करने वाले पैरामीटर को हटा देता है shift


अपडेट करें:

  • रजिस्टर करने के लिए होने से बचाने के .vbsमें विस्तार Windows 10 , मैं लाइन जगह ले ली है
    "%temp%\OEgetPrivileges.vbs"
    द्वारा
    "%SystemRoot%\System32\WScript.exe" "%temp%\OEgetPrivileges.vbs"
    ऊपर स्क्रिप्ट में; cd /d %~dp0स्टीफन (अलग उत्तर) द्वारा सुझाए गए और स्क्रिप्ट निर्देशिका को डिफ़ॉल्ट रूप में सेट करने के लिए टॉम ज़ेटो (टिप्पणी) द्वारा जोड़ा गया ।

  • अब स्क्रिप्ट कमांड लाइन के मापदंडों को पूरा करती है। टिप्पणियों और प्रेरणाओं के लिए jxmallet, TanisDLJ और पीटर मॉर्टेंसन को धन्यवाद।

  • Artjom बी के संकेत के अनुसार, मैं यह विश्लेषण किया है और जगह ले ली है SHIFTद्वारा SHIFT /1जिसके लिए फ़ाइल नाम को बरकरार रखता है, %0पैरामीटर

  • साफ del "%temp%\OEgetPrivileges_%batchName%.vbs"करने के लिए :gotPrivilegesअनुभाग में जोड़ा गया (जैसा कि एमएलटी ने सुझाव दिया है)। %batchName%यदि आप समानांतर में अलग-अलग बैच चलाते हैं तो प्रभाव से बचने के लिए जोड़ा गया । ध्यान दें कि आपको forउन्नत स्ट्रिंग फ़ंक्शंस का लाभ उठाने में सक्षम होने के लिए उपयोग करने की आवश्यकता है , जैसे कि %%~nk, जो केवल फ़ाइल नाम को निकालता है।

  • अनुकूलित स्क्रिप्ट संरचना, सुधार (जोड़ा गया वैरिएबल vbsGetPrivilegesजो अब फ़ाइल के पथ या नाम को आसानी से बदलने की अनुमति देकर हर जगह संदर्भित है, केवल .vbsफ़ाइल को हटा दें यदि बैच को ऊंचा करने की आवश्यकता है)

  • कुछ मामलों में, ऊंचाई के लिए एक अलग कॉलिंग सिंटैक्स आवश्यक था। यदि स्क्रिप्ट काम नहीं करती है, तो निम्न मापदंडों की जांच करें:
    set cmdInvoke=0
    set winSysFolder=System32
    या तो 1 पैरामीटर को बदलें set cmdInvoke=1और जांचें कि क्या पहले से ही समस्या को ठीक करता है। यह cmd.exeऊंचा प्रदर्शन करने वाली स्क्रिप्ट में जोड़ देगा ।
    या winSysFolder=Sysnative64 बिट सिस्टम पर 2 पैरामीटर को बदलने की कोशिश करें , यह मदद कर सकता है (लेकिन अधिकांश मामलों में इसकी आवश्यकता नहीं है)। (ADBailey ने इसकी सूचना दी है)। "Sysnative" केवल 32-बिट स्क्रिप्ट होस्ट से 64-बिट एप्लिकेशन लॉन्च करने के लिए आवश्यक है (उदाहरण के लिए एक विज़ुअल स्टूडियो बिल्ड प्रक्रिया, या अन्य 32-बिट एप्लिकेशन से स्क्रिप्ट इनवोकेशन)।

  • यह स्पष्ट करने के लिए कि मापदंडों की व्याख्या कैसे की जाती है, मैं इसे अब प्रदर्शित कर रहा हूं P1=value1 P2=value2 ... P9=value9। यह विशेष रूप से उपयोगी है यदि आपको दोहरे उद्धरण चिह्नों में पथ जैसे मापदंडों को संलग्न करने की आवश्यकता है, जैसे "C:\Program Files"

  • यदि आप VBS स्क्रिप्ट को डीबग करना चाहते हैं, तो आप //Xपहले पैरामीटर के रूप में WScript.exe में पैरामीटर को जोड़ सकते हैं , जैसा कि यहां सुझाया गया है (यह CScript.exe के लिए वर्णित है, लेकिन WScript.exe के लिए भी काम करता है)।

उपयोगी कड़ियाँ:


9
महान जवाब, हालांकि यह मुझे थोड़ा हैरान करता है कि आपको वह सब करना है जो कुछ मामलों में स्पष्ट रूप से आवश्यक है।
जेकोडर 10

50
दरअसल, विंडोज बैच की भाषा में ELEVATE जैसी एक कमांड स्पष्ट रूप से गायब है।
मैट

2
शायद यह शक्तियां के साथ आसान है जो लगता है कि अधिक जटिल चीजों के लिए अनुमोदित स्क्रिप्टिंग लैंग्वेज है, लेकिन मैंने इसे अभी तक जानने की
जहमत नहीं उठाई

1
पावरशेल में सिंटैक्स पूरी तरह से अलग है (क्रिया-संज्ञा सिंटैक्स), लेकिन यह आपको .NET असेंबली को आसानी से कॉल करने की अनुमति देता है। लेकिन इसे संभालना थोड़ा मुश्किल है (स्क्रिप्ट आदि पर हस्ताक्षर करना)।
मैट

2
@ मैट आप देख सकते हैं कि क्या आपके जवाब में इस अस्वीकृत संपादन के पीछे कुछ सच्चाई है ?
आर्टजोम बी।

41

जैसा कि जेकोडर और मैट ने उल्लेख किया है, पॉवरशेल ने इसे आसान बना दिया है, और यह एक नई स्क्रिप्ट बनाने के बिना भी बैच स्क्रिप्ट में एम्बेड किया जा सकता है।

मैंने मैट की स्क्रिप्ट को संशोधित किया:

:: 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
आप सही हैं, यदि PowerShell स्थापित है, तो आप इसका उपयोग बैच फ़ाइल को उन्नयन के साथ चलाने के लिए कर सकते हैं (कोड स्निपेट के लिए धन्यवाद!)। और हां, लेबल की जरूरत नहीं है। संकेत के लिए धन्यवाद, यह एक लायक है ... :-)
मैट

2
जब cmd से आमंत्रित Powershell.exe में -verb runas विकल्प नहीं है। यह मौजूद है यदि आप पहले से ही PowerShell में हैं।
आदिल हिंदिस्तान

1
मैं वास्तव में इस समाधान को पसंद करता हूं, मेरे लिए बहुत अच्छा काम करता है। विंडोज 8.1 पर मुझे इसकी आवश्यकता थी: इसे काम करने के लिए gotPrivileges लेबल।
शॉनो

अगर यह बैच फ़ाइल UNC पथ पर दूरस्थ है तो मैं एक समस्या मार रहा हूँ।
रयान बेस्ले

मैंने शुरुआत में परिवर्तन निर्देशिका को जोड़ा, प्रवाह को सरल किया और थोड़ा साफ किया। प्रक्रियाओं में सुरक्षा कारण की वजह से कार्य डायर को WorkingDirectoryपैरामीटर के माध्यम से नहीं बदला जा सकता हैStart-Processrunas
सेप्टेंको

28

मैं मैट के उत्कृष्ट उत्तर का उपयोग कर रहा हूं, लेकिन मैं अपने विंडोज 7 और विंडोज 8 सिस्टम के बीच एक अंतर देख रहा हूं जब ऊंचा स्क्रिप्ट चल रहा है।

एक बार जब स्क्रिप्ट विंडोज 8 पर बढ़ जाती है, तो वर्तमान निर्देशिका को सेट किया जाता है C:\Windows\system32। सौभाग्य से, वर्तमान निर्देशिका को वर्तमान स्क्रिप्ट के पथ में परिवर्तित करके एक आसान समाधान है:

cd /d %~dp0

नोट: cd /dयह सुनिश्चित करने के लिए कि ड्राइव लेटर को भी बदल दिया गया है।

इसका परीक्षण करने के लिए, आप निम्न को एक स्क्रिप्ट में कॉपी कर सकते हैं। समान परिणाम देखने के लिए किसी भी संस्करण पर सामान्य रूप से चलाएँ। व्यवस्थापक के रूप में चलाएँ और 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

1
अच्छा संकेत, स्टीफन। तो स्क्रिप्ट को cd %~dp0अपने वर्तमान पथ को बनाए रखने के लिए समाप्त होना चाहिए (मैं इस काम को Win7 में भी मानता हूं, इसलिए उसी कमांड का उपयोग किया जा सकता है, हालांकि केवल Win8 + के लिए आवश्यक है)। इसके लिए +1!
मैट

2
इस बात पर भी विंडोज 7. पर चल रहे मेरे सिस्टम पर यह जरूरी था
meh-uk

1
या pushd %~dp0इसके बजाय का उपयोग करें ... क्यों? क्योंकिpopd
Jaroslav Záruba

27

मैं इसे इस तरह से करता हूं:

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

इस तरह यह सरल है और केवल विंडोज़ डिफॉल्ट कमांड का उपयोग होता है। यह बहुत अच्छा है अगर आपको बैच फ़ाइल को फिर से वितरित करने की आवश्यकता है।

CD /d %~dp0वर्तमान निर्देशिका को फ़ाइल की वर्तमान निर्देशिका में सेट करता है (यदि यह पहले से नहीं है, तो ड्राइव की परवाह किए बिना फ़ाइल /dविकल्प के लिए धन्यवाद )।

%~nx0 एक्सटेंशन के साथ वर्तमान फ़ाइल नाम लौटाता है (यदि आप एक्सटेंशन को शामिल नहीं करते हैं और फ़ोल्डर पर एक ही नाम के साथ एक exe है, तो यह exe कॉल करेगा)।

इस पोस्ट पर बहुत सारे जवाब हैं मुझे नहीं पता कि क्या मेरा जवाब देखा जाएगा।

वैसे भी, मैं अन्य उत्तरों पर प्रस्तावित अन्य समाधानों की तुलना में इस तरह से सरल पाता हूं, मुझे उम्मीद है कि यह किसी की मदद करता है।


4
cd% ~ dp0 नेटवर्क ड्राइव पर काम नहीं करेगा, इसके बजाय pushd% ~ dp0 का उपयोग करें।
स्टेव्म

1
मुझे इस उत्तर की सादगी बहुत पसंद है। और आखिरकार Jscript का उपयोग करने का एक कारण!
जो कोडर

1
जादू! आपका बहुत बहुत धन्यवाद।
डेनियल ऑरलैंडो

1
@Wolf मैंने केवल एक गलत जवाब टाइप किया, जिससे मुझे पता चला कि मैं आपको गलत समझ रहा हूं ... मुझे वही मिला है जो अब आपका मतलब है। मैं इसे शामिल करने वाला हूं /d। थैंक्यू पाल :) (PS: पियानोवादक यहाँ भी!)
मथियस रोचा

1
यह बहुत अच्छा काम करता है, लेकिन cdकमांड को शुरू करने के लिए आगे बढ़ना एक अच्छा विचार हो सकता है (यह सुनिश्चित करता है कि एलिवेटेड स्क्रिप्ट के लिए भी रास्ता उपलब्ध है - अन्यथा एलिवेटेड स्क्रिप्ट बस सिस्टम 32 से चलती है)। नेट आउटपुट को छिपाने के लिए आपको नेट कमांड को रीडायरेक्ट करना चाहिए:net session >nul 2>&1
18

23

मैट के पास एक शानदार उत्तर है, लेकिन यह स्क्रिप्ट में पारित किसी भी तर्क को दूर कर देता है। यहाँ मेरा संशोधन है जो तर्क देता रहता है। मैंने विंडोज 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...

1
यह एक उपयोगी उत्तर है। हालांकि ECHO UAC.ShellExecute....लाइन में, "batchArgs!"चर का विस्तार नहीं करेगा। का उपयोग करें "!batchArgs!"। मेरा संपादन अस्वीकार कर दिया गया था, इसलिए मैं टिप्पणी करता हूं।
प्याज

1
@fliedonion अच्छी तरह से देखा! मुझे यकीन नहीं है कि आपके संपादन को अस्वीकार कर दिया गया था क्योंकि यह निश्चित रूप से एक टाइपो और आपका फिक्स काम था। स्वयं परिवर्तन किया और इसे 8.1 पर परीक्षण किया। अब सभी लिपियों को खोजने के लिए जहां मैं इस कोड का उपयोग करता हूं ....
jxmallett

2
उद्धृत तर्कों, जैसे test.bat "a thing"या का उपयोग करते समय स्क्रिप्ट टूट गई "test script.bat" arg1 arg2। अब सब तय हो गया।
jxmallett

मैं इसे तोड़ने में कामयाब रहा (मेरी गलती के कारण: मैप्ड नेटवर्क ड्राइव से स्क्रिप्ट चलाना, चूंकि व्यवस्थापक और सामान्य उपयोगकर्ता के पास समान मैपिंग नहीं है)। फिर भी: क्या आउटपुट देखने का कोई तरीका है? मेरे लिए, मुझे .vbs को खोजना होगा और / c को a / K में बदलना होगा और फिर इसे मैन्युअल रूप से देखना होगा।
एंड्रियास रीफ

21

यदि यह नहीं है तो मैं स्क्रिप्ट को फिर से लॉन्च करने के लिए पावरशेल का उपयोग करता हूं। इन पंक्तियों को अपनी स्क्रिप्ट के शीर्ष पर रखें।

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

मैंने @ मैट के उत्तर से 'शुद्ध नाम' विधि की प्रतिलिपि बनाई। उनका जवाब बहुत बेहतर दस्तावेज है और इसमें त्रुटि संदेश और पसंद है। इसका लाभ यह है कि PowerShell पहले से ही स्थापित है और विंडोज 7 और ऊपर उपलब्ध है। कोई अस्थायी VBScript (* .vbs) फाइलें नहीं हैं, और आपको उपकरण डाउनलोड करने की आवश्यकता नहीं है।

इस विधि को बिना किसी कॉन्फ़िगरेशन या सेटअप के काम करना चाहिए, जब तक कि आपके PowerShell निष्पादन की अनुमति बंद न हो जाए।


जब एक सूची व्हाट्सएप से अलग करने के लिए उद्धरणों से घिरा हुआ तर्क दिया जाता है ताकि इसे एक के रूप में माना जा सके, तो /c %~fnx0 %*'भाग पहले के अलावा हर भाग को छोड़ देता है। उदाहरण के लिए test.bat "arg1 arg2 arg3"केवल arg1 को आगे बढ़ाया जाता है
निकोलस मॉमर्ट्स

ऐसा लगता है कि कोई बात नहीं, स्टार्ट-प्रोसेस ने तर्क-सूची के सभी दोहरे उद्धरणों को हटा दिया ..
निकोलस मम्मैर्ट्स

मेरे लिये कार्य करता है! मैं इसके लिए उपयोग कर रहा हूं netsh int set int %wifiname% Enable/Disable
मार्सलो

2
मुझे ऊपर निकोलस मॉमर्ट्स के समान समस्या थी। मुझे समझ में नहीं आता कि यह क्यों काम करता है (सबसे अच्छी तरह का फिक्स), लेकिन निम्न कार्यों की तरह यह (अंत में सभी अतिरिक्त उद्धरण चिह्नों पर ध्यान देना चाहिए): net file 1>nul 2>nul && goto :run || powershell -ex unrestricted -Command "Start-Process -Verb RunAs -FilePath '%comspec%' -ArgumentList '/c ""%~fnx0""""'"
quakes

एक अन्य समस्या (असुविधा) यह है कि यदि सर्वर सेवा नहीं चल रही है तो स्क्रिप्ट रुक जाती है (उपयोगकर्ता इनपुट के लिए प्रतीक्षा करता है) (मेरे पास कारणों से यह अक्षम है)। मैं usuallly को लिखने की कोशिश कर रहा द्वारा व्यवस्थापक perms के लिए परीक्षण मेजबानों फ़ाइल स्थान है, लेकिन यह PowerShell आदेश को लागू करने की शायद बेहतर है -Verb runas बजाय पर भरोसा करने की, सक्षम खिड़कियों सेवाओं या फ़ाइल राईट प्रयास में।
script'n'code

15

काम करने के लिए सुपर सीक्रेट __COMPAT_LAYERएनवायरनमेंट वैरिएबल सेट करने वाले कुछ प्रोग्राम के लिए RunAsInvoker इसे चेक करें:

set "__COMPAT_LAYER=RunAsInvoker"
start regedit.exe

हालांकि, इस तरह कोई UAC संकेत नहीं होगा उपयोगकर्ता व्यवस्थापक अनुमतियों के बिना जारी रहेगा।


1
Microsoft साइट के लिंक ने अब काम नहीं किया, इसलिए मैंने इसे आर्काइव.ऑर्ग के कंटेंट में बदल दिया। यदि कोई भी Microsoft की साइट पर सामग्री के लिए एक कार्यशील लिंक पा सकता है, लेकिन सभी साधन, कृपया इसे उसी पर अपडेट करें।
रॉकप्परलॉगर

1
यह अभी भी मध्यम अखंडता में उन्नत नहीं है , इसलिए आप HKLM को संपादित नहीं कर सकते regedit। यह सिर्फ यूएसी को छोड़ देता है।
हैकिंगएडक्ट 1337

5

मैंने इसे स्क्रिप्ट की शुरुआत में चिपकाया:

:: 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
मुझे आपकी स्क्रिप्ट में आर्ग प्रोसेसिंग पसंद है। लेकिन ध्यान दें कि caclsविंडोज 7 और नए विंडोज़ संस्करणों में अपग्रेड किया गया है।
मैट

Fsutil गंदा भी बेहतर है
वुल्फ

1
क्या आप जानते हैं कि लाइन pushd "%CD%"वर्तमान कार्य निर्देशिका को सहेजती है और वर्तमान कार्यशील निर्देशिका में परिवर्तन करती है?
वुल्फ

3

मैंने लिखा gsudo, एक sudoखिड़कियों के लिए : कि में उठ वर्तमान कंसोल (कोई संदर्भ एक नई विंडो का उपयोग करने जा), एक साख कैश के साथ (UAC पॉपअप कम), और भी उठ PowerShell आदेशों

यदि आप चाहते हैं तो यह उन विशेषाधिकारों को बढ़ाने की अनुमति देता है जिनके लिए व्यवस्थापक विशेषाधिकार या पूरे बैच की आवश्यकता होती है। बस बहाना हैgsudo कुछ भी करने से पहले चाहिए।

उदाहरण बैच फ़ाइल जो स्वयं को gsudo का उपयोग करके ऊपर उठाती है:

संपादित करें: नया एक लाइनर संस्करण जो किसी भी विंडोज़ भाषा के साथ काम करता है और जो ओम्मी मुद्दों से बचा जाता है :

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

वैकल्पिक (मूल संस्करण):

@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

इंस्टॉल:

कार्रवाई में देखें gsudo: gsudo डेमो


ठंडा। धन्यवाद। विंडोज के किन संस्करणों पर काम करता है?
रॉकपैपर छिपकली

परीक्षण सूट सर्वर 2019 पर चलता है और मेरा स्थानीय देव बॉक्स विंडोज 10 1909 है। क्षमा करें, मैंने अन्य पुराने ओएस के साथ संगतता का परीक्षण नहीं किया है।
गेरार्डो ग्रिग्नोली

धन्यवाद जेरार्डो। यदि कोई इसे विंडोज के अन्य संस्करणों पर आज़माता है, तो कृपया अपने परिणाम पोस्ट करें।
रॉकपरपेपर छिपकली

मैंने अभी विंडोज 8.1 पर gsudo v0.7 का परीक्षण किया है और काम किया है। यह .Net Framework 4.6वहाँ स्थापित करने के लिए तुच्छ नहीं है । सौभाग्य से choco install dotnet4.6.2कुछ कठिन-निर्भरताएं लाईं। फिर एक गलत प्रॉम्प्ट (रेड शार्प की बजाए एस्केप सीक्वेंस चार्ज) दिखाते हुए एक gsudo config Prompt "$p# "मुद्दा तय किया ConHost। @RockPaperLizard
गेरार्डो

बहुत बहुत धन्यवाद गेरार्डो। क्या इसे 4.6 से पहले .Net फ्रेमवर्क के किसी भी संस्करण के साथ काम करने के लिए फिर से तैयार किया जा सकता है, या यह 4.6 के लिए कुछ कार्यक्षमता पर निर्भर करता है?
रॉकपॉपरलॉगर

2

हालाँकि यह सीधे तौर पर इस सवाल पर लागू नहीं होता है, क्योंकि यह उपयोगकर्ता के लिए कुछ जानकारी चाहता है, Google ने मुझे यहां तब लाया जब मैं कार्य शेड्यूलर से उन्नत .bat फ़ाइल को चलाना चाहता था।

सरलतम दृष्टिकोण .bat फ़ाइल का शॉर्टकट बनाना था, क्योंकि शॉर्टकट के लिए आप Run as administratorसीधे उन्नत गुणों से सेट कर सकते हैं।

शॉर्टकट को कार्य शेड्यूलर से चलाना, .bat फ़ाइल को उन्नत करता है।


0

शक्तियों का उपयोग करना।

यदि cmd फ़ाइल लंबी है, तो मुझे पहले एक का उपयोग ऊंचाई की आवश्यकता है और फिर वास्तविक कार्य करने वाले को कॉल करें।

यदि स्क्रिप्ट एक साधारण कमांड है तो सब कुछ एक cmd फ़ाइल पर फिट हो सकता है। स्क्रिप्ट फ़ाइलों पर पथ को शामिल करना न भूलें।

टेम्पलेट:

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

उदाहरण 1:

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

उदाहरण 2:

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

0

इसे इस्तेमाल करे:

@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

यदि आपको उस बैच फ़ाइल की जानकारी चाहिए, तो 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>


-3

निम्नलिखित समाधान साफ ​​है और पूरी तरह से काम करता है।

  1. Https://www.winability.com/download/Elevate.zip से एलिवेट ज़िप फ़ाइल डाउनलोड करें

  2. ज़िप के अंदर आपको दो फाइलें मिलनी चाहिए: Elevate.exe और Elevate64.exe। (उत्तरार्द्ध एक देशी 64-बिट संकलन है, अगर आपको इसकी आवश्यकता है, हालांकि नियमित 32-बिट संस्करण, Elevate.exe, को विंडोज के 32- और 64-बिट दोनों संस्करणों के साथ ठीक काम करना चाहिए)

  3. फ़ाइल Elevate.exe को एक फ़ोल्डर में कॉपी करें, जहां विंडोज हमेशा इसे पा सकता है (जैसे कि C: / Windows)। या आप बेहतर तरीके से उसी फ़ोल्डर में कॉपी कर सकते हैं जहाँ आप अपनी बैट फाइल रखने की योजना बना रहे हैं।

  4. एक बैच फ़ाइल में इसका उपयोग करने के लिए, केवल उस कमांड को पूर्वस्थापित करें जिसे आप एलिवेट कमांड के साथ प्रशासक के रूप में निष्पादित करना चाहते हैं, जैसे:

 elevate net start service ...

2
यह कमांड केवल एक डायलॉगविंड खोलता है जो उपयोगकर्ता से पूछता है कि क्या इस कमांड को निष्पादित करने की अनुमति है। तो आप इस कमांड का उपयोग बैचफाइल में कर सकते हैं जो उपयोगकर्ता के इंटरैक्शन के बिना चलना चाहिए।
रादोन .४ Rad२

यदि उपयोगकर्ता सहभागिता के बिना इसे बढ़ाना संभव था, तो यह एक बड़ा सुरक्षा छेद होगा? प्रत्येक वायरस उपयोगकर्ता की स्वीकृति के बिना खुद को ऊंचा करने के लिए उस पद्धति का उपयोग करना शुरू कर देगा।
आंद्रेई बेलोगॉर्टसेफ़
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.