Batch

Non Sequitur: Creating Dynamic Variables on the Fly in Batch

I’m only mentioning this because of something that came up recently and I thought it was kind of neat.

To keep things simple, I’m going to break this up into a few posts:

  1. Batch
  2. VBScript
  3. PowerShell

 

Batch

Maybe 5 years ago, before I dunked my head into the vat of PowerShell Kool-Aid™ (or is it ­®?), I was doing some work in the registry on various machines to get some specific data.  I thought it would be neat to create a function that would allow me to reference the data by calling on the value name.

I came up with this little number:

@echo off
setlocal enabledelayedexpansion

rem This happens to be Microsoft Visual C++ 2010 x64 Redistributable - 10.0.40219 - everyone has that ! 😉
Set _Key=HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{1D8E6291-B0D5-35EC-8441-6616F567A0F7}
Set _QueryValues=Publisher DisplayName DisplayVersion InstallSource

rem execute to generate variables dynamically
For %%b in (!_QueryValues!) do ( for /F "usebackq tokens=2*" %%c in (`reg query "!_Key!" /v "%%b"`) do (set %%b=%%d) )

rem validate dynamicallly generated variables
For %%e in (!_QueryValues!) do ( echo [%%e] is [!%%e!] )

:end
rem clear dynamically generated variables
For %%e in (!_QueryValues!) do (Set %%e=)
set _QueryValues=
set _Key=
endlocal
pause

Which allowed me to do things like this:

echo Publisher is [!Publisher!]
echo DisplayName is [!DisplayName!]
echo DisplayVersion is [!DisplayVersion!]
echo InstallSource is [!InstallSource!]

Throughout the script wherever I needed to reference one of those varaibles.

Worked like a charm for my needs then and I still think it’s pretty slick.

 

Good Providence!

Advertisements

Applying Hotfix 3143760 for Windows ADK v1511

Although I’m moving full-steam-ahead with PowerShell, I regularly fall back on batch for really simple things mostly because I’m comfortable with the ‘language.’   (A little too comfortable maybe.)

I needed to apply hotfix KB3143760 on a handful of machines so I pulled the instructions from the KB, put them into a batch file and executed from the central repository since I had already previously downloaded the files.

@echo off
rem can be amd64 or x86
Set _Arch=x86
Set _WIMPath=%ProgramFiles(x86)%\Windows Kits\10\Assessment and Deployment Kit\Windows Preinstallation Environment\%_Arch%\en-us\winpe.wim
Set _MountPoint=%SystemDrive%\WinPE_%_Arch%\mount
Set _ACLFile=%SystemDrive%\WinPE_%_Arch%\AclFile

if /i [%_Arch%]==[amd64] (Set _Schema=\\path\to\schema-x64.dat)
if /i [%_Arch%]==[x86] (Set _Schema=\\path\to\schema-x86.dat)

if not exist "%_WIMPath%" echo. & echo ERROR: WIM NOT FOUND&&goto end
if not exist "%_Schema%" echo. & echo ERROR: SCHEMA NOT FOUND&&goto end
if not exist "%_MountPoint%" mkdir "%_MountPoint%"
if exist "%_ACLFile%" del /q "%_ACLFile%"
if not exist "%_WIMPath%.ORIG" echo f | xcopy "%_WIMPath%" "%_WIMPath%.ORIG" /V /F /H /R /K /O /Y /J
if %ERRORLEVEL% NEQ 0 echo ERROR %ERRORLEVEL% OCCURRED&&goto end

:mount
dism /Mount-Wim /WimFile:"%_WIMPath%" /index:1 /MountDir:"%_MountPoint%"

:backuppermissions
icacls "%_MountPoint%\Windows\System32\schema.dat" /save "%_ACLFile%"

:applyfix
takeown /F "%_MountPoint%\Windows\System32\schema.dat" /A
icacls "%_MountPoint%\Windows\System32\schema.dat" /grant BUILTIN\Administrators:(F)
xcopy "%_Schema%" "%_MountPoint%\Windows\System32\schema.dat" /V /F /Y

:restorepermissions
icacls "%_MountPoint%\Windows\System32\schema.dat" /setowner "NT SERVICE\TrustedInstaller"
icacls "%_MountPoint%\Windows\System32\\" /restore "%_ACLFile%"

echo. & echo.

:confirm
Set _Write=0
set /p _UsrResp=Did everything complete successfully? (y/n):
if /i [%_UsrResp:~0,1%]==[y] (set _Write=1) else (if /i [%_UsrResp:~0,1%]==[n] (set _Write=0) else (goto confirm))

:unmount
echo. & echo.
if %_Write% EQU 1 (
	echo. & echo Unmounting and COMMITTING Changes
	dism /Commit-Wim /MountDir:"%_MountPoint%"
	dism /Unmount-Wim /MountDir:"%_MountPoint%" /commit
) else (
	echo. & echo Unmounting and DISCARDING Changes
	dism /Unmount-Wim /MountDir:"%_MountPoint%" /discard
)
dism /Cleanup-Wim

:end
if exist "%_ACLFile%" del /q "%_ACLFile%"
Set _Write=
Set _UsrResp=
Set _MountPoint=
Set _WIMPath=
Set _Arch=
pause

 

Really simple, and it worked brilliantly.

It’s nowhere nearly as elegant or complete as Keith Garner’s solution, but it got the job done for me lickety split.

 

Good Providence and patch safely!