Повышение UAC через файл .bat?


10

Довольно простой вопрос, на который мне трудно найти ответ.

Ранее serverfault помог мне найти способ автоматизации обновлений Windows без использования WSUS. Он работает фантастически, но чтобы запустить его по сети, сначала нужно подключить общий диск. Это довольно простая XP, поскольку вы просто монтируете диск и запускаете программу обновления.

На Vista и W7, однако, все это должно быть сделано с повышенными привилегиями для правильной работы. Учетная запись UAC не может видеть сетевые диски, подключенные обычным пользователем, поэтому, чтобы все заработало, я должен смонтировать общий ресурс через net useрасширенную оболочку. Я хотел бы автоматизировать монтирование этого ресурса и запуск программы обновления через простой файл .bat.

Возможно, я мог бы просто поручить всем щелкнуть правой кнопкой мыши «Запуск от имени администратора» в файле .bat, но я хотел бы сделать все как можно более простым и сделать так, чтобы .bat автоматически предлагал пользователю повысить свои привилегии.

Поскольку эти компьютеры не принадлежат нам, я не могу рассчитывать на то, что будет установлен Powershell, так что это исключает любые решения в этом направлении и в значительной степени должно полагаться на то, что будет включено в установку RTM Vista. Я надеюсь, что в основном мне не хватает чего-то очевидного здесь. :)

Ответы:


8

http://technet.microsoft.com/en-us/magazine/2007.06.utilityspotlight.aspx

РЕДАКТИРОВАТЬ: Если вы даете клиенту один файл для запуска, почему бы не создать самораспаковывающийся RAR с WinRAR и установить флаг «Требовать администратора» в опциях SFX? Это освобождает вас от ограничения в 1 файл, вы можете иметь все необходимые ресурсы.

Или сделайте свой SFX, используя ваш любимый инструмент SFX и используйте инструменты поднять выше.


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

Я считаю, что вы можете использовать их, не устанавливая их, просто упакуйте их в свой пакетный файл.
ta.speot.is

В загрузке есть несколько файлов, но, похоже, все, что вам нужно для вашего требования, будет elevate.cmdиelevate.vbs
Приостановлено до дальнейшего уведомления.

Если я могу упаковать все это что-то достаточно автономное / портативное, это может сработать. Я посмотрю на это поближе, когда у меня будет немного больше времени сегодня.
jslaker

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

4

Если вы готовы перейти на PowerShell, это сделать гораздо проще. Это мой " Elevate-Process.ps1" скрипт (с suпсевдонимом в моем профиле):

# Updated elevate function that does not need Elevate PowerToys
# From http://devhawk.net/2008/11/08/My+ElevateProcess+Script.aspx


$psi = new-object System.Diagnostics.ProcessStartInfo
$psi.Verb = "runas"

# If passed multiple commands, or one (that isn't a folder) then execute that command:
if (($args.Length -gt 1) -or (($args.length -eq 1) -and -not (test-path $args[0] -pathType Container))) {

    $file, [string]$arguments = $args;
    $psi.FileName = $file  
    $psi.Arguments = $arguments
    [System.Diagnostics.Process]::Start($psi) | out-null
    return
}

# If from console host, handle case of one argyment that is
# a folder, to start in that folder. Otherwise start in current folder.
if ($host.Name -eq 'ConsoleHost') {
    $psi.FileName = (Get-Command -name "PowerShell").Definition
    if ($args.length -eq 0) {
        $psi.Arguments = "-NoExit -Command &{set-location '" + (get-location).Path + "'}"
    } else {
        $psi.Arguments = "-NoExit -Command &{set-location '" + (resolve-path $args[0]) + "'}"
    }
    [System.Diagnostics.Process]::Start($psi) | out-null
    return
}

# Otherwise this is some other host (which cannot be assumed to take parameters).
# So simplely launch elevated.
$psi.FileName = [system.diagnostics.process]::getcurrentprocess().path
$psi.Arguments = ""
[System.Diagnostics.Process]::Start($psi) | out-null

Обнаружение повышения также может быть сделано в PSH (таким образом, вы можете проверить повышение, а затем повысить при необходимости):

$wid=[System.Security.Principal.WindowsIdentity]::GetCurrent()
$prp=new-object System.Security.Principal.WindowsPrincipal($wid)
$adm=[System.Security.Principal.WindowsBuiltInRole]::Administrator
$IsAdmin=$prp.IsInRole($adm)
if ($IsAdmin) {
  $host.UI.RawUI.Foregroundcolor="Red"
  write-host "`n** Elevated Session **`n" -foreground $_errorColour -background $_errorBackound
}

Я подумал, что Powershell может сделать это, но опять же, я не могу полагаться на установку Powershell, и мне нужно что-то как огонь и забыть, насколько это возможно.
Jslaker

@jslaker: это может быть проблема с Vista / 2008. Но PSH включен в Win7 / 2008R2, так что должно стать проще. В корпоративной ситуации это может быть стимулом для раскрутки?
Ричард

Ну, это не корпоративная ситуация. В исходном вопросе, который я связал, есть еще кое-что, но короткая версия состоит в том, что мы являемся мастерской по ремонту ПК, и это в основном все попытки обойти то, что лицензия WSUS запрещает вам использовать WSUS для развертывания обновлений на компьютерах, которые не лицензию для вашей организации. Это все клиентские машины, которые могут работать с XP RTM и выше. Вот почему я не могу рассчитывать на то, что что-то будет установлено, что не будет включено в установку RTM какой-либо конкретной ОС.
jslaker

Если вы не можете рассчитывать на установку Powershell, посмотрите ответ, который я дал ниже.
Мэтт

3

Вот пример сценария, который я придумал, надеюсь, он поможет другим. Это bat-файл, который запрашивает у пользователя разрешение и затем сам расширяется. Он передает некоторый vbscript, который вызывает приглашение UAC, а затем повторно запускает файл bat с повышенными правами ... http://jagaroth.livejournal.com/63875.html


2

Это то, что вам нужно: http://sites.google.com/site/eneerge/home/BatchGotAdmin


1
В этом скрипте есть небольшая ошибка, он не передает параметры. Просто поместите их в команду для вызова вашего скрипта следующим образом: echo UAC.ShellExecute "% ~ s0", "% *", "", "runas", 1 >> "% temp% \ getadmin.vbs"
SvenS

1

FusionInventory.org - это решение с открытым исходным кодом, в основном используемое небольшими ремонтными мастерскими. Это может быть как ваш персональный удаленно управляемый Windows Updater.


0

Ни одно из этих решений не работает для файла .cmd, который должен знать параметры командной строки. Поместите это в самом начале файла .cmd, и все ваши проблемы будут решены. (Это для будущих людей, просматривающих эту ветку [Я проверял это на Windows XP, 7 Vista и 8; x86 + x64]):

@echo off
NET SESSION >nul 2>&1 && goto noUAC
title.
set n=%0 %*
set n=%n:"=" ^& Chr(34) ^& "%
echo Set objShell = CreateObject("Shell.Application")>"%tmp%\cmdUAC.vbs"
echo objShell.ShellExecute "cmd.exe", "/c start " ^& Chr(34) ^& "." ^& Chr(34) ^& " /d " ^& Chr(34) ^& "%CD%" ^& Chr(34) ^& " cmd /c %n%", "", "runas", ^1>>"%tmp%\cmdUAC.vbs"
echo Not Admin, Attempting to elevate...
cscript "%tmp%\cmdUAC.vbs" //Nologo
del "%tmp%\cmdUAC.vbs"
exit /b
:noUAC

::-----Normal Batch Starts Here---------------------

0

Как сказал @emilio, этот сценарий в порядке, но он не принимает никаких аргументов. Здесь модифицированный скрипт для совместимости с аргументами:

:: BatchGotAdmin
:-------------------------------------
REM  --> Check for permissions
>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"
    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"
:--------------------------------------

0

Если вы не можете рассчитывать на установку Powershell, вы можете использовать это решение в StackOverflow:

автоматическое повышение с UAC с использованием командного файла

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


Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.