Windows batch file for invalid microsoft updates - batch-file

I am struck while creating a windows batch file which just indicates if an invalid KB article is installed on my computer/ windows server.
This is where i am at now,
Script :
#ECHO OFF
WMIC QFE GET HOTFIXID>%~dp0QFE_list.txt
FOR /f "delims=," %%a IN (%~dp0Patch_List.txt) DO (
CALL :PATCH_LIST %%a
)
GOTO :EOF
:PATCH_LIST
REG QUERY "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" /s /f "%1">NULL.txt
IF %ERRORLEVEL% EQU 0 ECHO %1: INSTALLED
IF %ERRORLEVEL% NEQ 0 (
ECHO FIND %1
FIND /C "%1" %~dp0QFE_List.txt>NULL.txt
IF ERRORLEVEL 0 ECHO %1: QFE INSTALLED
IF ERRORLEVEL 1 ECHO %1: **** NOT INSTALLED! ****
)
Current output : ---------- C:\USERS\PVENK17\DESKTOP\TEST\QFE_LIST.TXT: 1
Desired output : : Installed
Inputfile contents : KB3057839,KB3002657
Issue :
Even though it works for 1 KBarticle. When i place more than 1 in the inputfile it is not working.
Kindly help me resolve this issue.
Thanks
Prashanth

I can make this work by changing the input file format: 1 KB per line
KB3057839
KB3002657
Then, just remove the "delims" stuff and it works for several items. Not sure of the logic of the last lines. It seems to say "installed/not installed"
And BTW redirect your commands to NUL to avoid creating a useless file.
#ECHO OFF
WMIC QFE GET HOTFIXID>%~dp0QFE_list.txt
FOR /f %%a IN (%~dp0Patch_List.txt) DO (
CALL :PATCH_LIST %%a
)
GOTO :EOF
:PATCH_LIST
REG QUERY "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall" /s /f "%1">NUL
IF %ERRORLEVEL% EQU 0 ECHO %1: INSTALLED
IF %ERRORLEVEL% NEQ 0 (
ECHO FIND %1
FIND /C "%1" %~dp0QFE_List.txt>NUL
IF ERRORLEVEL 0 ECHO %1: QFE INSTALLED
IF ERRORLEVEL 1 ECHO %1: **** NOT INSTALLED! ****
)

After much more debugging i wrote this code, i know its not ideal solution but it works
Code :
#ECHO OFF
title IllegalPatchCheck
echo Select a server. (AW/PG)
set /p server=
IF /i "%server%"=="AW" goto AdminWorkstation
IF /i "%server%"=="PG" goto PeripheralGateway
echo Invalid Input.
goto commonexit
:AdminWorkstation
WMIC QFE GET HOTFIXID>%~dp0QFE_list.txt
find /c "KB3057839" %~dp0QFE_list.txt>nul
if %errorlevel% equ 1 ECHO KB3057839 NOT Found
if %errorlevel% neq 1 ECHO KB3057839 Found
find /c "KB3058515" %~dp0QFE_list.txt>nul
if %errorlevel% equ 1 ECHO KB3057839 NOT Found
if %errorlevel% neq 1 echo KB3058515 Found
find /c "KB3059317" %~dp0QFE_list.txt>nul
if %errorlevel% equ 1 echo KB3059317 NOT found
if %errorlevel% neq 1 echo KB3059317 Found
find /c "KB3063858" %~dp0QFE_list.txt>nul
if %errorlevel% equ 1 echo KB3063858 NOT found
if %errorlevel% neq 1 echo KB3063858 Found
goto commonexit
:PeripheralGateway
WMIC QFE GET HOTFIXID>%~dp0QFE_list.txt
find /c "KB2984972" %~dp0QFE_list.txt>nul
if %errorlevel% equ 1 echo KB2984972 NOT Found
if %errorlevel% neq 1 echo KB2984972 Found
find /c "KB3046049" %~dp0QFE_list.txt>nul
if %errorlevel% equ 1 echo KB3046049 NOT Found
if %errorlevel% neq 1 echo KB3046049 Found
find /c "KB3002657" %~dp0QFE_list.txt>nul
if %errorlevel% equ 1 echo KB3002657 NOT Found
if %errorlevel% neq 1 echo KB3002657 Found
goto commonexit
:commonexit
del /q /f %~dp0QFE_list.txt >nul
pause
Thanks
Prashanth

#echo off
title HOTFIXID_KB_FOUND
setlocal enabledelayedexpansion
cd /d "%~dp0"
for /f %%A in (KB_list.txt) do (
wmic qfe get hotfixid |findstr /i "%%A"
if !errorlevel! equ 0 echo %%A: ****INSTALLED****
if !errorlevel! equ 1 echo %%A: NOT INSTALLED
)
pause
KB_list.txt, in my case, is the list of the harmful updates leading to BSOD. You can, of course, automate and delete, but not always get wusa.exe sometimes requires dism.exe.
An example of removing using wusa.exe
wusa.exe /uninstall /kb:3065987 /quiet /norestart
An example of removing using dism.exe
DISM /Online /Get-Packages /Format:Table
DISM /Online /Remove-Package /PackageName:Package_for_KB3045999~31bf3856ad364e35~amd64~~6.1.1.1

Related

REG Query to find a specify value of registry and if it exist than go to

I want to find a specify value of registry and if it exist than go to execute the job
Here my script used but not successful
:SkinReplacementKIS64
CLS
ECHO.
REG Query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\KasperskyLab\AVP19.0.0\settings" /v "EnableSelfProtection" |find "1" >nul & IF %ErrorLevel% EQU 0 (
ECHO.
ECHO Please disable Kaspersky self-defense first before doing the action!
ECHO.
pause
GOTO SkinReplacementKIS64
) else (
CLS
ECHO ***************************************************************************************
ECHO Kaspersky Tweaker v1.4 for KFA, KAV, KIS, KTS, KSC (19.0.0.1088)
ECHO ***************************************************************************************
ECHO.
net stop AVP19.0.0
dark_skin_kis.exe /p12345678
net start AVP19.0.0
ECHO.
pause
GOTO KIS64
)
what am I wrong ? Please help
Use for /fto get the value an test it?
#echo off
:SkinReplacementKIS64
CLS
ECHO.
for /f "delims=" %%a in ('REG Query "HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\KasperskyLab\AVP19.0.0\settings" /v "EnableSelfProtection"') do set "$val=%%a"
if %$val%==1 (
ECHO.
ECHO Please disable Kaspersky self-defense first before doing the action!
ECHO.
pause
GOTO SkinReplacementKIS64
) else (
CLS
ECHO ***************************************************************************************
ECHO Kaspersky Tweaker v1.4 for KFA, KAV, KIS, KTS, KSC (19.0.0.1088)
ECHO ***************************************************************************************
ECHO.
net stop AVP19.0.0
dark_skin_kis.exe /p12345678
net start AVP19.0.0
ECHO.
pause
GOTO KIS64
)
Based on my comment, the easiest way would be to exclude the first line from your potential match:
Reg Query "HKLM\SOFTWARE\WOW6432Node\KasperskyLab\AVP19.0.0\settings" /V "EnableSelfProtection" 2>Nul | Find /V "HKLM" | Find "1" >Nul ...
You may even wish to use x1 instead of 1 to provide more certainty too.

Modifying Host File Using batch file

I got the codes below. Here is my situation, I want to copy my modified hosts the host file in each of my clients units. But some of my clients hosts file was already modified(and I dont want to mess it, they are allowed to access these some site) while some host arent modified.
I want my code to check if atleast one host entry is written in the host file, if it finds atleast one entry it wont copy my modified hosts file.
#echo off
#echo off
For /f "tokens=2-4 delims=/ " %%a in ('date /t') do (set mydate=%%c-%%a-%%b)
For /f "tokens=1-2 delims=/:" %%a in ('time /t') do (set mytime=%%a:%%b)
echo "Host File modification starts at %mydate% %mytime% " >> "%~dp0Host_log.txt"
for /F "UseBackQ" %%M in ("%~dp0Modify_Host.txt") do (
ping -n 1 -w 1 %%M >nul 2>&1
If ErrorLevel 1 (Echo=%%M is Down %mytime%>>"%~dp0Host_log.txt") Else (
FIND /C /I "www.facebook.com" \\%%M\C$\Windows\System32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 1 (goto END)
FIND /C /I "https://m.www.facebook.com" \\%%M\C$\Windows\System32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 1 (goto END)
FIND /C /I "edge-star-shv-01-sit4.facebook.com" \\%%M\C$\Windows\System32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 1 goto END
FIND /C /I "login.facebook.com" \\%%M\C$\Windows\System32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 1 goto END
FIND /C /I "fbcdn.net" \\%%M\C$\Windows\System32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 1 goto END
FIND /C /I "https://m.facebook.com" \\%%M\C$\Windows\System32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 1 goto END
FIND /C /I "www.fbcdn.com" \\%%M\C$\Windows\System32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 1 goto END
FIND /C /I "static.ak.fbcdn.net" \\%%M\C$\Windows\System32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 1 goto END
FIND /C /I "static.ak.connect.facebook.com" \\%%M\C$\Windows\System32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 1 goto END
FIND /C /I "connect.facebook.net" \\%%M\C$\Windows\System32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 1 goto END
FIND /C /I "apps.facebook.com" \\%%M\C$\Windows\System32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 1 goto END
FIND /C /I "www.facebook.com" \\%%M\C$\Windows\System32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 1 goto END
FIND /C /I "ns2.intranet.de" \\%%M\C$\Windows\System32\drivers\etc\hosts
IF %ERRORLEVEL% NEQ 1 (goto END) ELSE (
copy /Y "%~dp0hosts" \\%%M\c$\windows\system32\drivers\etc
)
:END
Echo Host file in %%M is already modified
)
)
pause
But either it detects a certain host entry or not, my code will copy my modified host to the remote PC. Please help me, thanks.
It's IMO easier to put the checks into a sub where you can return on any fail to the call in a for loop. I don't use If's but conditional execution on fail || or success &&.
#echo off
For /f "tokens=2-4 delims=/ " %%a in ('date /t') do set "mydate=%%c-%%a-%%b"
Set Log=^>^>"%~dp0Host_log.txt"
%Log% echo=[%time:/=:%] Host File modification starts at %mydate%
for /F "UseBackQ" %%M in ("%~dp0Modify_Host.txt") do Call :CheckM "%%M"
goto :Eof
:CheckM
ping -n 1 -w 1 %1 >nul 2>&1 || (
%Log% Echo=[%time:/=:%] %~1 is Down
Goto :Eof
)
Set "RemoteHosts=\\%~1\C$\Windows\System32\drivers\etc\hosts"
For %%U in (
"apps.facebook.com"
"connect.facebook.net"
"edge-star-shv-01-sit4.facebook.com"
"fbcdn.net"
"https://m.facebook.com"
"https://m.www.facebook.com"
"login.facebook.com"
"ns2.intranet.de"
"static.ak.connect.facebook.com"
"static.ak.fbcdn.net"
"www.facebook.com"
"www.fbcdn.com"
) do FIND /C /I %%U "%RemoteHosts%" >Nul 2>&1 && (
Echo [%time:/=:%] Host file in %~1 is already modified
Goto :Eof
)
Echo copy /Y "%~dp0hosts" "\\%~1\c$\windows\system32\drivers\etc"
copy /Y "%~dp0hosts" "\\%~1\c$\windows\system32\drivers\etc"
pause

How to force exit command line bat file when occur download error

Dears
Here is my .bat command line
I use bitsadmin /transfer command download from url.
but got error(like disconnect network...etc) I need continue execute remain command.
But now I can't get achievement... what should I do
#echo off
:: Filter updater for HCK and HLK
:::::::::::::::::::::::::: Settings :::::::::::::::::::::::::::::::::
:: Notice: As of July 2015, the HCK and the HLK filter updates are the exact same file, downloaded from the same location!
SET "source=https://sysdev.microsoft.com/member/SubmissionWizard/LegalExemptions/HCKFilterUpdates.cab"
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
SET "destination=C:\FilterUpdates.cab"
if not exist "%DTMBIN%\" (
echo ERROR: folder "%DTMBIN%"
echo does not exist! Please verify that you have the controller installed.
pause
exit /B 1
)
echo Please make sure that all instances of the Studio are turned OFF!
echo Downloading Filters...
bitsadmin /transfer "Downloading Filters" "%source%" "%destination%"
if errorlevel 1 goto end
echo Extracting...
expand -i "%destination%" -f:UpdateFilters.sql "%DTMBIN%\"
if not errorlevel 0 echo ERROR & exit /B 1
echo Installing...
pushd "%DTMBIN%\"
if not errorlevel 0 echo ERROR & exit /B 1
"%DTMBIN%\updatefilters.exe " /s
if not errorlevel 0 echo ERROR & exit /B 1
popd
:end
exit
Your problem could be caused by the errorlevels generated by bitsadmin: some of them are negative values and the test if errorlevel 1 will be evaluated as false (if errorlevel n is true for values greater than or equal to n)
You will need to read and test the value of the errorlevel variable
if not %errorlevel%==0 exit /b 1
But sometimes, bitsadmin will have errors and will generate a errorlevel 0, so, you need to manualy check the status
#echo off
setlocal enableextensions disabledelayedexpansion
:: Filter updater for HCK and HLK
:::::::::::::::::::::::::: Settings :::::::::::::::::::::::::::::::::
:: Notice: As of July 2015, the HCK and the HLK filter updates
:: are the exact same file, downloaded from the same location!
SET "source=https://sysdev.microsoft.com/member/SubmissionWizard/LegalExemptions/HCKFilterUpdates.cab"
:::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::::
if not exist "%DTMBIN%\" (
echo ERROR: folder "%DTMBIN%"
echo does not exist! Please verify that you have the controller installed.
pause
exit /B 1
)
SET "destination=C:\FilterUpdates.cab"
if exist "%destination%" del /q "%destination%"
echo Please make sure that all instances of the Studio are turned OFF!
echo Creating download task...
set "taskName=[HCK_FilterUpdater]"
>nul (
rem remove task if already present
bitsadmin /list | find "%taskName%" && bitsadmin /cancel "%taskName%"
rem create the task
bitsadmin /create "%taskName%"
rem include our file in the task
bitsadmin /addfile "%taskName%" "%source%" "%destination%"
rem start the download
bitsadmin /resume "%taskName%"
)
echo Downloading...
set "exitCode="
for /l %%a in (1 1 500) do if not defined exitCode for /f "delims=" %%a in ('
bitsadmin /info "%taskName%"
^| findstr /b /l /c:"{"
') do for /f "tokens=3,*" %%b in ("%%a") do (
if "%%~b"=="TRANSFERRED" (
set "exitCode=0"
>nul bitsadmin /complete "%taskName%"
echo ... done
)
if "%%~b"=="ERROR" (
set "exitCode=1"
bitsadmin /geterror "%taskName%" | findstr /b /c:"ERROR"
>nul bitsadmin /cancel "%taskName%"
)
if not defined exitCode (
echo(%%b %%c
timeout /t 2 >nul
)
)
if not defined exitCode ( echo TIMEOUT & exit /b 1 )
if not exist "%destination%" ( echo ERROR & exit /b 1 )
echo Expanding...
>nul expand -i "%destination%" -f:UpdateFilters.sql "%DTMBIN%"
if errorlevel 1 ( echo ERROR & exit /b 1 )
echo Installing...
pushd "%DTMBIN%" || ( echo ERROR & exit /b 1 )
".\updatefilters.exe " /s || ( echo ERROR & exit /b 1 )
popd
It seems like once command shell is in bitsadmin mode you can't take it out of it. My solution unfortunately is two seperate .bats.

returning errorlevel from batch function doesnt work

I have some function in batch script:
:run
set "CMD=%*"
<...>
timeout 300s !CMD!
if %errorlevel% equ 0 (
echo !CMD! >> ./!_tool!.OK
) else (
echo !CMD! >> ./!_tool!.FAIL
echo exitcode= %errorlevel% >> ./FAIL
echo ===STOP=== %date% %time%
exit /b %errorlevel%
)
exit /b %errorlevel%
and im checking its %errorlevel% code in the main cycle:
for /f "tokens=*" %%t in (%TEST_LIST%) do (
<...>
call :run %TOOL% -O0 -S %REPO_PATH%\%%t
if %errorlevel% equ 0 (
echo %%t PASSED
) else (
echo %%t FAILED
)
But the issue when timeout 300s !CMD! returns errorlevel 1 and is returning exit /b %errorlevel% as 1 (./!_tool!.FAIL being created and so on) doesnt affect the main cycle's IF and im getting echo %%t PASSED anyway.
Cannot function return code be checked this way or what?
P.S. Some <...> code is working correctly, so I've cut it
Thanks to #Stephan i've found my problem - I should use !errorlevel! instead of %errorlevel% in my FOR loop as it should refresh every iteration

Batch errorlevel is not working properly

so i have really problems with the ERRORLEVEL of batch. Its just not working for me.
I have a big own ms build batch script and i always get 0 back from ERRORLEVEL, whatever I do (eg. msbuild, tf get, tf checkout, copy, xcopy,...)
so i did a small example to post it here:
#echo off
set Update=1
IF %Update% == 1 (
echo.
set /p "=- Copy stuff..." <NUL
xcopy /R /Y C:\test\2.lib C:\test1
if %ERRORLEVEL% neq 0 (echo FAILED!) ELSE (echo SUCCEED!)
echo -^> done
pause
)
so its always returning succeed and printing 0 when i do: echo %ERRORLEVEL%
can you please help me with that? I really would like to use that errorlevel
you need delayed expansion here or to use IF ERRORLEVEL :
#echo off
set Update=1
IF %Update% == 1 (
echo.
set /p "=- Copy stuff..." <NUL
xcopy /R /Y C:\test\2.lib C:\test1
IF ERRORLEVEL 1 (echo FAILED!) ELSE (echo SUCCEED!)
echo -^> done
pause
)
with IF ERRORLEVEL 1 you can check if the errorlevel is 1 or bigger .
As npocmaka says, you have a delayed expansion issue.
An alternative is to ditch ERRORLEVEL and use the && and || conditional command concatenation operators instead.
#echo off
set Update=1
IF %Update% == 1 (
echo.
set /p "=- Copy stuff..." <NUL
xcopy /R /Y C:\test\2.lib C:\test1 && (echo SUCCEED!) || (echo FAILED!)
echo -^> done
pause
)
Edit showing use of multiple lines
#echo off
set Update=1
IF %Update% == 1 (
echo.
set /p "=- Copy stuff..." <NUL
xcopy /R /Y C:\test\2.lib C:\test1 && (
echo First success command
echo SUCCEED!
) || (
echo First failure command
echo FAILED!
)
echo -^> done
pause
)

Resources