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

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

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

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

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

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

9 ответов

Решение

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

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

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

Если вы готовы перейти на 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
}

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

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

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

Как сказал @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"
:--------------------------------------

Ни одно из этих решений не работает для файла.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---------------------

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

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

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

Вы пробовали runas команда?

Другие вопросы по тегам