Using a variable in Reg Queries - batch-file

I have the below which is meant to do the following:
Work out all the SIDs in HKEY_USERS and then use that variable in reg query to check for the existance of a key for each HKEY_USER. However, it is telling me it is an invalid key because it basically just misses out the %%~na when it sets hkeyuserpath and then fails on the reg query. What am I doing wrong?
for /f %%a in ('reg query HKEY_USERS') do (
echo %%~na
set hkeyuserpath="HKEY_USERS\%%~na\Software\Microsoft\Windows\CurrentVersion\Run"
reg query %hkeyuserpath% /v *WhatIamLookingfor*
if "%ERRORLEVEL%" EQU "0" goto HELLO
if "%ERRORLEVEL%" EQU "1" goto GOODBYE
:HELLO
echo Hello
GOTO END
:GOODBYE
GOTO END
)
:END
pause

You're setting hkeyuserpath inside of a for loop, so you have to use delayedexpansion to access the variable.
setlocal enabledelayedexpansion
for /f %%a in ('reg query HKEY_USERS') do (
echo %%~na
set hkeyuserpath="HKEY_USERS\%%~na\Software\Microsoft\Windows\CurrentVersion\Run"
reg query "!hkeyuserpath!" /v *WhatIamLookingFor*
if not errorlevel 1 (
Echo(Hello & goto :end
) ELSE (
Echo(Goodbye
)
)
:end
pause

Related

For /F binary reg value neq (result = always success)

What I'm I missing?
I try to grab a binary key value from UserPreferencesMask, the binary value is 9032078010000000 (or hex:90,32,07,80,10,00,00,00 in regedit).
Result %%A does print 9032078010000000, but when I use this result in/with if %% NEQ or EQU I always goto:HEX_okay.
for /f "skip=2 tokens=3 delims= " %%A in ('reg query "HKCU\Control Panel\Desktop" /f UserPreferencesMask /d /T REG_BINARY') do (
echo.RESULT="%%A"
REM if %%a NEQ 9032078010000000 goto FiX
if %%A EQU 9032038010000000 goto HEX_okay
goto:FiX
)
I use skip=2 because I don't use the first 2 lines,
and delims= " to skip to the 3rd token, sort of speak...
edit:
The UserPreferencesMask has to be 9032078010000000 (binary value), if not, change it to this specific binary value (use reg add).
ie. REG.exe ADD "HKCU\Control Panel\Desktop" /V "UserPreferencesMask" /T REG_BINARY /D "9032078010000000" /F
I also tried:
for /f "tokens=3" %%i in ('reg query "HKCU\Control Panel\Desktop" /v UserPreferencesMask /t REG_BINARY') do (
echo.RESULT="%%i"
IF NOT %%i equ 9032038010000000 goto FiX
IF %%i equ 9032038010000000 goto HEX_okay
goto:DO_NOTING
)
...But with same result and changing equ into == doesn't help either.
when I change the value for UserPreferencesMask in regedit and place aa (or what ever) I do get some result; goto FiX. BUT when I just add some numbers (in regedit) then I always goto HEX_okay, so annoying :'(
These next changes (below) don't help either, then it's always, goto FIX:
IF NOT "%%i"=="9032038010000000" goto FiX
IF "%%i"=="9032038010000000" goto HEX_okay
These next lines do seem to "work", WELL SORT OFF:
when I change the binary value of "UserPreferencesMask" like a lot than just 1 or 2 digits, then it does seem to work as expected...
Weird and not completely 'monkey proof', it's NOT always doing as expected.
for /f "skip=2 tokens=3 delims= " %%i in ('reg query "HKCU\Control Panel\Desktop" /F "UserPreferencesMask" /D /C /E /T REG_BINARY') do (
echo.RESULT="%%i"
IF NOT %%i equ 9032038010000000 goto FiX
IF %%i equ 9032038010000000 goto HEX_okay
goto:NO_UserPreferencesMask
)
PS. I can use for /f "tokens=3" for the same result though
This workaround does seem to function though:
reg query "HKCU\Control Panel\Desktop" /F "UserPreferencesMask" /D /C /E /T REG_BINARY | find /i "9032078010000000"
if errorlevel 1 goto FiX
if errorlevel 0 goto HEX_okay
Here's how I would do it using Reg.exe in a For loop:
#Echo Off
Set "DUPM=9032078010000000"
Set "MASK="
For /F "EOL=H Tokens=2*" %%A In (
'Reg Query "HKCU\Control Panel\Desktop" /V UserPreferencesMask'
) Do If /I Not "%%B"=="%DUPM%" Set "MASK=%%B"
If Not Defined MASK GoTo HEX_okay
:FiX
Echo The value data %MASK% needs fixing!
Pause
GoTo :EOF
:HEX_okay
Echo The value data matches %DUPM%!
Pause
GoTo :EOF
EditBased upon your comment, and given that you're still not using the Reg Query options correctly/efficiently, here is how you should perform that task:
#Echo Off
Reg Query "HKCU\Control Panel\Desktop" /V UserPreferencesMask|Find /I "9032078010000000" >Nul && GoTo HEX_okay
:FiX
Echo The value data needs fixing!
Pause
GoTo :EOF
:HEX_okay
Echo The value data matches!
Pause
GoTo :EOF
Side note: as mentioned in my comments why aren't you simply adding the key? If the existing key matches, overwriting it will not matter, if it doesn't you've changed it:
Reg Add "HKCU\Control Panel\Desktop" /V UserPreferencesMask /T REG_BINARY /D 9032078010000000 /F>Nul

Trouble with using For variables within for loop Batch

I am having trouble with a bit of code, I don't really know how to describe it
but I can explain what doesn't work
FOR /D /r "%cd%\files\" %%G in ("*") DO (
echo In folder: %%~nxG
set /a count=1
echo %%~fG
For /R "%%~fG" %%B in ("*.mp3") do (
call :subroutine "%%~nB"
) & echo. >>%archive%.txt
)
just if you want to know what the subroutine does:
:subroutine
echo %count%:%1>>%archive%.txt
echo %count%: %1
set /a count+=1
GOTO :eof
I figured out that it doesn't read the %%~fG inside the second for loop.
Can someone please help me.
I am using SETLOCAL EnableDelayedExpansion
Thank you in advance.
Unfortunately you'll need another subroutine as for options are parsed before outer for tokens. Check the following example:
#echo off
echo :::ATTEMPT 1:::
for %%a in (z) do (
rem the expected delimiter is z and result should be ++::%%a
for /f "delims=%%a tokens=1,2" %%A in ("++z%%%%az--") do echo %%A::%%B
)
echo :::ATTEMPT 2:::
for %%a in (z) do (
call :subr "%%~a"
)
exit /b
:subr
rem the expected delimiter is z and result should be ++::%%a
for /f "delims=%~1 tokens=1,2" %%A in ("++z%%%%az--") do echo %%A::%%B
the output is:
:::ATTEMPT 1:::
++z::zz--
:::ATTEMPT 2:::
++::%%a
As you can see in the first attempt the %%a symbols are taken as delimiters. But subroutine arguments are parsed imminently so they can be used.
To make your code work you can try with:
FOR /D /r "%cd%\files\" %%G in ("*") DO (
echo In folder: %%~nxG
set /a count=1
echo %%~fG
call ::innerFor "%%~fG"
)
...
exit /b %errorlevel%
:innerFor
For /R "%~1" %%B in ("*.mp3") do (
call :subroutine "%%~nB"
) & echo. >>%archive%.txt
For /R "%%~fG" %%B in ("*.mp3") do (
Sadly, for/r can't be run with a variable as the dirname.
I'd suggest
call :anothersubroutine "%%~fG"
and
:anothersubroutine
For /R "%~1" %%B in ("*.mp3") do (
but I've not tried it. Perhaps you'd need to set %%~fG into a variable and use %var% (not tried that either...)

Batch file for Services Start and stop

I am working on a batch file in which I wanted to stop one service and then another and after that will restart the services simultaneously.
Below is the sample code:
for /F "tokens=*" %%A in (servers_stop_All.txt) do (
echo %%A >> "log\MyService_stop_log_%datetime%.txt"
sc \\%%A stop MyService >> "log\MYService_stop_log_%datetime%.txt")
:CHECK1
for /F "tokens=3 delims=: " %%H in ('sc query "MyService" ^| findstr " STATE"') do (
if /I "%%H" EQU "STOPPED" (
GOTO :STOP_JBOSS
) ELSE (
GOTO :CHECK1
)
)
:STOP_JBOSS
for /F "tokens=*" %%A in (servers_stop_All.txt) do (
echo %%A >> "log\jboss_stop_log_%datetime%.txt"
sc \\%%A stop jboss_qa >> "log\jboss_stop_log_%datetime%.txt"
)
The first service is getting stopped but it is unable to check for the condition and going to next activity.
Next code snippet could help (crucial points are commented, see all rem in code):
#ECHO OFF
SETLOCAL EnableExtensions DisableDelayedExpansion
rem obtain %datetime% variable in locale independent yyyymmddHHMMSS format
for /f "tokens=2 delims==" %%G in (
'wmic OS get localdatetime /value') do set "datetime=%%G"
set "datetime=%datetime:~0,14%"
rem loop: read server list and stop services
for /F "tokens=*" %%A in (servers_stop_All.txt) do (
set "server=%%A"
call :stopAService MyService
If errorlevel 1 (
rem %server%: MyService unknown at all
) else (
rem %server%: MyService stopped succesfully
call :stopAService jboss_qa
)
rem finish manipulation for particular server here
)
GOTO :continue
:stopAService
rem subroutine to stop a service and wait until it's state is not STOPPED
rem input parameter: service name
echo %server% >> "log\%~1_stop_log_%datetime%.txt"
sc \\%server% stop %~1 >> "log\%~1_stop_log_%datetime%.txt")
rem SC command would raise errorlevel >0 in case of no success
rem 1062: The service has not been started.
If %errorlevel% EQU 1062 exit /B 0
rem 1060: The specified service does not exist as an installed service.
If %errorlevel% EQU 1060 exit /B 1060
:CHECK1
rem add some time to wait for state change from "STOP_PENDING" to "STOPPED"?
>NUL TIMEOUT /T 5 /NOBREAK
for /F "tokens=3 delims=: " %%H in ('sc query "%~1" ^| findstr "STATE"') do (
if /I "%%H" EQU "STOPPED" (
rem Success
) ELSE (
GOTO :CHECK1
)
)
rem return from subroutine with exit code 0
exit /B 0
:continue
rem finish script here

Issues with batch file to search registry and edit

I'm not so new to batch scripting and have done a small amount of scripts for various other things but this script has stumped me.
I've actually pulled this idea from somewhere else as I'm not that deep into the for commands just yet.
What I'm trying to do with this script is search every subkey within the HKU rootkey for a specific subkey path. If that subkey path exists it'll modify a key value within that subkey path. But it seems to keep failing with no error.
This is what I have right now:
for /f %%a in ('reg query hku') do call :loop1 %%a
goto :end
:loop1
for /f %1 in (reg query %1\software\microsoft\dynamics) do call :loop2 %%b
goto :end
:loop2
if Errorlevel 1 goto :error
reg add %1\6.0\configuration /v configurationfile /t reg_sz /d \ /f
goto :end
:error
echo Error has occurrd.
goto :end
:end
Pause
When I run this batch I get the following.
c:\Users\-username-\Desktop\test>for /F %a in ('reg query hku') do call :loop1 %a
c:\Users\-username-\Desktop\test>call :loop1 HKEY_USERS\.DEFAULT
c:\Users\-username-\Desktop\test>for /f HKEY_USERS\.DEFAULT in (reg query HKEY_USER
S\.DEFAULT\software\microsoft\dynamics) do call :loop2 %b
c:\Users\-username-\Desktop\test>
It seems like it just stops running? when I check the errorlevel after it runs it returns "0" so I'd think I'd at least see the error message come up?
Am I missing something small I'm just looking over?
Run this to start with - see if what it returns is helpful to you:
This may need a later version of Windows - I'm not sure of the reg query options for earlier windows.
#echo off
for /f "delims=" %%a in ('reg query hku /s /f data /k ^| find /i "\software\microsoft\dynamics" ') do echo "%%a"
You need GOTO :eof to return from the subroutines.
for /f %%a in ('reg query hku') do call :loop1 "%%a"
pause
goto :eof
:loop1
for /f "%~1" in (reg query "%~1\software\microsoft\dynamics") do call :loop2 "%%b"
goto :eof
:loop2
if Errorlevel 1 echo Error has occurred. & pause & exit /B 1
reg add "%~1\6.0\configuration /v configurationfile" /t reg_sz /d \ /f
goto :eof
I found the bug(s). It was two places. RGuggiesberg, you are right. I needed the EOF in there. As foxidrive points out, the first line of "loop1" had some syntax issues. I was confusing myself.
Replaced:
for /f %1 in ('reg query %1\software\microsoft\dynamics') do call :loop2 %%b
with:
for /f %%b in ('reg query %1\software\microsoft\dynamics') do call :loop2 %%b
Now it's working fine. Thanks for the pointers!

Check registry values in windows batch

I would like to check the existence of some windows registry entries and their values in a .bat file.
So far I managed to check the existence:
#echo off
set SMB2_REGKEY=HKLM\SYSTEM\CurrentControlSet\services\LanmanWorkstation\Parameters
set SMB2_REGVAL1=FileInfoCacheLifetime
set SMB2_REGVAL2=FileNotFoundCacheLifetime
set SMB2_REGVAL3=DirectoryCacheLifetime
REM Check for presence of key first.
reg query %SMB2_REGKEY% /v %SMB2_REGVAL1% 2>nul || (echo Error! & exit /b 1)
reg query %SMB2_REGKEY% /v %SMB2_REGVAL2% 2>nul || (echo Error! & exit /b 1)
reg query %SMB2_REGKEY% /v %SMB2_REGVAL3% 2>nul || (echo Error! & exit /b 1)
How can I now check that the values of the three values (FileInfoCacheLifetime, FileNotFoundCacheLifetime, DirectoryCacheLifetime) are set to zero?
#echo off
setlocal enableextensions enabledelayedexpansion
set "key=HKLM\SYSTEM\CurrentControlSet\services\LanmanWorkstation\Parameters"
for %%v in (FileInfoCacheLifetime FileNotFoundCacheLifetime DirectoryCacheLifetime) do (
set "%%~v="
for /f "tokens=3" %%a in ('reg query "%key%" /v "%%~v" 2^>nul ^| find "REG_DWORD"') do set /a "%%~v=%%a"
if not defined %%~v (
echo %%~v is not defined
) else if not !%%~v! equ 0 (
echo %%~v is not correctly defined
) else (
echo %%~v is correctly defined
)
)
endlocal

Resources