I'm writing a batch file and I need to read the values Hidden and Showsuperhidden in the registry, and put them into variables i guess. I have this so far:
reg query HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced/vHidden
I'm not sure how all this works but I'm reading up on it as well.
parsing reg query result is a pain.
Here's how you can do it :
for /f "tokens=2,*" %%a in ('reg query HKEY_CURRENT_USER\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced /v "Hidden" ^| findstr Hidden') do set hiddenvalue=%%b
Related
i want to export HKEY_LOCAL_MACHINE\SOFTWARE\ABC\EFGH string XYZ value 12. i looked into regedit /e and Reg export. it gives options to export till HKEY_LOCAL_MACHINE\SOFTWARE\ABC\EFGH, but not my string value XYZ.
I can think of no native method of exporting just a particular value with its data directly as a .reg file.
The best advice would be that you parse the output from reg query for your particular value data, and save it as a reg add command to another batch file. Then when, or if, you need to replace that value data with the previously saved data, you can just run that saved batch file.
Below is a basic example, (designed only for use with value type REG_SZ). I've used a common registry subkey and value for demonstration purposes, (because yours was not clear to me); please replace those on lines 4 and 5 as per your specific requirements:
#Echo Off
SetLocal EnableExtensions DisableDelayedExpansion
Set "RegistryKey=HKEY_CURRENT_USER\Control Panel\Desktop"
Set "ValueName=Wallpaper"
Set "ValueData="
For /F "Tokens=*" %%G In ('%SystemRoot%\System32\reg.exe Query "%RegistryKey%"
/V "%ValueName%" 2^>NUL ^| %SystemRoot%\System32\findstr.exe /R "\<REG_SZ\>"'
) Do (Set "ValLine=%%G" & SetLocal EnableDelayedExpansion
For /F "UseBackQ Tokens=1,*" %%H In ('!ValLine:*%ValueName%^=!'
) Do EndLocal & Set "ValueData=%%I")
If Defined ValueData Echo #%%SystemRoot%%\System32\reg.exe Add "%RegistryKey%"^
/V "%ValueName%" /T REG_SZ /D "%ValueData:"=\"%" /F 1^>NUL 1>"%ValueName%.cmd"
If the string value is successfully found, its data will be saved to a local variable %ValueData%, for further use within the script if required. In addition, a batch file with the name of the registry value, should be output to the current directory. If you wish to change that name or location, please replace %ValueName%.cmd on the last line as needed. To restore the data at a later time just run the saved batch file.
Trying to record a user client IP for a remote session. Currently have a little batch file recording logon times, and hostname. Need to also include the client IP address;
Currently using this;
reg query "HKEY_CURRENT_USER\Volatile Environment" /s > %temp%\IPINFO.txt
findstr /L ViewClient_IP_Address %temp%\IPINFO.txt > %temp%\IPRESULTS.txt
FOR /F “tokens=* delims= ” %%a in (%temp%\IPRESULTS.txt) do set IP=%%a
del %temp%\IPRESULTS.txt
set IP=%IP%
echo Login ,%Date%,%Time%,%computername%,%clientname%,%IP% >> Y:\%username%.csv
The registry key viewclient_ip_Address has the information I need, but the registry folder it sits within changes name each time so I'm having to export the whole directory and then filter for the key itself.
I just need to add the information from that IPRESULTS.txt into my end .csv file but struggling with writing it up.
Any help appreciated.
Is this what you're looking for? (The for-loop runs the command and parses it's output in memory)
For /F "EOL=HTokens=2*" %%H In ('^""%__AppDir__%reg.exe" Query "HKCU\Volatile Environment" /V ViewClient_IP_Address 2^>NUL^"')Do Set "IP=%%~I"
To find out more about how to use reg.exe with query, open up a Command Prompt window and enter reg query /?
If, as you've stated in your question, the required value and data is located under HKEY_CURRENT_USER\Volatile Environment but within a variable/unknown, subkey name, the help information should show you that you can use the /F option to locate your known value name, ViewClient_IP_Address, if you specify that the search is to locate a value using /V, it should retrieve the line you need.
For example, at the Command Prompt:
Reg Query "HKCU\Volatile Environment" /S /F "ViewClient_IP_Address" /V
Returns:
C:\Users\smith_ll>Reg Query "HKCU\Volatile Environment" /S /F "ViewClient_IP_Add
ress" /V
HKEY_CURRENT_USER\Volatile Environment\UnknownSubKey
ViewClient_IP_Address REG_SZ 192.168.1.15
End of search: 1 match(es) found.
You can then put that command into your for-loop, and pass its output through find.exe to isolate the line you need to parse. The underscore, for instance, looks unique to just the line you need. As we're already excluding any line beginning with H ,(with EOL=H), it will not match the End of search: 1 match(es) found. line:
Example:
For /F "EOL=HTokens=2*" %%H In ('^""%__AppDir__%reg.exe" Query "HKCU\Volatile Environment" /S /F "ViewClient_IP_Address" /V 2^>NUL^|"%__AppDir__%find.exe" "_"^"')Do #Set "IP=%%~I"
If you don't like the super long line, you can split into more using the caret:
For /F "EOL=HTokens=2*" %%H In ('^""%__AppDir__%reg.exe" Query^
"HKCU\Volatile Environment" /S /F "ViewClient_IP_Address" /V 2^>NUL^
^|"%__AppDir__%find.exe" "_"^"')Do #Set "IP=%%~I"
I basically want to know if its possible for me to get a path from the registry and use it in a Batch file.
Basically what I have is some code I've gather from this site
#echo off
reg query "HKLM\SOFTWARE\Wow6432Node\Rockstar Games\Grand Theft Auto V" /v "InstallFolder"
That line returns
HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Rockstar Games\Grand Theft Auto V
InstallFolder REG_SZ D:\Rockstar Games\Grand Theft Auto V
All I want to do here is add the path of GTA to the batch file so I can then launch the executable (PlayGTAV.exe) through the batch file. The reason I'm not using the path i already know is because I want this batch file to work on some friends computers too.
#ECHO OFF
SETLOCAL
FOR /f "delims=" %%a IN ('reg query "HKLM\SOFTWARE\Embarcadero\Interbase\Servers" ^|find " REG_SZ "') DO (
SET "target=%%a"
)
SET "target=%target:*REG_SZ =%"
ECHO "%target%"
GOTO :EOF
This should demonstrate how - I've obviously used a different key.
The ^|find... finds the appropriate line containing the REG_SZ (the caret is used to tell cmd that the piping is of the reg query command, not part of the for) and the for /f "delims=" selects the entire line for application to %%a.
From there, it's simply a matter of applying substringing to the ordinary environment variable target (since substringing of the metavariable %%a is not allowed) - replace any characters before and including the first occurrence of REG_SZ+4spaces with nothing (the string between the = and terminal %
I am trying to query the registry value of an installed application on many servers. I could hardcode the servers in, and have a lot of repetition and it seems to work. But sometimes a list of servers may change, and I'd like to take a more sensible modular approach.
So I can provide a test file with a list of server names, and then query the registry values of all of these servers, outputting them in a logfile.
I think the issue is definitely with my loops/variable storing. Not sure exactly what is going on, but it seems like once I get one set of Registry values, these are outputted for every single server, regardless of their respective registry values.
Not too experience with this kind of scripting, so I have been sort of mashing this together through trial and error, below is what I have so far. Please point out any woeful syntax errors I've made.
So essentially this is to find a McAfee scan engine version installed to each server. The reporting from the McAfee console itself is not always reliable, and I want to check that the contents are successfully pulled down to each server.
There are two registry values required to create a full engine version, so I am required to pull both of these and then combine them into a single string.
At the moment I do get an output that looks correct, but it does not represent what is actually installed to each server. It is like one value is being picked up and then replicated.
On an additional note, this only seems to work when executed in command line. And the first 1-2 times it is ran, no values are pulled up. Get the feeling I am quite far away from a solution.
SET LOGFILE=C:\LogFile.log
For /f %%i in (servers.txt) DO (
for /f "tokens=3" %%a in ('reg query \\%%i\HKLM\SOFTWARE\McAfee\AVEngine /v EngineVersion32Major ^| find /i "EngineVersion32Major"') do set /a major=%%a
for /f "tokens=3" %%b in ('reg query \\%%i\HKLM\SOFTWARE\McAfee\AVEngine /v EngineVersion32Minor ^| find /i "EngineVersion32Minor"') do set /a minor=%%b
echo %%i: %major%.%minor% >> %LOGFILE%
)
Would expect an output like this:
server1 : 5900.5647
server2 : 6000.4589
server3 : 5900.5647
server4 : 5900.5647
Cheers for any help you can provide.
It has nothing to do with for syntax, but how cmd parses scripts. See How does the Windows Command Interpreter (CMD.EXE) parse scripts?
When cmd parses a block (anything within parens), processes it as a single line. So it expands any %var% to its actual content. Changes made to it, are not taken into account until the block is exited. To retrieve new content within a block, you must enable delayed expansion, which forces the parser to evaluate it for every iteration. Also, syntax must be changed from %var% to !var!
Here, also, removed the /a switch from set command, as you are not doing calculations, and you may get results you won't expect (imagine a minor version equal to 0080 that will be treated as octal (invalid) and would break the script). Also, note both var name and var content enclosed in quotes (set "minor=%%b"), to avoid undesired trailing/leading spaces.
More also, I think you don't need the ^| find /i "EngineVersion32Major part, as possibly the key named EngineVersion32Major will content only what you are looking for. And again, enclose data in quotes (never know when a space may appear). You may also change "tokens=3" by "skip=1 tokens=3" to avoid process the heading reg echoes.
Thus
#echo off
SetLocal EnableDelayedExpansion
SET LOGFILE=C:\LogFile.log
for /f %%i in (servers.txt) DO (
for /f "tokens=3" %%a in ('reg query "\\%%i\HKLM\SOFTWARE\McAfee\AVEngine" /v "EngineVersion32Major"') do set "major=%%a"
for /f "tokens=3" %%b in ('reg query "\\%%i\HKLM\SOFTWARE\McAfee\AVEngine" /v "EngineVersion32Minor"') do set "minor=%%b"
echo %%i: !major!.!minor!>>%LOGFILE%
)
EndLocal
Also, this works within a block regardless delayed expansion is enabled or not (note double percent sign)
call echo %%i: %%major%%.%%minor%%>>%LOGFILE%
Another issue, any time a redirection is used within a block, the system opens and closes the file (or stream).
But
#echo off
SetLocal EnableDelayedExpansion
SET LOGFILE=C:\LogFile.log
>>"%LOGFILE%" (
for /f %%i in (servers.txt) DO (
for /f "tokens=3" %%a in ('reg query "\\%%i\HKLM\SOFTWARE\McAfee\AVEngine" /v "EngineVersion32Major"') do set "major=%%a"
for /f "tokens=3" %%b in ('reg query "\\%%i\HKLM\SOFTWARE\McAfee\AVEngine" /v "EngineVersion32Minor"') do set "minor=%%b"
echo %%i: !major!.!minor!
)
)
EndLocal
Processes all commands in the block, so the file is opened and closed only once. This may improve performance, specially with large files.
BTW,
>>"%LOGFILE%" (
...
...
)
Is the same as
(
...
...
)>>"%LOGFILE%"
Please use the search facility to locate many SO articles on delayed expansion.
The easy way in your case is to use
call echo %%i: %%major%%.%%minor%% >> %LOGFILE%
So, I've been working on a batch file to collect specific system information, I've run into a road block with opening an INI file that's on the network installation. So obtaining the path is:
for /f "tokens=2*" %%a in ('REG Query "HKCU\SOFTWARE\Zephyr Associates, Inc." /v StyleDir 2^>nul') do set "StyleDir=%%~b"
for /f "tokens=2*" %%a in ('REG Query "HKLM\SOFTWARE\Zephyr Associates, Inc." /v StyleDir 2^>nul') do set "StyleDir=%%~b"
for /f "tokens=2*" %%a in ('REG Query "HKLM\SOFTWARE\Wow6432Node\Zephyr Associates, Inc." /v StyleDir 2^>nul') do set "StyleDir=%%~b"
cd %StyleDir%
So in this scenario, let's say %StyleDir% is //Server/StyleDir/
Later on in the script we read the Style.ini file with the following:
for /f "tokens=2 delims==" %%a in ('findstr SQLiteHome style.ini') do set SQLiteHome=%%a
for /f "tokens=2 delims==" %%a in ('findstr Server style.ini') do set SQL=%%a
for /f "tokens=2 delims==" %%a in ('findstr DataHome style.ini') do set DataHome=%%a
At this point I get an error saying we're unable to read the Style.ini. Within the Style.ini I have the following:
[Default]
DataHome=C:\ProgramData\Zephyr\Data\
SQLiteHome=C:\ProgramData\Zephyr\Data\
[DataBaseList]
Tons of other lines I don't need to read Right now....
Later I populate a txt file that records the information. That script is as follows:
::Output
echo StyleDir: %StyleDir% >> SystemInformation.txt
echo SQLiteHome: %SQLiteHome% >> SystemInformation.txt
echo SQL Server: %SQL% >> SystemInformation.txt
echo DataHome: %DataHome% >> SystemInformation.txt
So is there a special way that I could get this info recorded from the INI file? I've had thoughts about temporarily mapping a network drive, but the problem with that is knowing what network drives are already mapped so that I don't break what's already there. I'm not even 100% sure that this has to do with the UNC path at all, I just know that when the INI is locally on C:\ that it can be read, but on the network it cannot. Any suggestions for what to try?
Another thing I've noticed is that I can open the Style.ini from a batch file just fine, regardless of the location. I just can't Read it for some reason.
You said:
I just know that when the INI is locally on C:\ that it can be read,
but on the network it cannot.
That's not true. You can read ini files with UNCs like this:
\\ServerName\directory\any.ini
The error may be somewhere else, such as unmatched quotes, authentication or missing file. Knowing what the exact error message you get would help debug the precise reason.
Expanded in response to complete error msg:
CMD does not support UNC paths
Implies removing this line
cd %StyleDir%
in your batch file as you cannot cd unless you map to a drive letter first. Consult map /help for details. Or you can avoid cd'ing to that folder by fixing the findstr command to use the UNC directly, such as:
findstr stringToSearch \\full\UNC\path\to\file.ini
Which option you choose will depend on what is being done to the found strings. You mention you are populating those strings, but not where. If populating to a file on the remote server, use the drive map option. If populating locally, then use the UNC option.
I figured it out, all you have to do is use
pushd \\server\dir
instead of
cd \\server\dir
when pointing to the path. Figures it would be something easy. I still get an error, but it'll proceed past it, which is fine by me :-)