Как я могу автоматически поднять свой пакетный файл, чтобы он запрашивал права администратора UAC, если это необходимо?

209

Я хочу, чтобы мой командный файл работал только с повышенными правами. Если уровень не повышен, предоставьте пользователю возможность перезапустить пакет с повышенными правами.

Я пишу командный файл для установки системной переменной, копирую два файла в папку Program Files и запускаю установщик драйвера. Если пользователь Windows 7 / Windows Vista ( UAC включен и даже если он является локальным администратором) запускает его без щелчка правой кнопкой мыши и выбора «Запуск от имени администратора», он получит «Отказано в доступе», скопировав два файла и записав системную переменную. ,

Я хотел бы использовать команду для автоматического перезапуска пакета с повышенными правами, если пользователь фактически является администратором. В противном случае, если они не администратор, я хочу сказать им, что им нужны права администратора для запуска командного файла. Я использую xcopy для копирования файлов и REG ADD для записи системной переменной. Я использую эти команды для работы с возможными компьютерами с Windows XP. Я нашел похожие вопросы по этой теме, но ничего, что касалось перезапуска командного файла с повышенными правами.

PDixon724
источник
2
Посмотрите, что я написал - вам не нужен какой-либо внешний инструмент, скрипт автоматически проверяет права администратора и автоматически повышает его, если требуется.
Мэтт
1
Пожалуйста, подумайте, будет ли ответ Мэтта отмечен галочкой? Мне так кажется.
akauppi
Пожалуйста, обратите внимание на новые подсказки Windows 10 в разделе комментариев пакетного скрипта, который я опубликовал.
Мэтт
4
Из CMD: @powershell Start-Process cmd -Verb runas. От Powershell просто капля @powershell. Это запускает cmd с повышенными правами.
BrunoLM

Ответы:

20

Вы можете иметь вызов сценария сам с Psexec «s -hвариантом запуска повышен.

Я не уверен, как вы могли бы определить, работает ли он с повышенными правами или нет ... может быть, повторите попытку с повышенными привилегиями только в случае ошибки «Отказано в доступе»?

Или вы можете просто использовать команды для xcopyи reg.exeвсегда запускать их psexec -h, но для конечного пользователя будет раздражать, если ему нужно будет каждый раз вводить свой пароль (или небезопасно, если вы включите пароль в сценарий) ...

ewall
источник
10
Спасибо за ответ. К сожалению, я не думаю, что могу использовать что-либо, кроме стандартных инструментов Windows Vista / 7, потому что это будет распространяться среди клиентов за пределами моего офиса. Я не думаю, что могу легально распространять PSExec.
PDixon724
2
Да, я думаю, что вы правы в этом - несмотря на то, что PSExec теперь является инструментом Microsoft (поскольку они выкупили парней из Sysinternals!), EULA запрещает распространение :(
ewall
2
Я думаю, что мои возможности довольно ограничены. Если бы я знал, как кодировать на VB, я мог бы сделать его exe с манифестом администратора, но я бы даже не знал, с чего начать. Думаю, я просто предупрежу в начале пакета, что он должен работать от имени администратора, если они работают под управлением Windows Vista / 7. Спасибо всем.
PDixon724
1
Другой третьей стороной инструмент , который может быть свободно распространяемый и легко интегрировать и учиться в AutoIt ; На этой странице показано, как скрипт запрашивает повышенные привилегии.
ewall
4
psexec -hне работает: «Не удалось установить службу PSEXESVC: доступ запрещен». У вас уже должны быть права администратора для запуска psexec.
Николас
320

Существует простой способ без необходимости использования внешнего инструмента - он отлично работает с Windows 7, 8, 8.1 и 10 и обратно совместим (также Windows XP не имеет UAC, поэтому повышение прав не требуется - в этом на всякий случай скрипт просто продолжается).

Проверьте этот код (я был вдохновлен кодом от NIronwolf, размещенным в ветке Batch File - «Доступ запрещен» в Windows 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если у вас его нет. Повышение достигается путем создания сценария, который повторно запускает пакетный файл для получения привилегий. Это заставляет Windows представить диалоговое окно UAC и запрашивает учетную запись администратора и пароль.

Я проверил его с Windows 7, 8, 8.1, 10 и с Windows XP - он отлично работает для всех. Преимущество заключается в том, что после начальной точки вы можете разместить все, что требует привилегий системного администратора, например, если вы собираетесь переустановить и повторно запустить службу Windows для целей отладки (предполагается, что 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) должно быть на одной линии. Это отображается здесь в несколько строк для лучшей читаемости!


На некоторых машинах я столкнулся с проблемами, которые уже решены в новой версии выше. Одна из них была связана с другой обработкой двойных кавычек, а другая проблема была связана с тем, что UAC был отключен (установлен на самый низкий уровень) на компьютере с Windows 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 и Peter Mortensen за наблюдения и вдохновение.

  • Согласно подсказке Артжома Б., я проанализировал его и заменил SHIFTна SHIFT /1, который сохраняет имя файла для %0параметра

  • Добавлено del "%temp%\OEgetPrivileges_%batchName%.vbs"в :gotPrivilegesраздел для очистки (как предложено MLT ). Добавлено, %batchName%чтобы избежать влияния, если вы запускаете разные партии параллельно. Обратите внимание, что вам нужно использовать, forчтобы иметь возможность воспользоваться расширенными строковыми функциями, такими как %%~nk, который извлекает только имя файла.

  • Оптимизированная структура скрипта, улучшения (добавлена ​​переменная, на vbsGetPrivilegesкоторую теперь ссылаются все, что позволяет легко изменять путь или имя файла, удалять .vbsфайл только в том случае, если требуется повысить пакет)

  • В некоторых случаях для повышения прав потребовался другой синтаксис вызова. Если сценарий не работает, проверьте следующие параметры:
    set cmdInvoke=0
    set winSysFolder=System32
    либо измените 1-й параметр на set cmdInvoke=1и проверьте, устраняет ли это уже проблему. Это добавит cmd.exeк сценарию выполнения возвышения.
    Или попробуйте изменить второй параметр на winSysFolder=Sysnative, это может помочь (но в большинстве случаев не требуется) в 64-битных системах. (ADBailey сообщил об этом). «Sysnative» требуется только для запуска 64-разрядных приложений с 32-разрядного хоста сценария (например, процесс сборки Visual Studio или вызов сценария из другого 32-разрядного приложения).

  • Чтобы было понятнее, как интерпретируются параметры, я теперь отображаю это следующим образом P1=value1 P2=value2 ... P9=value9. Это особенно полезно, если вам нужно заключить такие параметры, как пути, в двойные кавычки, например "C:\Program Files".

  • Если вы хотите отладить сценарий VBS, вы можете добавить //Xпараметр в WScript.exe в качестве первого параметра, как предлагается здесь (он описан для CScript.exe, но работает и для WScript.exe).

Полезные ссылки:

Matt
источник
9
Отличный ответ, хотя меня немного удивляет, что вы должны делать все это, чтобы делать то, что явно необходимо в некоторых случаях.
Jcoder
50
Действительно, такая команда, как ELEVATE, явно отсутствует в пакетном языке Windows.
Мэтт
2
Возможно, это проще с PowerShell, который кажется одобренным языковым сценарием для более сложных вещей, но я никогда не удосужился изучить его до сих пор :(
jcoder
1
Синтаксис в powershell совершенно другой (синтаксис глагол-существительное), но он позволяет легко вызывать сборки .NET. Но с этим немного сложнее (подписание скриптов и т. Д.).
Мэтт
2
@Matt Можете ли вы проверить, есть ли какая-то правда в этом отклоненном редактировании вашего ответа?
Artjom B.
41

Как упоминали jcoder и Matt, PowerShell сделал это легко, и его даже можно было встроить в пакетный скрипт без создания нового скрипта.

Я изменил сценарий Мэтта:

:: 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, вы можете использовать его для запуска командного файла с повышением прав (спасибо за фрагмент кода!). И да, ярлык не нужен. Спасибо за подсказки, стоит +1 ... :-)
Мэтт
2
При запуске из cmd Powershell.exe отсутствует опция -verb runas. Он существует, если вы уже в PowerShell.
Адиль Хиндистан
1
Мне очень нравится это решение, прекрасно работает для меня. В Windows 8.1 мне требовался ярлык: gotPrivileges, чтобы он работал.
ShaunO
Я столкнулся с проблемой, если этот командный файл удален по пути UNC.
Райан Бизли
Я добавил изменить каталог при запуске, упростил процесс и немного почистил. Рабочий WorkingDirectoryStart-Processrunas
каталог
28

Я использую отличный ответ Мэтта, но я вижу разницу между моими системами Windows 7 и Windows 8 при запуске сценариев с повышенными правами.

Как только сценарий повышен в Windows 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
Следует отметить, что это также требовалось в моей системе, работающей под управлением Windows 7.
meh-uk,
1
или использовать pushd %~dp0вместо ... почему? потому чтоpopd
Ярослав
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

Таким образом, это просто и использовать только команды Windows по умолчанию. Это здорово, если вам нужно распространять пакетный файл.

CD /d %~dp0Устанавливает текущий каталог в текущий каталог файла (если его нет, независимо от того, на каком диске находится файл, благодаря /dопции).

%~nx0 Возвращает текущее имя файла с расширением (если вы не включите расширение и в папке есть исполняемый файл с тем же именем, он вызовет исполняемый файл).

На это сообщение так много ответов, что я даже не знаю, увидят ли мой ответ.

В любом случае, я нахожу этот способ проще, чем другие решения, предложенные в других ответах, надеюсь, это кому-нибудь поможет.

Матеус Роча
источник
4
cd% ~ dp0 не будет работать на сетевых дисках, вместо этого используйте pushd% ~ dp0.
Ставм
1
Мне нравится простота этого ответа. И, наконец, причина использовать Jscript!
Джо Кодер
1
Магия! Большое спасибо.
Даниэле Орландо
1
@ Волк Я набрал огромный ответ только для того, чтобы понять, что неправильно понял тебя ... Теперь я понял, что ты имеешь в виду. Я собираюсь изменить это, чтобы включить /d. Спасибо, приятель :) (PS: здесь тоже пианист!)
Матеус Роча,
1
Это прекрасно работает, но может быть хорошей идеей переместить cdкоманду в начало (это гарантирует, что путь также доступен для сценария с повышенными правами - в противном случае сценарий с повышенными правами просто запускается из system32). Вы также должны перенаправить команду net на nul, чтобы скрыть вывод:net session >nul 2>&1
Nulano
23

У Мэтта отличный ответ, но он убирает все аргументы, переданные сценарию. Вот моя модификация, которая сохраняет аргументы. Я также включил исправление Стивена для проблемы с рабочим каталогом в 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
источник
1
Это полезный ответ. Однако в ECHO UAC.ShellExecute....строке, "batchArgs!"не будет расширять переменную. Использование "!batchArgs!". Мои изменения были отклонены, поэтому я комментирую.
летал лук
1
@fliedonion хорошо заметили! Я не уверен, почему ваше редактирование было отклонено, потому что это была определенная опечатка, и ваше исправление работает. Внес изменения самостоятельно и протестировал их на Win 8.1. Теперь, чтобы найти все сценарии, где я использую этот код ....
jxmallett
2
Сценарий не работает при использовании аргументов в кавычках, например test.bat "a thing"или "test script.bat" arg1 arg2. Все исправлено сейчас.
Jxmallett
Мне удалось его сломать (по моей вине: запуск сценария с подключенного сетевого диска, так как администратор и обычный пользователь не имеют одинакового сопоставления). Тем не менее: есть ли способ увидеть результат? Для меня я должен был найти .vbs и изменить / c на / K, а затем увидел его вручную.
Андреас Рифф
21

Я использую PowerShell, чтобы перезапустить сценарий с повышенными правами, если это не так. Поместите эти строки в самый верх вашего сценария.

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

Я скопировал метод 'net name' из ответа @ Matt. Его ответ гораздо лучше задокументирован и содержит сообщения об ошибках и тому подобное. Преимущество этого заключается в том, что PowerShell уже установлен и доступен в Windows 7 и более поздних версиях. Нет временных файлов VBScript (* .vbs), и вам не нужно загружать инструменты.

Этот метод должен работать без какой-либо настройки или настройки, если ваши разрешения на выполнение PowerShell не заблокированы.

Райан Бемроуз
источник
при предоставлении списка разделенных пробелами аргументов, заключенных в кавычки, чтобы рассматривать его как единое целое, /c %~fnx0 %*'часть, кажется, оставляет каждую часть, кроме первой. Например, test.bat "arg1 arg2 arg3"только arg1 передается вперед
Nicolas Mommaerts
Кажется, что несмотря ни на что, Start-Process удаляет все двойные кавычки в
списке
Работает для меня! Я использую это для 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""""'"
землетрясения
Другая проблема (неудобство) заключается в том, что скрипт приостанавливает работу (ожидает ввода данных пользователем), если служба сервера не запущена (у меня она отключена по причинам). Обычно я проверяю администраторские привилегии, пытаясь записать в местоположение файла HOSTS , но, возможно, лучше вызывать команду powershell -Verb runas вместо того, чтобы полагаться на включенные службы Windows или пытаться записать файлы.
script'n'code
15

Для некоторых программ установка суперсекретной __COMPAT_LAYERпеременной среды RunAsInvoker будет работать. Проверьте это:

set "__COMPAT_LAYER=RunAsInvoker"
start regedit.exe

Хотя, как это, UAC не будет предлагать пользователю продолжить работу без прав администратора.

npocmaka
источник
1
Ссылка на сайт Microsoft больше не работала, поэтому я изменил ее на содержимое на archive.org. Если кто-то может найти рабочую ссылку на контент на сайте Microsoft, но все средства, пожалуйста, обновите его до этого.
RockPaperLizard
1
он все еще в средней целостности, не повышен , поэтому вы не можете редактировать HKLM в regedit. Он просто пропустил UAC.
HackingAddict1337
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"
:--------------------------------------
TanisDLJ
источник
2
Мне нравится обработка arg в вашем скрипте. Но обратите внимание, что caclsустарела в Windows 7 и более новых версиях Windows.
Мэтт
Фсутил грязнее даже лучше
Вольф
1
Знаете ли вы, что строка pushd "%CD%"сохраняет текущий рабочий каталог и изменяет текущий рабочий каталог?
Вольф
3

Я написал gsudo, для окон : что возвышает в текущей консоли (контекста не переключение в новое окно), с кэшем мандатных (уменьшенная UAC всплывающих окон), а также возводит команду PowerShell .sudo

Это позволяет поднять команды, которые требуют прав администратора, или весь пакет, если хотите. Просто подготовьтесь, gsudo прежде чем что-либо, что должно работать с повышенными правами.

Пример командного файла, который поднимается с помощью gsudo:

РЕДАКТИРОВАТЬ: Новая версия с одним вкладышем, которая работает с любым языком Windows и позволяет избежать проблем с whoami :

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

Установка:

  • через шоколадку: choco install gsudo
  • или совок: scoop install gsudo
  • или скачайте его с github: https://github.com/gerardog/gsudo

Смотрите gsudo в действии: демо-версия

Герардо Гриньоли
источник
Прохладно. Спасибо. На каких версиях Windows он работает?
RockPaperLizard
Набор тестов работает на сервере 2019, и мой локальный компьютер разработчика - Windows 10 1909. К сожалению, я не тестировал совместимость с другими более старыми ОС.
Герардо Гриньоли
Спасибо Герардо. Если кто-то попробует это сделать в других версиях Windows, пожалуйста, опубликуйте свои результаты.
RockPaperLizard
Я только что протестировал gsudo v0.7 на Windows 8.1 и работал. Это не просто установить .Net Framework 4.6там. К счастью, choco install dotnet4.6.2принес некоторые труднодоступные зависимости. Затем gsudo config Prompt "$p# "исправлена ConHostошибка с отображением неверного приглашения (вместо красной резкости используются экранирующие символы). @RockPaperLizard
Херардо Гриньоли
Большое спасибо Герардо. Может ли он быть перекомпилирован для работы с любыми версиями .Net Framework до 4.6, или это зависит от некоторых функций, специфичных для 4.6?
RockPaperLizard
2

Хотя это не относится непосредственно к этому вопросу, потому что он хочет получить некоторую информацию для пользователя, Google привел меня сюда, когда я хотел запустить мой .bat-файл с повышенными правами из планировщика задач.

Простейшим подходом было создать ярлык для файла .bat, потому что ярлык можно установить Run as administratorпрямо из расширенных свойств.

Запустив ярлык из планировщика задач, запустим файл .bat с повышенными правами.

Хьюго Делсинг
источник
1

Если вам не нужно передавать аргументы, вот компактный сценарий запроса UAC длиной в одну строку. Это делает то же самое, что и сценарий повышения прав в ответе с верхним голосом, но не передает аргументы, поскольку нет надежного способа сделать это, обрабатывая все возможные комбинации ядовитых символов.

@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
user8922283
источник
0

Использование powershell.

Если 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. Загрузите почтовый файл Elevate по адресу https://www.winability.com/download/Elevate.zip.

  2. Внутри zip вы должны найти два файла: Elevate.exe и Elevate64.exe. (Последняя представляет собой встроенную 64-разрядную компиляцию, если вам требуется, хотя обычная 32-разрядная версия Elevate.exe должна нормально работать как с 32-, так и с 64-разрядными версиями Windows)

  3. Скопируйте файл Elevate.exe в папку, где Windows всегда может его найти (например, C: / Windows). Или вы лучше можете скопировать в ту же папку, где вы планируете сохранить файл bat.

  4. Чтобы использовать его в командном файле, просто добавьте команду, которую вы хотите выполнить от имени администратора, с помощью команды elevate, например:

 elevate net start service ...
Вайбхав Джайн
источник
2
Эта команда только открывает диалоговое окно, которое спрашивает пользователя, разрешено ли выполнение этой команды. Таким образом, вы не можете использовать эту команду в пакетном файле, который должен запускаться без взаимодействия с пользователем.
Radon8472
Если бы можно было повысить уровень БЕЗ взаимодействия с пользователем, это была бы огромная дыра в безопасности, не так ли? Каждый вирус начал бы использовать этот метод, чтобы поднять себя без согласия пользователя.
Андрей Белогорцеф