Using FOR Loop and SC Query in CMD Script - windows

Suppose this instruction:
C:\>SC query state= all | find /I "adobe"
The result is:
SERVICE_NAME: AdobeARMservice
DISPLAY_NAME: Adobe Acrobat Update Service
Now I want to obtain the exact argument in this case is "AdobeARMservice"
Here my Script TestLineArgument.bat:
#echo off
cls
REM
REM for /f "delims=" %%# in ('SC query state= all ^| find /I "adobe"') do ( IS NOT WORKING
REM
set "SCQueryState=SC query state ^= all"
set "QueryAdobe=%SCQueryState%^^^| find /I ^"adobe^""
for /f "delims=" %%# in ("%QueryAdobe%") do (
set "THERSERVICE_NAME=%%#"
echo %%#
goto :END_FORSCQUERY
)
:END_FORSCQUERY
REM show the Line "SERVICE_NAME: AdobeARMservice"
echo THERSERVICE_NAME:%THERSERVICE_NAME%
FOR /f "tokens=2" %%# IN ("%THERSERVICE_NAME%") DO (
set "THESERVICE=%%#"
)
REM show the second part "AdobeARMservice"
echo THESERVICE:%THESERVICE%
My Script is not working, I don't know how use FOR with SC Command
Some clue?

#echo off
setlocal enableextensions disabledelayedexpansion
rem Initialize variables
set "serviceName="
set "displayName="
rem Execute the query and retrieve all the SERVICE_NAME lines and
rem the line with the desired display name
for /f "tokens=1,*" %%a in ('
sc query state^= all ^| findstr /i /l /c:"SERVICE_NAME" /c:"Adobe"
') do if not defined displayName if "%%a"=="SERVICE_NAME:" (
set "serviceName=%%b"
) else set "displayName=%%b"
rem Show retrieved data
if defined displayName (
echo %serviceName%
echo %displayName%
) else echo Not found

This method does not work in the manner you were trying to implement, as #MCND answer does, but if "AdobeARMservice" is only returned by sc query state when it is running, this may be useful.
It simply looks for the string "AdobeARMservice" and sets THESERVICE var to the result: If "AdobeARMservice" not found, THESERVICE remains empty. If found it gets value=AdobeARMservice
#echo off
Set "THESERVICE="
For /f %%A in ('sc query state^= all ^| find /i "AdobeARMservice"') do set THESERVICE=%%A
If "%THESERVICE%"=="" echo AdobeARMservice not found
If NOT "%THESERVICE%"=="" echo THESERVICE: %THESERVICE%
pause

My problem was simply...
#echo off
set "SERVICE=Adobe"
for /f "delims=" %%s in ('sc query state^= all ^| find /I "%SERVICE%"') do (
for /f "tokens=2" %%# in ("%%s") do (
echo THESERVICE:%%#
)
)
I tryng to avoid to change the code according to version something like : "Adobe3.2_1" or "Adobe3.2_5" or "Adobe4.5", this snippet of code only...

Related

Execute specific command according to user existence

In a batch file, I need to check if given user exists, then execute different commands according to results.
Username is taken as a parameter during bat file call on cmd.
What I want is something like that:
IF userExists (
do something
) else (
do something else
)
Following code can retrieve number of matching results, but I failed to use it in IF statement.
set username=%1
set searchUser="net user |find /c %username% "
for /F "tokens=*" %%i IN (%searchUser%) do set userCount=%%i
I expect to use userCount in if statement, but failed to do so.
How can I use my userCount in if statement, or is there a better approach for this?
Firstly, %username% is a predefined environment variable, select somethig else like myuser
As per your original attempt using the count.
#echo off
set myname=%~1
for /F %%i IN ('net user ^| find /I /C "%myname% "') do (
if not "%%i"=="0" (
echo found %%i Matches of username
) else (
echo %%i matches found.
)
)
Else, using %errorlevel%
#echo off
set "myuser=%~1"
net user |findstr /I /R /C:"\<%myuser%\>"
if not "%errorlevel%"=="0" (
echo %myuser% does NOT exist!
) else (
echo %myuser% exists!
)
Alternatively in a for loop:
#echo off
set "myuser=%~1"
for /f %%i in ('net user ^| findstr /I /R /C:"\<%myuser%\>"') do (
if /i "%%i"=="%myuser%" echo myusers exists!
) else (
echo %myuser% does NOT exist!
)
)
If you are simply trying to determine if a particular user account exists, instead of how many matching user names exist on the same PC, then I'd suggest this wmic alternative:
#Echo Off
Set "ProfilePath="
For /F "Skip=1Delims=" %%A In ('WMIC UserAccount Where^
"LocalAccount='TRUE' And Name='%~1'" Get SID 2^>Nul') Do For /F %%B In ("%%A"
) Do For /F "Tokens=2Delims==" %%C In ('WMIC Path Win32_UserProfile Where^
"SID='%%B' And Special!='True'" Get LocalPath /Value 2^>Nul'
) Do For /F "Tokens=*" %%D In ("%%C") Do Set "ProfilePath=%%D"
If Defined ProfilePath (Echo User Profile %1 exists at %ProfilePath%) Else (
Echo User Profile %1 does not exist)
Pause
The If command along with the Pause are included just to show you an If|Else structure for your further commands, (they could obviously be modified/changed as required).
If you do not need to know and/or access the user profile path, you can simplify the command considerably:
#Echo Off
WMIC UserAccount Where "LocalAccount='TRUE' And Name='%~1'" Get SID 2>Nul|Find "S-">Nul && (
Echo User Profile %1 exists) || Echo User Profile %1 does not exist
Pause

How can I automatically uninstall all programs containing "VNC" in their displayname using a batch file?

I am attempting to create a batch script that will query the registry for uninstall packages. The goal is to create a batch script that will uninstall all VNC programs (UltraVNC, RealVNC, and TightVNC). This must be compatible with both Windows XP and Windows 7.
I started with the script from this StackOverflow solution Reg Query script for batch script . I am trying to alter the code to allow it to search for "VNC" in the DisplayName, strip the text between the {} in its corresponding UninstallPath, and then run msiexec.exe /qn /x {package-identifier} to silently uninstall the program.
When running the following code, it retrieves several programs that do not contain "VNC" in their DisplayName. The issue appears to lie in the following line of code:
if not "x!str1:VNC=!"=="x!str1!" (
Source of this line of code: How can I check if a variable contains another variable within a windows batch file?
I have tried the following code found at as an alternative, but it also listed way too many packages and did not properly pick only packages with "VNC" in their names.
set str1 = !product[%counter%]!
echo str1 > temp.dat
findstr /c:"VNC" "temp.dat" >nul 2>&1
if %errorlevel% == 0 (
Note: Many of the echo commands are there simply for testing purposes.
#echo off
setlocal
set regVar=HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall
set excluded=/c:" Microsoft" /c:"MDOP" /c:"Dell"
set count=1
for /f "tokens=1,2,*" %%a in ('Reg Query %regVar% /S ^| findstr "DisplayName HKEY_ UninstallString"') do (
setlocal EnableDelayedExpansion
for %%n in (!count!) do (
ENDLOCAL
SET HKEY=Y
IF "%%a"=="DisplayName" SET "HKEY="&set product[%%n]=%%c
IF "%%a"=="UninstallString" SET "HKEY="&IF NOT DEFINED uninstall[%%n] set uninstall[%%n]=%%c
IF "%%a"=="QuietUninstallString" SET "HKEY="&IF NOT DEFINED uninstall[%%n] set uninstall[%%n]=%%c
IF DEFINED hkey IF DEFINED product[%%n] IF defined uninstall[%%n] SET /a count+=1&SET "hkey="
IF DEFINED hkey set "product[%%n]="&SET "uninstall[%%n]="
)
)
IF NOT DEFINED product[%count%] SET "uninstall[%count%]="&SET /a count-=1
IF NOT DEFINED uninstall[%count%] SET "product[%count%]="&SET /a count-=1
ECHO %count% entries found
set counter=%count%
pause
#setlocal enableextensions enabledelayedexpansion
:while
if %counter% GTR 0 (
set str1 = !product[%counter%]!
echo str1
if not "x!str1:VNC=!"=="x!str1!" (
echo !product[%counter%]!
echo !uninstall[%counter%]!
set UninstallString=!uninstall[%counter%]!
echo !UninstallString!
set RunUninstall = ""
for /f "tokens=2 delims={}" %%A in ("!uninstall[%counter%]!") do echo %%A REM set RunUninstall="msiExec.exe /qn /x{%%A}" (commented for testing purposes)
call !RunUninstall!
set /a counter-=1
GOTO While
) Else (
set /a counter-=1
GOTO While
)
)
Output Snippet:
Intel(R) Network Connections 15.7.176.0
MsiExec.exe /X{26A24AE4-039D-4CA4-87B4-2F86418051F0}
MsiExec.exe /X{26A24AE4-039D-4CA4-87B4-2F86418051F0}
26A24AE4-039D-4CA4-87B4-2F86418051F0 REM set RunUninstall="msiExec.exe /qn /x{26
A24AE4-039D-4CA4-87B4-2F86418051F0}"
ECHO is off.
Microsoft .NET Framework 4.5.2
MsiExec.exe /X{26784146-6E05-3FF9-9335-786C7C0FB5BE}
MsiExec.exe /X{26784146-6E05-3FF9-9335-786C7C0FB5BE}
26784146-6E05-3FF9-9335-786C7C0FB5BE REM set RunUninstall="msiExec.exe /qn /x{26
784146-6E05-3FF9-9335-786C7C0FB5BE}"
ECHO is off.
Lenovo ThinkVantage Toolbox
MsiExec.exe /I{23170F69-40C1-2702-0920-000001000000}
MsiExec.exe /I{23170F69-40C1-2702-0920-000001000000}
23170F69-40C1-2702-0920-000001000000 REM set RunUninstall="msiExec.exe /qn /x{23
170F69-40C1-2702-0920-000001000000}"
ECHO is off.
OSFMount v1.5
MsiExec.exe /I{1B8ABA62-74F0-47ED-B18C-A43128E591B8}
MsiExec.exe /I{1B8ABA62-74F0-47ED-B18C-A43128E591B8}
1B8ABA62-74F0-47ED-B18C-A43128E591B8 REM set RunUninstall="msiExec.exe /qn /x{1B
8ABA62-74F0-47ED-B18C-A43128E591B8}"
UPDATE:
I modified the code provided by wOxxOm in an attempt to make an exception for TightVNC and uninstall it quietly. Since there is not a QuietUninstallString in the registry for TightVNC, I am attempting to accomplish this by utilizing the msiexec.exe /qn /x options. However it keeps throwing the following error:
else was unexpected at this time.
My modified version of wOxxOm's code is listed below:
#echo off
setlocal enableDelayedExpansion
for %%a in ("" "\Wow6432Node") do (
for /f "delims=" %%b in ('
reg query HKLM\SOFTWARE%%~a\Microsoft\Windows\CurrentVersion\Uninstall ^
/s /d /f "VNC" ^| findstr "HKEY_ DisplayName"
') do (
set "line=%%b"
if "!line:~0,4!"=="HKEY" (
set "key=!line!"
) else (
set Uninstall=
rem Sort /r makes QuietUninstallString the last line
for /f "tokens=2*" %%c in ('
reg query "!key!" ^| find "UninstallString" ^| sort /r
') do if not "%%d"=="" set "Uninstall=%%d"
if defined Uninstall (
for /f "tokens=2*" %%c in ("!line!") do (
set product=%%d
if "x!product:TightVNC=!"=="x!product!" (
for /f "tokens=2 delims={}" %%A in ("!Uninstall!") do (
echo Found !product!
Running msiExec.exe /qn /x{%%A} REM (COMMENTED FOR TESTING)
REM CALL msiExec.exe /qn /x{%%A}
)
) else (
echo Found %%d
echo Running !Uninstall! (COMMENTED FOR TESTING)
rem call !Uninstall!
echo.
)
)
)
)
)
Don't use spaces around = in set str1=!product[%counter%]!
Instead of if %counter% GTR 0 ( which doesn't work and makes the loop infinite)
use if %counter%==0 goto done and a :done label after the loop
With quotes you don't need to add x to the comparison.
Don't forget about 64-bit Windows and check Wow6432Node tree too (see the alternative code)
:while
if %counter%==0 goto done
set str1=!product[%counter%]!
if not "!str1:VNC=!"=="!str1!" (
..............................
rem call !RunUninstall!
)
set /a counter-=1
GOTO While
:done
Alternatively you can make the batch file much faster (the "arrays" are slow in case of many strings) by listing only the products with VNC in DisplayName first and then fetch the UninstallString:
#echo off
setlocal enableDelayedExpansion
for %%a in ("" "\Wow6432Node") do (
for /f "delims=" %%b in ('
reg query HKLM\SOFTWARE%%~a\Microsoft\Windows\CurrentVersion\Uninstall ^
/s /d /f "VNC" ^| findstr "HKEY_ DisplayName"
') do (
set "line=%%b"
if "!line:~0,4!"=="HKEY" (
set "key=!line!"
) else (
set Uninstall=
rem Sort /r makes QuietUninstallString the last line
for /f "tokens=2*" %%c in ('
reg query "!key!" ^| find "UninstallString" ^| sort /r
') do if not "%%d"=="" set "Uninstall=%%d"
if defined Uninstall (
for /f "tokens=2*" %%c in ("!line!") do echo Found %%d
echo Running !Uninstall! (COMMENTED FOR TESTING)
rem call !Uninstall!
echo.
)
)
)
)
pause
Modifying wOxxOm's code, I was able to create the following code to quietly uninstall TightVNC, UltraVNC, and RealVNC. It will also start the uninstaller for any other software with "VNC" in the DisplayName in the Windows registry under HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall and HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall.
Hopefully this is handy to someone else out there as well.
#echo off
setlocal enableDelayedExpansion
for %%a in ("" "\Wow6432Node") do (
for /f "delims=" %%b in ('
reg query HKLM\SOFTWARE%%~a\Microsoft\Windows\CurrentVersion\Uninstall ^
/s /d /f "VNC" ^| findstr "HKEY_ DisplayName"
') do (
set "line=%%b"
if "!line:~0,4!"=="HKEY" (
set "key=!line!"
) else (
set Uninstall=
rem Sort /r makes QuietUninstallString the last line
for /f "tokens=2*" %%c in ('
reg query "!key!" ^| find "UninstallString" ^| sort /r
') do if not "%%d"=="" set "Uninstall=%%d"
if defined Uninstall (
for /f "tokens=2*" %%c in ("!line!") do (
set product=%%d
if NOT "x!product:TightVNC=!"=="x!product!" (
for /f "tokens=2 delims={}" %%A in ("!Uninstall!") do (
echo Found !product!
CALL msiExec.exe /qn /x{%%A}
echo.
)
) else (
if NOT "x!product:UltraVNC=!"=="x!product!" (
for /f "tokens=1 delims=." %%A in ("!Uninstall!") do (
echo Found !product!
CALL %%A.exe" /VERYSILENT /NORESTART
echo.
)
) else (
if NOT "x!Uninstall:RealVNC=!"=="x!Uninstall!" (
for /f "tokens=1 delims=." %%A in ("!Uninstall!") do (
echo Found !product!
CALL %%A.exe" /VERYSILENT
echo.
)
) else (
echo Found %%d
CALL !Uninstall!
echo.
)
)
)
)
)
)
)
)

Disable all local Windows accounts

I need to make a batch script that disable all local user accounts of a computer or a way to list all the users, one below another.
I try to generate a file with the command:
net user > %systemroot%\users.txt | findstr /I adm
but the command returns me all users in the same line.
If someone knows how to generate every user in a separate line, it helps me too.
Here's a working code snippet:
for /F "tokens=1* delims==" %%G in (
'wmic USERACCOUNT where "Name!='Administrator'" get Name /value'
) do for /F "tokens=*" %%x in ("%%H") do (
echo %%x
rem some further command(s) here
)
Where the for loops are
%%G to retrieve the Name value (in the second token, %%H);
%%x to remove the ending carriage return in the value returned (wmic behaviour: each output line ends with 0x0D0D0A instead of common 0x0D0A), see the example below.
Example (copy & paste from my command line window):
==>for /F "tokens=1* delims==" %G in ('wmic USERACCOUNT where "Name!='Administra
tor'" get Name /value') do #echo "%H"
""
""
"Guest
""
""
"Edgar
""
""
"Allan
""
""
"Poe
""
""
""
==>for /F "tokens=1* delims==" %G in ('wmic USERACCOUNT where "Name!='Administra
tor'" get Name /value') do #for /F "tokens=*" %x in ("%H") do #echo "%x"
"Guest"
"Edgar"
"Allan"
"Poe"
==>
I don't believe net.exe can output them as separate lines, but you can use a call statement with shift to break the line into separate variables.
for /f "delims=" %%a in ('net user ^| findstr /i adm') do set userlist=%%a
call :process %userlist%
goto :eof
:process
if {%1}=={} goto :eof
::-----------
rem Do something with %1 here
echo %1
::-----------
shift
goto :process
here is the code that solved to me:
for /f "delims=" %%a in ('net user ^| findstr -V "Contas de usu" ^| findstr -V "Comando conc" ^| findstr -V "\-" ^| findstr -V "User accounts" ^| findstr -V "The command"') do (
for %%b in (%%a) do (
if not "%%b" == "Administrador" (
if not "%%b" == "Administrator" (
if not "%%b" == "Convidado" (
Net user %%b /active:no
) else (
for /f "delims=" %%c in ('ver ^| findstr /i "5\.1\."') do (
set version=%%c
)
if not {"!version!"} == {""} (
Net user "Convidado" /active:yes
) else (
Net user "Convidado" /active:no
)
)
) else (
Net user "Administrator" /active:yes
)
) else (
Net user "Administrador" /active:yes
)
)
)
WMIC USERACCOUNT WHERE localaccount=true set disabled=true
run it with admin privileges.

'if errorlevel' statement when in 'for findstr' loop

I have been unsuccessful getting the following to work. Everything works until I try to get the results of the 'findstr' in the 'for' loop. Maybe there is a better way of doing this: look for %subnet% in the masters.csv file. If it finds it, set the MSS variable to the resulting value from the 'for'. If it does not find a value, it will assign a static value (orphan). Thanks in advance for any help!!
for /f "tokens=1-2 delims=:" %%a in ('ipconfig^|find "IPv4"') do set ip=%%b
set ip=%ip:~1%
echo %ip% > ipaddress.txt
pause
for /F "tokens=1-3 delims=." %%a in ("%ip%") do set FirstThreeOctets=%%a.%%b.%%c
#REM echo First three: %FirstThreeOctets%
#echo off
setlocal
set subnet=%FirstThreeOctets%
echo %subnet%
for /f "tokens=2 delims=," %%A in ('findstr /r "^%subnet%," "\\server\APPS\appname\updates\masters.csv"') do goto OrphanCheck
#REM if errorlevel ==1 goto Orphan do set MSS=%%A
#REM echo %MSS%
#REM goto 64installcheck
:OrphanCheck
if errorlevel==1 goto Orphan
Goto NoOrphan
:NoOrphan
set MSS=%%A
Goto 64installcheck
:Orphan
set MSS=ORPHAN
echo %MSS%
pause
When you run
for /f "tokens=2 delims=," %%A in (
'findstr /r "^%subnet%," "\\server\APPS\appname\updates\masters.csv"'
) do goto OrphanCheck
two things can happen.
If findstr does not find the string, code in for loop is not executed and the next line is reached, but this line does not have access to the errorlevel generated by the findstr, it sees the errorlevel (?) of the for command.
If findstr finds the string, the goto is executed but the same scenario happens.
When the line that checks the error level is reached, another problem raises
if errorlevel==1
is a valid construct, but it does not do what it seams. It is testing if the string errorlevel is equal to the string 1. The correct sintax should be
if errorlevel 1 ....
or
if %errorlevel%==1
but as indicated, when the line is reached the errorlevel will not reflect the error of the findstr command.
And three lines later the next error.
set MSS=%%A
Once the for command has ended, its replaceable parameter does not have any value.
For a simplified version of your code
for /f "tokens=3-6 delims=.: " %%a in ('ipconfig ^| find "IPv4"') do (
set "ip=%%a.%%b.%%c.%%d"
set "subnet=%%a.%%b.%%c"
)
>"ipaddress.txt" echo %ip%
for /f "tokens=2 delims=," %%a in (
'findstr /b /c:"%subnet%," "\\server\APPS\appname\updates\masters.csv"'
) do (
set "MSS=%%a"
goto 64installcheck
)
set "MSS=ORPHAN"
echo %MSS%
pause

Batch: ECHO is on always when trying to output variable content

I'm always getting the message "Echo is on" when trying to run the script..
setlocal ENABLEEXTENSIONS
C:
cd ..
cd ..
reg query "HKLM\SYSTEM\CurrentControlSet\Services" | findstr /b "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DummyService" > "C:\servicePaths.txt"
FOR /f "delims=" %%g IN (servicePaths.txt) do (
set KEY_NAME="%%g"
set VALUE_NAME=ImagePath
FOR /F "tokens=1-3" %%A IN ('REG QUERY %KEY_NAME% /v %VALUE_NAME% 2^>nul') DO (
set ValueValue=%%C
)
echo %ValueValue%
pause
)
Could any batch-guru please help me? I know that it has something to do with the cascaded for-loops, but I cannot find the solutions - no clue anymore after 3 hours try&error.
It's a problem of expanding the %ValueValue%, as this happens when the complete parenthesis block is parsed.
Not when it is executed, but at parse time the ValueValue variable is empty, so you get only echo which will print echo is on.
Simply change it to delayed expansion
#echo off
setlocal EnableDelayedExpansion
C:
cd ..
cd ..
set VALUE_NAME=ImagePath
reg query "HKLM\SYSTEM\CurrentControlSet\Services" | findstr /b "HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\DummyService" > "C:\servicePaths.txt"
FOR /f "delims=" %%g IN (servicePaths.txt) do (
set "KEY_NAME=%%g"
FOR /F "tokens=1-3" %%A IN ('REG QUERY !KEY_NAME! /v !VALUE_NAME! 2^>nul') DO (
set ValueValue=%%C
)
echo !ValueValue!
pause
)

Resources