10

Pretty straightforward one that I'm having trouble finding an answer to.

serverfault previously helped me with finding a way to automate Windows updates without using WSUS. It's working fantastically, but to run it over the network, you have to first mount a shared drive. That's pretty simple XP since you just mount the drive and run the updater.

On Vista and W7, though, this all has to be done with elevated privileges to work correctly. The UAC account can't see network drives mounted by the regular user, so in order to get everything working, I have to mount the share via net use from an escalated shell. I'd like to automate mounting this share and launching the updater via a simple .bat file.

I could probably just instruct everybody to right click "Run as Administrator" on the .bat file, but I'd like to keep things as simple as possible and have the .bat automatically prompt the user to escalate their privileges.

Since these computers don't belong to us, I can't count on anything like Powershell being installed, so that rules any solution along those lines out and pretty much have to rely on things that would be included in an RTM Vista install. I'm hoping I'm mostly missing something obvious here. :)

jslaker
  • 155

9 Answers9

8

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

EDIT: If you are giving the customer a single file to run, why not create a self extracting RAR with WinRAR and set the "Require Administrator" flag in SFX options? This absolves you of your limit of only 1 file, you can have all the resources you need.

Alternatively make your SFX using your favourite SFX tool and use the elevate tools above.

4

If you are prepared to convert to PowerShell this is much easier to do. This is my "Elevate-Process.ps1" script (with su as alias in my profile):

# 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

Detection of being elevated can also be done in PSH (thus you can check for elevation, and then elevate if needed):

$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
  • 5,374
3

here is an example script I came up with, I hope it helps others. It's a bat file that prompts the user for permission and then escalates itself. It pipes out some vbscript which triggers the UAC prompt and then re-runs the bat file elevated... http://jagaroth.livejournal.com/63875.html

2

This is what you need: http://sites.google.com/site/eneerge/home/BatchGotAdmin

Emilio
  • 31
1

FusionInventory.org is an open source solution mostly used by small repair shops. It can be like your personal remotely controlled windows updater.

rjt
  • 594
0

If you can't rely on Powershell being installed, you can take this solution on StackOverflow:

auto-elevate with UAC using batch file

It does not require anything to be installed and runs out of the box. If you need to preserve the command-line arguments, consider this update.

Matt
  • 101
  • 3
0

None of those solutions work for a .cmd file that needs to be aware of command-line parameters. Put this at the very beginning of the .cmd file and all your problems will be solved. (This is for future people browsing this thread [I have tested this on windows XP, 7 Vista and 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---------------------
mgorven
  • 31,399
Grintor
  • 11
0

As @emilio said, that script is OK but it does not accept any arguments. Here the modified script to be compatible with arguments:

:: 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
  • 121
-1

Have you tried the runas command?