Problem with variables inside a FOR loop

January 26, 2010 at 04:08:03
Specs: Windows XP
Sir:

I am trying to create a batch file that will list installed software on a remote machine. I have written it so that you can query either a single machine or iterate a list of machines using the FOR command. I can not seem to get the variable to expand correctly inside the FOR loop. It returns the name of the list file, rather than the value from the list

What am I doing wrong?

******************************

:: This file will collect software inventory information directly from the registry
:: it will create an output file with the machine name and OS type at the beginning of each block

:: command line auguments: ALL three auguments
:: Single machine example softlist single (machinename) (outputfile)

:: Multiple machine example softlist list (listfile) (outputfile)

set list=
set outfile=
if "%1"==single goto single
if "%1"==list goto proclist
if "%1"==help goto help
if "%1"==/? goto help

:single
set compname=%2
set outfile=%3


reg query HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0 | find "x86 Family" /I
if errorlevel 0 set OStype=32bit
if errorlevel 1 set OStype=64bit
echo %compname% %OStype%>>%outfile%

Reg Query \\%compname%\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /S | find "displayname" /I | find "Update" /V | find "Hotfix" /V >>%outfile%


if %OStype% NEQ 32bit Reg Query \\%compname%\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall /S | find "displayname" /I | find "Software updates" /I /V | find "(KB" /I /V find "hotfix" /I /V >>%outfile%

goto end


:proclist
SETLOCAL ENABLEDELAYEDEXPANSION
set infile=%2
set outfile=%3
FOR /F %%A IN (%infile%) DO (
reg query HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0 | find "x86 Family" /I
if errorlevel 0 set OStype=32bit
if errorlevel 1 set OStype=64bit
echo %compname% %OStype%>>%outfile%
SET VAR1=%VAR1%%%A
Reg Query \\!VAR1!\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /S | find "displayname" /I | find "Update" /V | find "Hotfix" /V >>%outfile%
if "%OStype%"==64bit Reg Query \\!VAR1!\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall /S | find "displayname" /I | find "Update" /V | find "Hotfix" /V >>%outfile%
)
goto end

:help

:: This file will collect software inventory information directly from the registry
:: it will create an output file with the machine name and OS type at the beginning of each block of text

:: command line arguments: ALL three arguments auguments MUST be used!

:: Single machine example softlist single (machinename) (outputfile)

:: Multiple machine example softlist list (listfile) (outputfile)
goto end
:end


See More: Problem with variables inside a FOR loop

Report •

#1
January 26, 2010 at 04:27:14
To get the list to expand, change this:

FOR /F %%A IN (%infile%) DO (

to this:

FOR /F "tokens=*" %%A IN (%infile%) DO (


=====================================
Helping others achieve escape felicity

M2


Report •

#2
January 26, 2010 at 07:58:42
Thanks,

Now I seem to have a different, but related problem.
I can not set my own variables inside the FOR loop. I am trying to set a variable called OStype inside the FOR loop, and can't seem to make it work. It always come up blank.

:: This file will collect software inventory information directly from the registry
:: it will create an output file with the machine name and OS type at the beginning of each block

:: command line auguments: ALL three auguments
:: Single machine example softlist single (machinename) (outputfile)

:: Multiple machine example softlist list (listfile) (outputfile)

set outfile=
set infile=
set compname=
set OStype=

if /I %1==single goto single
if /I %1==list goto proclist
if /I %1==help goto help
if /I %1==/? goto help

:single
set compname=%2
set outfile=%3


reg query \\%compname%\HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0 | find "x86 Family" /I
IF %ERRORLEVEL%==0 set OStype=32Bit
IF %ERRORLEVEL%==1 set OStype=64Bit
echo %compname% %OStype%>>%outfile%

Reg Query \\%compname%\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /S | find "displayname" /I | find "Update" /V | find "Hotfix" /V >>%outfile%
IF %ERRORLEVEL% == 1 echo Error retrieving 32Bit software key for %compname%

Reg Query \\%compname%\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall /S | find "displayname" /I | find "Update" /V | find "Hotfix" /V >>%outfile%
IF %ERRORLEVEL% == 1 echo Error retrieving 64Bit software key for %compname%
goto :end


:proclist

SETLOCAL ENABLEDELAYEDEXPANSION
set infile=%2
set outfile=%3
FOR /F %%A IN (%infile%) DO (
Set ERRRORLEVEL=
Reg query \\%%A\HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0 | find "x86 Family" /I
IF %ERRORLEVEL%==0 call SET OStype=!32Bit!%%A
IF %ERRORLEVEL%==1 call set OStype=!64Bit!%%A
echo %OStype%
echo %%A %OStype%>>%outfile%
Set ERRRORLEVEL=
Reg Query \\%%A\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /S | find "displayname" /I | find "Update" /V | find "Hotfix" /V >>%outfile%
Set ERRRORLEVEL=
IF %ERRORLEVEL% == 1 echo Error retrieving 34Bit software key for %%A>>%outfile%
Reg Query \\%%A\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall /S | find "displayname" /I | find "Update" /V | find "Hotfix" /V >>%outfile%
IF %ERRORLEVEL% == 1 echo Error retrieving 64Bit software key for %%A>>%outfile%
)
EndLocal
goto :end

:help

:: This file will collect software inventory information directly from the registry
:: it will create an output file with the machine name and OS type at the beginning of each block of text

:: command line arguments: ALL three arguments auguments MUST be used!

:: Single machine example softlist single (machinename) (outputfile)

:: Multiple machine example softlist list (listfile) (outputfile)
goto end
:end


Report •

#3
January 26, 2010 at 08:26:11
Do you use

%

or

!

when manipulating variables inside the FOR /F loop ?


Another thing : what if %1 is empty ?
(same for %2 and %3 btw)


Report •

Related Solutions

#4
January 26, 2010 at 09:01:25
I have been using %. I have not had a chance to even think about what action to take when %1, %2, or %3 are empty. I will most likely jump to the help section in these instances.

Thanks


Report •

#5
January 26, 2010 at 09:52:09
regarding tvc's pertinant question:
echo %OStype%
echo %%A %OStype%>>%outfile%

should prob'ly be:
echo !OStype!
echo %%A !OStype!>>%outfile%


Report •

#6
January 26, 2010 at 10:02:25
Thanks, but I tried that. It just returns !OStype! as the variable contents.

Any ideas?

I really want to thank all you for your responses! It has been very helpful.

Thanks


Report •

#7
January 26, 2010 at 11:04:01
ah, the errorlevel, i missed that, change:
IF %ERRORLEVEL%==0 call SET OStype=!32Bit!%%A
IF %ERRORLEVEL%==1 call set OStype=!64Bit!%%A

to:
IF !ERRORLEVEL!==0 call SET OStype=!32Bit!%%A
IF !ERRORLEVEL!==1 call set OStype=!64Bit!%%A
::debug testing:
echo.errlvl from FIND:!ERRORLEVEL!

the other errorlevels inside the for-loop will need the same mods


Report •

#8
January 26, 2010 at 11:51:22
Here is what I have so far. It still echos !OStype! instead of the value of OStype, which should be either 32Bit, or 64Bit.

Thanks

************************************************************
:proclist

SETLOCAL ENABLEDELAYEDEXPANSION
set infile=%2
set outfile=%3
FOR /F %%A IN (%infile%) DO (
Set !ERRRORLEVEL!=
Reg query \\%%A\HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0 | find "x86 Family" /I
IF !ERRORLEVEL!==0 SET OStype=!32Bit!
IF !ERRORLEVEL!==1 SET OStype=!64Bit!
echo return !OStype! based on Errorlevel
echo %%A !OStype!>>%outfile%
Set !ERRRORLEVEL!=
Reg Query \\%%A\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /S | find "displayname" /I | find "Update" /V | find "Hotfix" /V >>%outfile%
Set !ERRRORLEVEL!=
IF !ERRORLEVEL! == 1 echo Error retrieving 34Bit software key for %%A>>%outfile%
Reg Query \\%%A\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall /S | find "displayname" /I | find "Update" /V | find "Hotfix" /V >>%outfile%
IF !ERRORLEVEL! == 1 echo Error retrieving 64Bit software key for %%A>>%outfile%
)
EndLocal
goto :end
**********************************************************


Report •

#9
January 26, 2010 at 12:20:57
i think it might be here:
IF !ERRORLEVEL!==0 SET OStype=!32Bit!
IF !ERRORLEVEL!==1 SET OStype=!64Bit!

if you have not defined var.s named 32bit and 64bit respectively, OSTYPE will also be undefined from assigning undefined var.s to it.
i think you might have meant to do this:
IF !ERRORLEVEL!==0 SET OStype=32Bit
IF !ERRORLEVEL!==1 SET OStype=64Bit

see if that helps


Report •

#10
January 27, 2010 at 02:34:34
Indeed, that was wrong ...

Just an option, but what you can do is the following (in such cases). Suppose you program is called test.cmd, and issuming it does NOT require manual input:

1. change ECHO OFF into ECHO ON
2. run the script, echo all output : test.cmd > C:\test.log
3. notepad C:\test.log and scroll through the output, in this case you would see:

IF 1==1 SET OStype=


Report •

#11
January 27, 2010 at 05:06:12
I got this thing working just the way I want it. Thanks to all of you for your help and advice. I am post the file here in case anyone else out there needs a tool like this.

Again thanks your all your help.

***********************************************************************
@echo off
:: This file will collect software inventory information directly from the registry
:: it will create an output file with the machine name and OS type at the beginning of each block

:: command line auguments: ALL three auguments
:: Single machine example softlist single (machinename) (outputfile)

:: Multiple machine example softlist list (listfile) (outputfile)

set outfile=
set infile=
set compname=
set OStype=
set error=
IF [%1]==[] GOTO help
ECHO.%1 | FIND "/" >NUL
IF NOT ERRORLEVEL 1 GOTO help
if /I %1==single goto single
if /I %1==list goto proclist
if /I %1==help goto help

rem *******************************************************************************
:single
IF [%2]==[] GOTO help
IF [%3]==[] GOTO help
set compname=%2
set outfile=%3
set ERRORLEVEL=
set error=

Reg query \\%compname%\HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0
IF %ERRORLEVEL%==0 set error=passed
IF %ERRORLEVEL%==1 set error=error
Reg query \\%compname%\HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0 | find "x86 Family" /I
IF %ERRORLEVEL%==0 SET OStype=32Bit
IF %ERRORLEVEL%==1 SET OStype=64Bit
echo %compname% %OStype% >>%outfile%
IF %error%==error echo **** ERROR *** could not determine OS Type for %compname%>>%outfile%
set %ERRORLEVEL%=
Reg Query \\%compname%\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /S | find "displayname" /I | find "Update" /V | find "Hotfix" /V >>%outfile%
IF %error%==error echo **** ERROR *** could not read 32Bit Registry Key for %compname%>>%outfile%
set %ERRORLEVEL%=
Reg Query \\%compname%\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall /S | find "displayname" /I | find "Update" /V | find "Hotfix" /V >>%outfile%
IF %error%==error echo **** ERROR *** could not read 64Bit Registry Key for %compname%>>%outfile%

rem *****************************************************************************************************************************
goto :end


rem *****************************************************************************************************************************
:proclist
if not exist %2 goto help
IF [%3]==[] GOTO help
SETLOCAL ENABLEDELAYEDEXPANSION
set infile=%2
set outfile=%3
FOR /F %%A IN (%infile%) DO (
set !error!=
set !ERRORLEVEL!=
Reg query \\%%A\HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0
IF !ERRORLEVEL!==0 set error=passed
IF !ERRORLEVEL!==1 set error=error
Reg query \\%%A\HKLM\HARDWARE\DESCRIPTION\System\CentralProcessor\0 | find "x86 Family" /I
IF !ERRORLEVEL!==0 SET OStype=32Bit
IF !ERRORLEVEL!==1 SET OStype=64Bit
echo %%A !OStype!>>%outfile%
IF !error!==error echo **** ERROR *** could not determine OS Type for %%A>>%outfile%
set !ERRORLEVEL!=
Reg Query \\%%A\HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall /S | find "displayname" /I | find "Update" /V | find "Hotfix" /V >>%outfile%
IF !error!==error echo **** ERROR *** could not read 32Bit Registry Key for %%A>>%outfile%
set !ERRORLEVEL!=
Reg Query \\%%A\HKEY_LOCAL_MACHINE\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall /S | find "displayname" /I | find "Update" /V | find "Hotfix" /V >>%outfile%
IF !error!==error echo **** ERROR *** could not read 64Bit Registry Key for %%A>>%outfile%
)
EndLocal
goto :end
rem *****************************************************************************************************************************
:help
cls
echo This file will collect software inventory information directly from the registry
echo it will create an output file with the machine name and OS type at the beginning of each block of text
echo .
echo command line arguments: ALL three arguments auguments MUST be used!
echo .
echo Single machine example softlist single (machinename) (outputfile)
echo .
echo Multiple machine example softlist list (listfile) (outputfile)
goto end
:end


Report •

Ask Question