Elevando o UAC via arquivo .bat?

10

Muito simples, estou tendo problemas para encontrar uma resposta.

O

serverfault ajudou-me anteriormente a encontrar uma maneira de automatizar as atualizações do Windows sem usar o WSUS. Ele está funcionando fantasticamente, mas para executá-lo na rede, primeiro é necessário montar uma unidade compartilhada. Isso é muito simples XP desde que você acabou de montar a unidade e executar o atualizador.

No Vista e no W7, tudo isso precisa ser feito com privilégios elevados para funcionar corretamente. A conta do UAC não pode ver as unidades de rede montadas pelo usuário comum, portanto, para que tudo funcione, eu tenho que montar o compartilhamento via net use de um shell escalonado. Gostaria de automatizar a montagem desse compartilhamento e iniciar o atualizador por meio de um arquivo .bat simples.

Eu provavelmente poderia instruir todo mundo a clicar com o botão direito do mouse em "Executar como Administrador" no arquivo .bat, mas gostaria de manter as coisas o mais simples possível e fazer com que o .bat avise automaticamente o usuário para aumentar seus privilégios.

Como esses computadores não nos pertencem, eu não posso contar com nada como o Powershell sendo instalado, de modo que regras qualquer solução ao longo daquelas linhas e praticamente tem que confiar em coisas que seriam incluídas em um RTM Vista instalar. Eu espero que eu esteja perdendo algo óbvio aqui. :)

    
por jslaker 07.01.2010 / 14:15

9 respostas

8

link

EDIT: Se você está dando ao cliente um único arquivo para executar, por que não criar um RAR auto-extraível com o WinRAR e definir o sinalizador "Exigir administrador" nas opções do SFX? Isso te isenta do seu limite de apenas 1 arquivo, você pode ter todos os recursos que você precisa.

Alternativamente, faça seu SFX usando sua ferramenta SFX favorita e use as ferramentas de elevação acima.

    
por 07.01.2010 / 14:29
4

Se você está preparado para converter para o PowerShell, isso é muito mais fácil de fazer. Este é o meu script " Elevate-Process.ps1 " (com su como alias no meu perfil):

# 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

A detecção de ser elevado também pode ser feita em PSH (assim, você pode verificar a elevação e, em seguida, elevar, se necessário):

$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
}
    
por 07.01.2010 / 15:48
3

aqui está um exemplo de script que eu criei, espero que ajude os outros. É um arquivo bat que solicita permissão ao usuário e, em seguida, se auto-escalona. Ele canaliza alguns vbscript que aciona o prompt do UAC e, em seguida, re-executa o arquivo bat elevado ... link

    
por 08.03.2011 / 23:03
2

Isso é o que você precisa: link

    
por 06.04.2012 / 06:09
1

O FusionInventory.org é uma solução de código aberto usada principalmente por pequenas oficinas. Pode ser como o seu atualizador pessoal de janelas controlado remotamente.

    
por 07.03.2011 / 16:40
0

Nenhuma dessas soluções funciona para um arquivo .cmd que precisa estar ciente dos parâmetros da linha de comando. Coloque isso no início do arquivo .cmd e todos os seus problemas serão resolvidos. (Isto é para pessoas futuras navegando nesta discussão [Eu testei isso no windows XP, 7 Vista e 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---------------------
    
por 21.05.2013 / 01:36
0

Como @emilio disse, esse script é OK, mas não aceita argumentos. Aqui o script modificado para ser compatível com argumentos:

:: 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"
:--------------------------------------
    
por 11.08.2014 / 10:01
0

Se você não puder confiar na instalação do Powershell, poderá usar essa solução no StackOverflow:

auto-elevate com o UAC usando o arquivo em lote

Não requer nada para ser instalado e é executado fora da caixa. Se você precisar preservar os argumentos da linha de comando, considere esta atualização.

    
por 20.03.2013 / 16:04
-1

Já experimentou o comando runas ?

    
por 07.01.2010 / 14:24