Elevando o UAC via arquivo .bat?

10

Bem simples que eu estou tendo problemas para encontrar uma resposta.

O serverfault me ajudou anteriormente a encontrar uma maneira de automatizar as atualizações do Windows sem usar o WSUS. Está funcionando de maneira fantástica, mas para executá-lo na rede, você deve primeiro montar uma unidade compartilhada. Isso é bastante simples, pois você monta a unidade e executa o atualizador.

No Vista e W7, porém, tudo isso deve 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, preciso montar o compartilhamento via net useum shell escalado. Gostaria de automatizar a montagem desse compartilhamento e o lançamento do atualizador por meio de um simples arquivo .bat.

Provavelmente, eu 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 solicite automaticamente que o usuário aumente seus privilégios.

Como esses computadores não nos pertencem, não posso contar com nada como o Powershell sendo instalado, de modo que as regras de qualquer solução nesse sentido e praticamente dependam de coisas que seriam incluídas em uma instalação do RTM Vista. Espero estar perdendo algo óbvio aqui. :)

jslaker
fonte

Respostas:

8

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

EDIT: Se você estiver fornecendo ao cliente um único arquivo para execução, por que não criar um RAR auto-extraível com o WinRAR e defina o sinalizador "Requer administrador" nas opções de SFX? Isso absolve você do seu limite de apenas 1 arquivo; você pode ter todos os recursos que precisa.

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

ta.speot.is
fonte
Vou manter isso em mente, mas, novamente, estou tentando evitar instalar algo extra, pois essas máquinas pertencem a terceiros.
jslaker
Eu acredito que você pode usá-los sem instalá-los, apenas empacotá-los ao lado do seu arquivo em lotes.
ta.speot.is
Existem vários arquivos no download, mas parece que tudo o que você precisa para sua exigência seria elevate.cmdeelevate.vbs
Pausado até novo aviso.
Se eu conseguir empacotar tudo isso de forma bastante autônoma / portátil, pode funcionar. Vou dar uma olhada mais de perto quando tiver um pouco mais de tempo hoje.
jslaker
Embora isso possa teoricamente responder à pergunta, seria preferível incluir aqui as partes essenciais da resposta e fornecer o link para referência.
Mark Henderson
4

Se você estiver preparado para converter para o PowerShell, isso é muito mais fácil. Este é o meu Elevate-Process.ps1script " " (com sucomo apelido 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 elevação também pode ser feita no PSH (portanto, você pode verificar a elevação e, se necessário, elevar):

$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
}
Richard
fonte
Achei que o Powershell pode fazer isso, mas, novamente, não posso confiar no Powershell sendo instalado e preciso de algo como fogo e esquecer o possível.
jslaker
@jslaker: isso certamente pode ser um problema com o Vista / 2008. Mas o PSH está incluído no Win7 / 2008R2, para que fique mais fácil. Em uma situação corporativa, essa poderia ser a unidade para lançar?
Richard
Bem, não é uma situação corporativa. Há mais na pergunta original que eu vinculei, mas a versão curta é que somos uma oficina de reparos de PCs, e isso é basicamente tudo o que está tentando contornar que a licença do WSUS proíbe o uso do WSUS para implantar atualizações em máquinas que não são licenciado para sua organização. Essas são todas as máquinas dos clientes que podem estar executando qualquer coisa do XP RTM em diante. É por isso que não posso confiar em nada que esteja sendo instalado que não seria incluído em uma instalação RTM de qualquer sistema operacional.
jslaker
Se você não pode confiar na instalação do Powershell, confira a resposta que eu dei abaixo.
22413 Matt
3

Aqui está um exemplo de script que eu criei, espero que ajude outras pessoas. É um arquivo bat que solicita permissão ao usuário e, em seguida, aumenta a sua capacidade. Ele lança algum vbscript que aciona o prompt do UAC e depois executa novamente o arquivo bat elevado ... http://jagaroth.livejournal.com/63875.html

A coisa
fonte
2

É disso que você precisa: http://sites.google.com/site/eneerge/home/BatchGotAdmin

Emilio
fonte
1
Este script possui um bug menor, não encaminha nenhum parâmetro. Basta colocá-los no comando para chamar seu script assim: echo UAC.ShellExecute "% ~ s0", "% *", "", "runas", 1 >> "% temp% \ getadmin.vbs"
SvenS
1

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

rjt
fonte
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 neste tópico [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---------------------
Grintor
fonte
0

Como o @emilio disse, esse script está 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"
:--------------------------------------
TanisDLJ
fonte
0

Se você não pode confiar na instalação do Powershell, pode usar esta solução no StackOverflow:

elevar automaticamente com o UAC usando o arquivo em lotes

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

Matt
fonte
-1

Você já tentou o runascomando?

Pausado até novo aviso.
fonte