Elevare UAC tramite file .bat?


10

Piuttosto semplice a cui ho problemi a trovare una risposta.

serverfault in precedenza mi ha aiutato a trovare un modo per automatizzare gli aggiornamenti di Windows senza utilizzare WSUS. Funziona in modo fantastico, ma per eseguirlo sulla rete, devi prima montare un'unità condivisa. È abbastanza semplice XP poiché basta montare l'unità ed eseguire il programma di aggiornamento.

Su Vista e W7, tuttavia, tutto deve essere fatto con privilegi elevati per funzionare correttamente. L'account UAC non può vedere le unità di rete montate dall'utente normale, quindi per far funzionare tutto, devo montare la condivisione tramite net useuna shell escalation. Vorrei automatizzare il montaggio di questa condivisione e l'avvio del programma di aggiornamento tramite un semplice file .bat.

Probabilmente potrei semplicemente istruire tutti a fare clic con il pulsante destro del mouse su "Esegui come amministratore" sul file .bat, ma vorrei mantenere le cose il più semplici possibile e avere automaticamente il .bat che chiede all'utente di aumentare i propri privilegi.

Dal momento che questi computer non ci appartengono, non posso contare su niente come l'installazione di Powershell, quindi questo regola qualsiasi soluzione lungo quelle linee e praticamente deve fare affidamento su cose che sarebbero incluse in un'installazione di RTM Vista. Spero di perdere quasi sempre qualcosa di ovvio qui. :)

Risposte:


8

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

EDIT: Se stai dando al cliente un singolo file da eseguire, perché non creare un RAR autoestraente con WinRAR e impostare il flag "Richiedi amministratore" nelle opzioni SFX? Questo ti assolve dal limite di 1 solo file, puoi avere tutte le risorse di cui hai bisogno.

In alternativa, crea il tuo SFX usando il tuo strumento SFX preferito e usa gli strumenti di elevazione sopra.


Lo terrò a mente, ma, ancora una volta, sto cercando di evitare l'installazione di qualcosa in più in quanto queste macchine appartengono a terze parti.
jslaker,

Credo che tu possa usarli senza installarli, basta imballarli accanto al tuo file batch.
ta.speot.is

Ci sono diversi file nel download, ma sembra che tutto ciò di cui hai bisogno per le tue esigenze sia elevate.cmdeelevate.vbs
Sospeso fino a nuovo avviso.

Se riesco a confezionare tutto questo in modo abbastanza autonomo / portatile, potrebbe funzionare. Lo guarderò più da vicino quando avrò un po 'più di tempo dopo oggi.
jslaker,

Sebbene ciò possa teoricamente rispondere alla domanda, sarebbe preferibile includere qui le parti essenziali della risposta e fornire il collegamento come riferimento.
Mark Henderson,

4

Se sei pronto per la conversione in PowerShell, è molto più semplice. Questo è il mio " Elevate-Process.ps1" script (con sucome alias nel mio profilo):

# 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

Il rilevamento dell'elevazione può essere eseguito anche in PSH (quindi è possibile verificare l'elevazione e quindi elevare se necessario):

$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
}

Ho pensato che Powershell potesse fare questo, ma ancora una volta, non posso fare affidamento sull'installazione di Powershell, e ho bisogno di qualcosa come il fuoco e dimenticare il più possibile.
jslaker,

@jslaker: questo può certamente essere un problema con Vista / 2008. Ma PSH è incluso in Win7 / 2008R2, quindi dovrebbe essere più semplice. In una situazione aziendale, questa potrebbe essere la spinta per ottenere un lancio?
Richard,

Bene, non è una situazione aziendale. C'è di più nella domanda originale che ho collegato, ma la versione breve è che siamo un'officina di riparazione per PC, e questo è fondamentalmente tutto cercando di aggirare il fatto che la licenza WSUS ti proibisce di usare WSUS per distribuire aggiornamenti su macchine che non lo sono concesso in licenza alla tua organizzazione. Queste sono tutte macchine del cliente che potrebbero eseguire qualsiasi cosa da XP RTM in poi. Questo è il motivo per cui non posso davvero fare affidamento su nulla che venga installato in un'installazione RTM di un determinato sistema operativo.
jslaker,

Se non puoi fare affidamento sull'installazione di Powershell, controlla la risposta che ho fornito di seguito.
Matt

3

ecco un esempio di script che ho ideato, spero che aiuti gli altri. È un file bat che richiede all'utente l'autorizzazione e quindi si intensifica. Esegue il pipe di vbscript che attiva il prompt UAC e quindi esegue nuovamente il file bat elevato ... http://jagaroth.livejournal.com/63875.html



1

FusionInventory.org è una soluzione open source utilizzata principalmente dalle piccole officine di riparazione. Può essere come il tuo aggiornamento personale di Windows controllato a distanza.


0

Nessuna di queste soluzioni funziona per un file .cmd che deve essere a conoscenza dei parametri della riga di comando. Mettilo all'inizio del file .cmd e tutti i tuoi problemi saranno risolti. (Questo è per le persone future che navigano su questo thread [Ho provato questo su 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---------------------

0

Come ha detto @emilio, quello script è OK ma non accetta alcun argomento. Ecco lo script modificato per essere compatibile con gli argomenti:

:: 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

Se non puoi fare affidamento sull'installazione di Powershell, puoi prendere questa soluzione su StackOverflow:

elevazione automatica con UAC utilizzando il file batch

Non richiede nulla da installare e si esaurisce immediatamente. Se è necessario conservare gli argomenti della riga di comando, prendere in considerazione questo aggiornamento.


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.