Компьютерный форум OSzone.net  

Компьютерный форум OSzone.net (http://forum.oszone.net/index.php)
-   Скриптовые языки администрирования Windows (http://forum.oszone.net/forumdisplay.php?f=102)
-   -   Список обновлений KB (http://forum.oszone.net/showthread.php?t=217591)

sov44 10-10-2011 14:08 1770052

Список обновлений KB
 
Нужна помощь в написании скрипта по выводу всех обновлений типа КВ* в разделе и подразделах HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall
начал примерно так
Код:

@ECHO OFF
SetLocal enabledelayedexpansion

SET UNISTALL=HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall
FOR /f "tokens=7 delims=\" %%a IN ('reg query "%UNISTALL%"') DO (
set "upd=%%a"
if /i "!upd:~0,2!"=="KB" echo !upd!
)
pause


gora 10-10-2011 14:15 1770055

Цитата:

Цитата sov44
по выводу всех обновлений »

Такой подойдет?
Код:

wmic qfe get Caption, Description, HotFixID, InstalledOn >ListUpdates.txt
Форматированный список (со ссылками и прочими подробностями) в ListUpdates.txt

sov44 10-10-2011 14:49 1770090

Цитата:

Цитата gora
Такой подойдет? »

наверное нет, т.к. в дальнейшем при установке обновлений планируется их перебор. Устанавливать только те, которых нет в системе.
п.с. в посте 1 столкнулся в проблемой отображения обновлений в "чистом" виде, то есть только в виде КВ123456 или КВ1234567 без дополнительных символов в конце.

sov44 11-10-2011 00:33 1770548

Вроде сделал. Прошу проверить верность скриптов и подсказать, как их объединить в один
Код:

@ECHO OFF
SetLocal enabledelayedexpansion

SET UNISTALL=HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall
FOR /f "tokens=7 delims=\" %%a IN ('reg query "%UNISTALL%"') DO (
set "upd=%%a"
if /i "!upd:~0,2!"=="KB" (
set "up1=!upd:~0,9!"
if /i "!up1:~-1!"=="-" set "up1=!up1:~0,8!"
if /i "!up1:~-1!"=="_" set "up1=!up1:~0,8!"
echo !up1!
)
)
pause

Код:

@ECHO OFF
SetLocal enabledelayedexpansion

SET UNISTALL=HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall
FOR /f "tokens=7 delims=\" %%a IN ('reg query "%UNISTALL%"') DO (
        FOR /f "tokens=1,2*" %%b IN ('reg query "%UNISTALL%\%%a" ^| FIND /I "HelpLink"') DO (
set "tt=%%d"
if /i "!tt:~7,21!"=="support.microsoft.com" (
set "up2=!tt:~-9!"
if /i "!up2:~0,2!"=="d=" set "up2=KB!up2:~2!"
if /i "!up2:~0,1!"=="=" set "up2=KB!up2:~1!"
if /i "!up2:~0,3!"=="id=" set "up2=KB!up2:~3!"
if /i "!up2:~0,3!"=="kb/" set "up2=KB!up2:~3!"
if /i "!up2:~6,2!"=="-v" set "up2=KB!up2:~0,-3!"
if /i "!up2:~0,4!"=="KBKB" set "up2=!up2:~2!"
echo !up2!
)
        )
)
pause


sov44 11-10-2011 17:03 1771060

Слепил всё в один файл. Осталось убрать дублирование некоторых записей.
Код:

@ECHO OFF
SetLocal enabledelayedexpansion

SET UNISTALL=HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall
FOR /f "tokens=7 delims=\" %%a IN ('reg query "%UNISTALL%"') DO (

FOR /f "tokens=1,2*" %%b IN ('reg query "%UNISTALL%\%%a" 2^>nul ^| FIND /I "HelpLink"') DO (
set "tt=%%d"
if /i "!tt:~7,21!"=="support.microsoft.com" (
set "up2=!tt:~-9!"
if /i "!up2:~0,2!"=="d=" set "up2=KB!up2:~2!"
if /i "!up2:~0,1!"=="=" set "up2=KB!up2:~1!"
if /i "!up2:~0,3!"=="id=" set "up2=KB!up2:~3!"
if /i "!up2:~0,3!"=="kb/" set "up2=KB!up2:~3!"
if /i "!up2:~6,2!"=="-v" set "up2=KB!up2:~0,-3!"
if /i "!up2:~0,4!"=="KBKB" set "up2=!up2:~2!"
if /i "!up2:~0,2!"=="b/" set "up2=KB!up2:~2!"
::echo !up2!
call :fn1 !up2!
)
)
 FOR /f "tokens=1,2*" %%b IN ('reg query "%UNISTALL%\%%a" 2^>nul ^| Find "REG_SZ"') DO (
set "zz=%%d"
if /i "!zz:~0,2!"=="KB" (
if /i "!zz:~-2!"=="v2" set "zz=!zz:~0,-2!"
set "up3=!zz!"
::echo !up3!
call :fn1 !up3!
)
)
)
pause

:fn1
set "update=%1"
Echo %update%

Надеюсь на помощь...

El Sanchez 12-10-2011 11:37 1771646

Цитата:

Цитата sov44
Устанавливать только те, которых нет в системе. »

Выдрал кусок из своего рабочего обновлятора. В примере обновления (только системные; IE, WMP требуют другого разбора) и скрипт находятся в одной директории, для боеготовности удалить Echo:
Код:

@Echo Off
For /F "Tokens=1-4* Delims=-" %%A in ('Dir /B "*.exe"') Do Call :_Func "%%A" "%%B" "%%C" "%%D" "%%E"
GoTo :EoF

:_Func
Set Version=%~3
If /i "!Version:~0,1!"=="v" (Set UpdNameVer=%~2-%~3) Else (Set UpdNameVer=%~2)
Reg Query "HKLM\Software\Microsoft\Updates" /s 2>nul|Find /i "%UpdNameVer%" 1>nul 2>&1||^
Reg Query "HKLM\Software\Microsoft\Windows NT\CurrentVersion\HotFix" /s 2>nul|Find /i "%UpdNameVer%" 1>nul 2>&1||^
If /i %5=="" (Echo Start /Wait %~1-%~2-%~3-%~4 /quiet /norestart) Else (Echo Start /Wait %~1-%~2-%~3-%~4-%~5 /quiet /norestart)


sov44 12-10-2011 17:25 1771907

El Sanchez, спасибо за скрипт и за наводку по месторасположению обновлений. Одно осталось не решенным в моём скрипте - убрать повторы выводов обновлений.

sov44 12-10-2011 23:25 1772106

После установки обновлений Office 2010, выяснил, что информация об их установке ( не всех, а только некоторых) прописывается только в
Код:

HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall
В связи с этим попытался объединить свой скрипт и скрипт El Sanchez.
читать дальше »
Код:

@Echo Off
SetLocal enabledelayedexpansion
Echo.
Echo                  Установка обновлений
Echo Если обновления есть в системе, их установка не производится
Echo.
For /F "Tokens=1-4* Delims=-" %%A in ('dir /b /od "*.exe"') Do Call :fn1 "%%A" "%%B" "%%C" "%%D" "%%E"

SET UNISTALL=HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall

FOR /f "tokens=7 delims=\" %%a IN ('reg query "%UNISTALL%"') DO (
FOR /f "tokens=1,2*" %%b IN ('reg query "%UNISTALL%\%%a" 2^>nul ^| FIND /I "HelpLink"') DO (
set "tt=%%d"
if /i "!tt:~7,21!"=="support.microsoft.com" (
set "up2=!tt:~-9!"
if /i "!up2:~0,2!"=="d=" set "up2=KB!up2:~2!"
if /i "!up2:~0,1!"=="=" set "up2=KB!up2:~1!"
if /i "!up2:~0,3!"=="id=" set "up2=KB!up2:~3!"
if /i "!up2:~0,3!"=="kb/" set "up2=KB!up2:~3!"
if /i "!up2:~6,2!"=="-v" set "up2=KB!up2:~0,-3!"
if /i "!up2:~0,4!"=="KBKB" set "up2=!up2:~2!"
if /i "!up2:~0,2!"=="b/" set "up2=KB!up2:~2!"
call :fn1 !up2!
)
)
 FOR /f "tokens=1,2*" %%b IN ('reg query "%UNISTALL%\%%a" 2^>nul ^| Find "REG_SZ"') DO (
set "zz=%%d"
if /i "!zz:~0,2!"=="KB" (
if /i "!zz:~-2!"=="v2" set "zz=!zz:~0,-2!"
set "up3=!zz!"
call :fn1 !up3!
)
)
)

pause
GoTo :EoF

:fn1

Set Version=%~3
set "n=%~1"
set "update=%1"

If /i "!Version:~0,1!"=="v" (Set UpdNameVer=%~2-%~3) Else (Set UpdNameVer=%~2)

if /i not "KB%UpdNameVer:~2%"=="update=%1" (
If /i %5=="" (
Echo Установка обновления %n%  -  KB%UpdNameVer:~2%
start /Wait %~1-%~2-%~3-%~4 /quiet /norestart
) Else (
Echo Установка обновления %n%  -  KB%UpdNameVer:~2%
start /Wait %~1-%~2-%~3-%~4-%~5 /quiet /norestart
)
)


При объединении, в скрипте появилась ошибка. Прошу подсказать, как её исправить.

sov44 17-10-2011 19:55 1775544

Всё ещё актуально! Как объединить скрипты?

Devils0411 02-02-2012 15:45 1850105

Подскажите в такой ситуации.
Код:

@Echo off
SetLocal enabledelayedexpansion
if exist "%ProgramFiles(x86)%" (set bit=x64) else (set bit=x86)
Title Поиск отсутствующих обновлений для Windows %bit%
wmic qfe get HotFixID >temp.txt
.\iconv\iconv -c -f UTF-16LE -t CP866 temp.txt > ListUpdated.txt
del /S /Q temp.txt >nul
For /F "Tokens=1-3* Delims=-" %%a in ('Dir /B ".\%bit%\*.msu"') Do Call :matching %%a %%b %%c %%d
goto :EOF

:matching
for /f "Tokens=1 Delims= " %%e in ('FindStr /IB "%2" "ListUpdated.txt"') do set upd=%%e
if "%2"=="%upd%" (echo Обновление %2 присутствует в системе.>>%~n0.log)

Данный код, проверяет, установлено ли обновление, которое находится в папке %bit%, в системе или нет. А нужно наоборот, если ли в папке %bit% обновление, которое установлено в системе, или нет?

Devils0411 06-02-2012 10:52 1852714

Доработал код, но есть одно "но":
Код:

@Echo off
SetLocal enabledelayedexpansion
if exist "%ProgramFiles(x86)%" (set bit=x64) else (set bit=x86)
Title Поиск отсутствующих обновлений для Windows %bit%
wmic qfe get HotFixID >temp.txt
.\iconv\iconv -c -f UTF-16LE -t CP866 temp.txt > CheckUpdates.txt
del /S /Q temp.txt >nul
for /f "Tokens=1 Delims=" %%a in ('FindStr /IB "KB" "CheckUpdates.txt"') do Call :files %%a
goto :EOF

:files
For /F "Tokens=2 Delims=-" %%b in ('Dir /B ".\%bit%\*.msu"') Do Call :matching %1 %%b

:matching
if "%1"=="%2" (echo Обновление %1 присутствует в папке %~dp0%bit%>>%~n0.log)
if "%2"=="" (echo Обновление %1 отсутствует в папке %~dp0%bit%>>%~n0.log)

При %%a==%%b, должно происходить следующее сравнение значения переменной %%a с множеством значений переменной %%b, а получается так, что даже когда переменные %%a, и %%b равны, то сравнение %%a идет до тех пор, пока значения %%b не закончатся, и тогда выполняется условие ""=="".

Devils0411 21-03-2012 12:13 1883853

Что-то ни как не получается довести до ума. Может кто подскажет, где ошибка?

gora 21-03-2012 13:33 1883900

Devils0411, попробуйте так:
Код:

@Echo off
SetLocal enabledelayedexpansion
if exist "%ProgramFiles(x86)%" (set bit=x64) else (set bit=x86)
Title Поиск отсутствующих обновлений для Windows %bit%
wmic qfe get HotFixID >temp.txt
Type temp.txt >CheckUpdates.txt
del /S /Q temp.txt >nul
(for /f "Tokens=1 Delims=" %%a in ('FindStr /IB "KB" "CheckUpdates.txt"') do (
        Set kb=%%a
        Set kb=!kb: =!
        Call :files !kb!
        echo Обновление !kb! !flag! в папке %~dp0%bit%
))>%~n0.log
Pause>nul

:files
Set flag=отсутствует
For /F "Tokens=2 Delims=-" %%k in ('Dir /B "%bit%\*.msu"') Do If %%k==%1 Set flag=присутствует& goto :EOF
goto :EOF


sov44 20-10-2012 20:41 2009169

В папке Office_Updates находятся два типа файлов *.msp (шестизначные КВ типа KB907417-OTKLOADR.msp, KB981716-MSACCESS.msp и семизначные КВ типа KB2535812-POWERPNT.msp, KB2598253-GDIPLUS.msp) Необходимо вывести в Echo в порядке возрастания номеров сначала шестизначные КВ9.., затем семизначные КВ2..

сделал немного криво, может есть более оптимальное решение:
Код:

@echo off
SetLocal EnableDelayedExpansion

for /f %%a in ('dir /b/on "Office_Updates\*.msp"') do (
set up1=%%a
if /i "!up1:~2,1!"=="9" (echo !up1!)
)
for /f %%a in ('dir /b/on "Office_Updates\*.msp"') do (
set up2=%%a
if /i "!up2:~2,1!"=="2" (echo !up2!)
)

pause
exit


Iska 20-10-2012 21:16 2009187

Попробуйте так:
читать дальше »
Код:

Option Explicit

Const adInteger  =  3
Const adVarChar  = 200


Dim objRegExp
Dim objFile


Set objRegExp = WScript.CreateObject("VBScript.RegExp")

With objRegExp
        .IgnoreCase = True
        .Pattern = "KB(\d{6,7}).*\.msp"
End With

With WScript.CreateObject("ADOR.Recordset")
        With .Fields
                .Append "KB FileName",                  adVarChar, 2^8 - 1
                .Append "KB Number",                    adInteger
        End With
       
        .Open
       
        For Each objFile In WScript.CreateObject("Scripting.FileSystemObject").GetFolder(WScript.Arguments.Item(0)).Files
                If objRegExp.Test(objFile.Name) Then
                        .AddNew
                       
                        .Fields.Item("KB FileName").Value = objFile.Name
                        .Fields.Item("KB Number").Value  = CLng(objRegExp.Execute(objFile.Name).Item(0).SubMatches.Item(0))
                End If
        Next
       
        .Sort = "[KB Number]"
       
        .MoveFirst
       
        Do Until .EOF
                WScript.Echo .Fields.Item("KB FileName")
                .MoveNext
        Loop
       
        .Close
End With

Set objRegExp = Nothing

WScript.Quit 0


Путь к папке указывайте аргументом скрипта, наподобие:
Код:

cscript.exe //nologo "c:\Scripts\This Script.vbs" "c:\Projects\Office_Updates"

sov44 20-10-2012 21:20 2009191

Iska, нужен именно батник, т.к. в дальнейшем Echo будет посылаться как аргумент для создания ini

gora 20-10-2012 21:33 2009195

sov44, попробуйте так:
Код:

@Echo Off
SetLocal EnableDelayedExpansion
Set fldr=e:\Temp 1\Office_Updates

For /F %%a In ('Dir "%fldr%" /B /A:-D') Do (
        Set ta=%%~nxa
        If "!ta:~8,1!"=="-" (
                Set $!ta:~0,2!0!ta:~2,6!=%%~nxa
        ) Else (
                Set $!ta:~0,9!=%%~nxa
        )
)

For /F "Tokens=2 Delims==" %%a In ('Set $KB') Do Echo %%a
Pause>nul


Iska 20-10-2012 21:52 2009201

Цитата:

Цитата sov44
т.к. в дальнейшем Echo будет посылаться как аргумент для создания ini »

Посылайте:
читать дальше »
Код:

@echo off
setlocal enableextensions enabledelayedexpansion

for /f "usebackq delims=" %%i in (
        `cscript.exe //nologo "c:\Scripts\This Script.vbs" "c:\Projects\Office_Updates"`
) do echo %%i

endlocal
exit /b 0


кто мешает ;).

sov44 20-10-2012 23:09 2009247

gora, поясните пожалуйста код. В частности не понятно, куда девается ноль после КВ и где идёт сортировка

gora 20-10-2012 23:27 2009258

Цитата:

Цитата sov44
где идёт сортировка »

Сортировка выполняется командой Set $KB, которая выводит список всех переменных начинающихся с $KB в алфавитном порядке.
Цитата:

Цитата sov44
куда девается ноль после КВ »

Нуль есть в имени переменной, а выводится значение переменной, в котором сохранено имя и расширение файла без изменений. Пример:
Код:

$KB0907417=KB907417-OTKLOADR.msp
$KB0981716=KB981716-MSACCESS.msp
$KB2535812=KB2535812-POWERPNT.msp
$KB2598253=KB2598253-GDIPLUS.msp


sov44 20-10-2012 23:54 2009276

Выяснился нюанс: нашлась пара обновлений, у которых одинаковая первая часть имени, но отличная вторая:
KB947319-OWC10.msp KB981716-ACCWIZ.msp
KB947319-OWC11.msp KB981716-MSACCESS.msp
Код к сожалению вывел только по одному обновлению из пары. :(

Iska 21-10-2012 00:46 2009313

Цитата:

Цитата gora
командой Set $KB, которая выводит список »

Хорошая идея. Возьму на заметку.

sov44 21-10-2012 00:47 2009314

похоже решил:
Код:

@Echo Off
SetLocal EnableDelayedExpansion
Set fldr=Office_Updates

For /F  %%a In ('Dir "%fldr%" /B /A:-D') Do (
        Set ta=%%~nxa
            If "!ta:~8,1!"=="-" (
                Set $!ta:*KB=KB0!=%%~nxa
        ) Else (
                Set $!ta!=%%~nxa
        )
)
For /F "Tokens=2 Delims==" %%a In ('Set $KB') Do Echo %%a
Pause>nul


Iska 21-10-2012 00:48 2009315

Код:

@echo off
setlocal enableextensions enabledelayedexpansion

set sFolder=e:\Temp 1\Office_Updates

for /f "delims=" %%i in (
        'dir /b /o:n "%sFolder%\kb??????-*.msp" ^& dir /b /o:n "%sFolder%\kb???????-*.msp"'
) do echo %%i

endlocal
exit /b 0

Неужели всё так просто оказалось?! Ажник не верится…

gora 21-10-2012 11:55 2009463

Цитата:

Цитата sov44
похоже решил: »

Тогда первый цикл можно немного упростить:
Код:

...
For /F  %%a In ('Dir "%fldr%" /B') Do (
        Set ta=%%~na
        If "!ta:~8,1!"=="-" Set ta=!ta:*KB=KB0!
        Set $!ta!=%%~nxa
)...


Foreigner 21-10-2012 17:27 2009625

Цитата:

Цитата sov44
HKLM\Software\Microsoft\Windows\CurrentVersion\Uninstall »

У меня там нет ни одного "KB". Но:
Код:

systeminfo | findstr "KB*"
находит 149

sov44 21-10-2012 18:42 2009670

Foreigner, http://savepic.su/2707533.htm

Foreigner 21-10-2012 19:44 2009710

sov44, В 7-ке нет такого.


Время: 20:28.

Время: 20:28.
© OSzone.net 2001-