When automating Windows updates across a network, we face a specific UAC limitation in Windows 7/Vista environments. Standard users mounting network drives can't access those resources from elevated processes due to UAC's security isolation.
We'll implement a two-phase batch script that:
- Detects elevation status
- Self-elevates when needed
- Persists network drive mapping across UAC boundary
First, we need to check if we're already running elevated:
@echo off
:: Check for administrative privileges
net session >nul 2>&1
if %errorLevel% == 0 (
echo Running with elevated privileges
) else (
echo Not elevated - requesting UAC
)
Here's the complete solution combining elevation and network operations:
@echo off
:: BatchUAC.cmd - Automated network update solution
:: Check elevation status first
net session >nul 2>&1
if %errorLevel% == 0 goto ELEVATED
:: Not elevated - relaunch with UAC prompt
echo Requesting elevation for network operations...
set batchPath=%~f0
set parameters=%*
powershell -Command "Start-Process cmd -ArgumentList '/c %batchPath% %parameters%' -Verb runAs"
exit /b
:ELEVATED
:: Now running elevated - map network drive
echo Mapping network share...
net use Z: \\server\updates /persistent:no /user:domain\username password
:: Run update process
echo Starting update sequence...
Z:\update_script.cmd
:: Cleanup
net use Z: /delete
exit
- The
net session
check reliably detects admin privileges - PowerShell's
Start-Process
with-Verb runAs
provides clean UAC prompting - Drive mapping must occur after elevation to be visible to the update process
If PowerShell isn't available, we can use VBScript fallback:
@echo off
:: Elevation via VBScript fallback
if "%1"=="ELEV" (goto ELEVATED) else (goto NOT_ELEVATED)
:NOT_ELEVATED
echo Creating temporary VBS script...
echo Set UAC = CreateObject^("Shell.Application"^) > %temp%\elevate.vbs
echo UAC.ShellExecute "cmd.exe", "/c ""%~f0"" ELEV", "", "runas", 1 >> %temp%\elevate.vbs
%temp%\elevate.vbs
del %temp%\elevate.vbs
exit /b
:ELEVATED
:: Elevated operations here...
When implementing this solution:
- Never store credentials in plain text - consider integrated authentication
- Validate all network resources before connection
- Include proper error handling for failed elevation attempts
When automating Windows updates via network shares on post-XP systems, UAC creates a privilege boundary that breaks traditional net use
operations. The key issue is that network drives mapped under standard user credentials become invisible to elevated processes.
Here are three approaches that work on base Windows installations without requiring PowerShell:
@echo off
:: Method 1 - Using runas with saved credentials
if not "%1"=="UAC" (
runas /savecred /user:administrator "%~f0 UAC"
goto :eof
)
net use z: \\server\updates /persistent:yes
start /wait z:\update_script.cmd
The limitation here is the stored credentials may pose security concerns. For temporary elevation:
:: Method 2 - VBScript elevation helper
if not exist "%~dp0elevate.vbs" (
echo Set UAC = CreateObject^("Shell.Application"^) > "%~dp0elevate.vbs"
echo UAC.ShellExecute "%~f0", "", "", "runas", 1 >> "%~dp0elevate.vbs"
)
if "%1"=="elevated" goto elevated
wscript "%~dp0elevate.vbs"
goto :eof
:elevated
net use z: \\server\updates /persistent:yes
start /wait z:\update_script.cmd
For corporate environments with constrained permissions, this hybrid approach handles both 32-bit and 64-bit systems:
@echo off
:: Check admin privileges
fltmc >nul 2>&1 || (
echo Creating temporary elevation script...
echo Set objShell = CreateObject("Shell.Application") > "%temp%\elevate.vbs"
echo objShell.ShellExecute "%~f0", "/elevated", "", "runas", 1 >> "%temp%\elevate.vbs"
wscript "%temp%\elevate.vbs"
del "%temp%\elevate.vbs"
exit /b
)
:: Elevated section
net use * /delete /y
net use z: \\update-server\patches /persistent:no /user:DOMAIN\updater P@ssw0rd
:: Workaround for UAC network visibility
set "UPDATE_CMD=z:\wsusoffline\UpdateInstaller.exe"
if not exist "%UPDATE_CMD%" (
pushd "z:\"
if exist "wsusoffline\UpdateInstaller.exe" (
start "" /wait "wsusoffline\UpdateInstaller.exe"
)
popd
) else (
start "" /wait "%UPDATE_CMD%"
)
1. Always use /persistent:no
for temporary network connections to avoid credential caching
2. The fltmc
check is more reliable than other admin detection methods
3. For Windows 10/11, consider adding net session >nul 2>&1
as an additional privilege check
For environments where VBScript is disabled, this JScript hybrid can work:
@if (@CodeSection == @Batch) @then
@echo off
cscript //nologo //e:JScript "%~f0" %*
goto :EOF
@end
// JScript elevation section
var shell = new ActiveXObject("Shell.Application");
shell.ShellExecute("cmd.exe", "/c \"" + WScript.ScriptFullName + "\"", "", "runas", 1);