Ich möchte noch einmal einen Vorschlag aufgreifen, den ich vor einiger Zeit vorgestellt hatte:
viewtopic.php?f=5&t=5082
Dieser Thread beschreibt eine neue Methode zur Bestimmung der superseded Updates. Zusammengehörige Felder werden aus der Datei package.xml extrahiert, indem die relativen Pfade innerhalb der Datei (XPATH) berücksichtigt werden. Die extrahierten Daten können anschließend mit join verknüpft werden. Dann sind nur noch drei Schritte zur Bestimmung der superseded Updates nötig:
Die Vorteile sind:
- Die Methode ist genauer, da die Beziehungen zwischen den extrahierten Datenfeldern erhalten bleiben.
- Die Methode ist schneller, da sie keine langen Programmschleifen im Skript verwendet. Sie benötigt nur GNU sort und join zur Verknüpfung der Daten.
Anwendung der Datei ExcludeList-superseded.txt
Die Bestimmung der superseded Updates liefert eine Datei mit vollständigen URLs. Die Bestimmung der dynamischen Updates liefert ebenfalls eine Datei mit vollständigen URLs. Beide Dateien können mit join verglichen werden. "join -v1" liefert dabei einen "left join", also die URLs, die nur auf der linken Seite vorkommen. Die Datei ExcludeList-superseded.txt sollte deshalb in einem separaten Schritt angewendet werden:
- Code: Select all
join -v1 DynamicDownloadLinks.txt ExcludeList-superseded.txt > ValidDynamicLinks.txt
join ist für diesen Schritt effizienter als FindStr.exe oder grep:
- join kann zwei sortierte Dateien vergleichen, indem abwechselnd aus beiden Dateien gelesen wird.
- FindStr.exe und grep müssen dagegen jede Zeile der einen Datei mit jeder Zeile der anderen Datei vergleichen. FindStr.exe hat beim Vergleich großer Dateien Schwächen gezeigt, und grep scheint bei diesem Schritt manchmal zu viel Arbeitsspeicher zu verbrauchen.
viewtopic.php?f=5&t=4836
viewtopic.php?f=9&t=4507
Anschließend müssen noch weitere ExcludeLists angewendet werden, die nur KB-Nummern enthalten. Dazu wird dann doch wieder FindStr.exe oder grep eingesetzt. Diese Dateien sind aber weitaus kleiner als die Datei ExcludeList-superseded.txt.
Eine Beispielimplementierung zum Bestimmung und Anwendung der superseded Updates sieht dann so aus:
- Code: Select all
@echo off
setlocal enableextensions enabledelayedexpansion
set CSCRIPT_PATH=%SystemRoot%\System32\cscript.exe
set DOWNLOAD_LOGFILE=..\log\download.log
set DLDR_PATH=..\bin\wget.exe
set DLDR_COPT=-N
set DLDR_LOPT=-a %DOWNLOAD_LOGFILE%
set DLDR_IOPT=-i
set DLDR_POPT=-P
set DLDR_NVOPT=-nv
rem Always recalculate superseded updates
if exist ..\exclude\ExcludeList-superseded.txt del ..\exclude\ExcludeList-superseded.txt
rem Make Temp folder easier to find
if not exist ..\Temp\nul md ..\Temp
set TEMP=..\Temp
rem Configure proxy server
rem set http_proxy=http://192.168.2.101:3128
rem Example implementation for the determination of superseded updates.
rem
rem This is an excerpt of the script DownloadUpdates.cmd with revised parts
rem for the calculation of superseded updates and dynamic download links.
rem Get WSUS catalog file
echo Downloading/validating most recent Windows Update Agent installation and catalog files...
%DLDR_PATH% %DLDR_COPT% %DLDR_IOPT% ..\static\StaticDownloadLinks-wsus.txt %DLDR_POPT% ..\client\wsus
if errorlevel 1 goto DownloadError
echo %DATE% %TIME% - Info: Downloaded/validated most recent Windows Update Agent installation and catalog files>>%DOWNLOAD_LOGFILE%
call :DownloadCore w60 glb x86
if errorlevel 1 goto Error
goto EoF
:DownloadCore
rem *** Determine update urls for %1 %2 ***
rem *** Extract Microsoft's update catalog file package.xml ***
echo Extracting Microsoft's update catalog file package.xml...
if exist "%TEMP%\package.cab" del "%TEMP%\package.cab"
if exist "%TEMP%\package.xml" del "%TEMP%\package.xml"
%SystemRoot%\System32\expand.exe ..\client\wsus\wsusscn2.cab -F:package.cab "%TEMP%" >nul
%SystemRoot%\System32\expand.exe "%TEMP%\package.cab" "%TEMP%\package.xml" >nul
del "%TEMP%\package.cab"
rem *** Determine superseded updates ***
rem *** Download ExcludeList-superseded-exclude.txt ***
for %%i in (..\client\wsus\wsusscn2.cab) do echo %%~ai | %SystemRoot%\System32\find.exe /I "a" >nul 2>&1
if not errorlevel 1 (
if exist ..\exclude\ExcludeList-superseded.txt del ..\exclude\ExcludeList-superseded.txt
)
copy /Y ..\exclude\ExcludeList-superseded-exclude.txt ..\exclude\ExcludeList-superseded-exclude.ori >nul
%DLDR_PATH% %DLDR_COPT% %DLDR_NVOPT% %DLDR_POPT% ..\exclude %DLDR_LOPT% http://download.wsusoffline.net/ExcludeList-superseded-exclude.txt
echo n | %SystemRoot%\System32\comp.exe ..\exclude\ExcludeList-superseded-exclude.txt ..\exclude\ExcludeList-superseded-exclude.ori /A /L /C >nul 2>&1
if errorlevel 1 (
if exist ..\exclude\ExcludeList-superseded.txt del ..\exclude\ExcludeList-superseded.txt
)
del ..\exclude\ExcludeList-superseded-exclude.ori
if exist ..\exclude\ExcludeList-superseded.txt (
echo Found valid list of superseded updates.
echo %DATE% %TIME% - Info: Found valid list of superseded updates>>%DOWNLOAD_LOGFILE%
goto SkipSuperseded
)
echo %TIME% - Determining superseded updates (please be patient, this will take a while)...
rem *** Revised part for determination of superseded updates starts here ***
rem *** First step ***
echo Extract file 1
%CSCRIPT_PATH% //Nologo //E:vbs XSLT.vbs "%TEMP%\package.xml" ..\xslt\extract-existing-bundle-revision-ids.xsl "%TEMP%\existing-bundle-revision-ids.txt"
..\bin\gsort.exe -u -T "%TEMP%" "%TEMP%\existing-bundle-revision-ids.txt" > "%TEMP%\existing-bundle-revision-ids-unique.txt"
del "%TEMP%\existing-bundle-revision-ids.txt"
echo Extract file 2
%CSCRIPT_PATH% //Nologo //E:vbs XSLT.vbs "%TEMP%\package.xml" ..\xslt\extract-superseding-and-superseded-revision-ids.xsl "%TEMP%\superseding-and-superseded-revision-ids.txt"
..\bin\gsort.exe -u -T "%TEMP%" "%TEMP%\superseding-and-superseded-revision-ids.txt" > "%TEMP%\superseding-and-superseded-revision-ids-unique.txt"
del "%TEMP%\superseding-and-superseded-revision-ids.txt"
echo Join files 1 and 2 to file 3
..\bin\join.exe -t "," -o "2.2" "%TEMP%\existing-bundle-revision-ids-unique.txt" "%TEMP%\superseding-and-superseded-revision-ids-unique.txt" > "%TEMP%\ValidSupersededRevisionIds.txt"
del "%TEMP%\existing-bundle-revision-ids-unique.txt"
del "%TEMP%\superseding-and-superseded-revision-ids-unique.txt"
..\bin\gsort.exe -u -T "%TEMP%" "%TEMP%\ValidSupersededRevisionIds.txt" > "%TEMP%\ValidSupersededRevisionIds-unique.txt"
del "%TEMP%\ValidSupersededRevisionIds.txt"
rem *** Second step ***
echo Extract file 4
%CSCRIPT_PATH% //Nologo //E:vbs XSLT.vbs "%TEMP%\package.xml" ..\xslt\extract-update-revision-and-file-ids.xsl "%TEMP%\BundledUpdateRevisionAndFileIds.txt"
..\bin\gsort.exe -u -T "%TEMP%" "%TEMP%\BundledUpdateRevisionAndFileIds.txt" > "%TEMP%\BundledUpdateRevisionAndFileIds-unique.txt"
del "%TEMP%\BundledUpdateRevisionAndFileIds.txt"
echo Join files 3 and 4 to file 5
..\bin\join.exe -t "," -o "2.3" "%TEMP%\ValidSupersededRevisionIds-unique.txt" "%TEMP%\BundledUpdateRevisionAndFileIds-unique.txt" > "%TEMP%\SupersededFileIds.txt"
del "%TEMP%\ValidSupersededRevisionIds-unique.txt"
del "%TEMP%\BundledUpdateRevisionAndFileIds-unique.txt"
..\bin\gsort.exe -u -T "%TEMP%" "%TEMP%\SupersededFileIds.txt" > "%TEMP%\SupersededFileIds-unique.txt"
del "%TEMP%\SupersededFileIds.txt"
rem *** Third step ***
echo Extract file 6
%CSCRIPT_PATH% //Nologo //E:vbs XSLT.vbs "%TEMP%\package.xml" ..\xslt\extract-update-cab-exe-ids-and-locations.xsl "%TEMP%\UpdateCabExeIdsAndLocations.txt"
..\bin\gsort.exe -u -T "%TEMP%" "%TEMP%\UpdateCabExeIdsAndLocations.txt" > "%TEMP%\UpdateCabExeIdsAndLocations-unique.txt"
del "%TEMP%\UpdateCabExeIdsAndLocations.txt"
echo Join files 5 and 6 to file 7
..\bin\join.exe -t "," -o "2.2" "%TEMP%\SupersededFileIds-unique.txt" "%TEMP%\UpdateCabExeIdsAndLocations-unique.txt" > "%TEMP%\ExcludeListLocations-superseded-all.txt"
del "%TEMP%\SupersededFileIds-unique.txt"
del "%TEMP%\UpdateCabExeIdsAndLocations-unique.txt"
..\bin\gsort.exe -u -T "%TEMP%" "%TEMP%\ExcludeListLocations-superseded-all.txt" > "%TEMP%\ExcludeListLocations-superseded-all-unique.txt"
del "%TEMP%\ExcludeListLocations-superseded-all.txt"
rem *** Apply ExcludeList-superseded-exclude.txt ***
if exist ..\exclude\ExcludeList-superseded-exclude.txt copy /Y ..\exclude\ExcludeList-superseded-exclude.txt "%TEMP%\ExcludeList-superseded-exclude.txt" >nul
if exist ..\exclude\custom\ExcludeList-superseded-exclude.txt (
type ..\exclude\custom\ExcludeList-superseded-exclude.txt >>"%TEMP%\ExcludeList-superseded-exclude.txt"
)
rem Delete file if empty
for %%i in ("%TEMP%\ExcludeList-superseded-exclude.txt") do if %%~zi==0 del %%i
if exist "%TEMP%\ExcludeList-superseded-exclude.txt" (
%SystemRoot%\System32\findstr.exe /L /I /V /G:"%TEMP%\ExcludeList-superseded-exclude.txt" "%TEMP%\ExcludeListLocations-superseded-all-unique.txt" >..\exclude\ExcludeList-superseded.txt
del "%TEMP%\ExcludeListLocations-superseded-all-unique.txt"
del "%TEMP%\ExcludeList-superseded-exclude.txt"
) else (
move /Y "%TEMP%\ExcludeListLocations-superseded-all-unique.txt" ..\exclude\ExcludeList-superseded.txt >nul
)
%SystemRoot%\System32\attrib.exe -A ..\client\wsus\wsusscn2.cab
echo %TIME% - Done.
echo %DATE% %TIME% - Info: Determined superseded updates>>%DOWNLOAD_LOGFILE%
:SkipSuperseded
rem At this point, the file ..\exclude\ExcludeList-superseded.txt still
rem contains complete URLs, rather than just the file names.
rem Determination of static updates can be skipped, because there are no
rem changes here.
rem *** Suggested usage of the file ..\exclude\ExcludeList-superseded.txt
rem for the determination of valid dynamic download links ***
:DetermineWindows
rem *** Determine dynamic update urls for %1 %2 ***
echo %TIME% - Determining dynamic update urls for %1 %2...
if exist ..\xslt\ExtractDownloadLinks-%1-%2.xsl (
%CSCRIPT_PATH% //Nologo //B //E:vbs XSLT.vbs "%TEMP%\package.xml" ..\xslt\ExtractDownloadLinks-%1-%2.xsl "%TEMP%\DynamicDownloadLinks-%1-%2.txt"
if errorlevel 1 goto DownloadError
)
if exist ..\xslt\ExtractDownloadLinks-%1-%3-%2.xsl (
%CSCRIPT_PATH% //Nologo //B //E:vbs XSLT.vbs "%TEMP%\package.xml" ..\xslt\ExtractDownloadLinks-%1-%3-%2.xsl "%TEMP%\DynamicDownloadLinks-%1-%2.txt"
if errorlevel 1 goto DownloadError
)
del "%TEMP%\package.xml"
if not exist "%TEMP%\DynamicDownloadLinks-%1-%2.txt" goto DoDownload
rem A left join of the files DynamicDownloadLinks.txt and
rem ExcludeList-superseded.txt returns URLs, which are unique
rem to the left side. The intermediate file will be called
rem "DynamicDownloadLinks-pruned.txt".
rem As always, both input files must be sorted.
..\bin\gsort.exe -u -T "%TEMP%" "%TEMP%\DynamicDownloadLinks-%1-%2.txt" > "%TEMP%\DynamicDownloadLinks-%1-%2-unique.txt"
del "%TEMP%\DynamicDownloadLinks-%1-%2.txt"
..\bin\join.exe -v1 "%TEMP%\DynamicDownloadLinks-%1-%2-unique.txt" ..\exclude\ExcludeList-superseded.txt > "%TEMP%\DynamicDownloadLinks-%1-%2-pruned.txt"
del "%TEMP%\DynamicDownloadLinks-%1-%2-unique.txt"
rem The remaining exclude lists are applied as before.
if exist "%TEMP%\ExcludeList-%1.txt" del "%TEMP%\ExcludeList-%1.txt"
if exist ..\exclude\ExcludeList-%1.txt copy /Y ..\exclude\ExcludeList-%1.txt "%TEMP%\ExcludeList-%1.txt" >nul
if exist ..\exclude\custom\ExcludeList-%1.txt (
type ..\exclude\custom\ExcludeList-%1.txt >>"%TEMP%\ExcludeList-%1.txt"
)
if exist "%TEMP%\ExcludeList-%1.txt" goto ExcludeWindows
if exist ..\exclude\ExcludeList-%1-%3.txt copy /Y ..\exclude\ExcludeList-%1-%3.txt "%TEMP%\ExcludeList-%1.txt" >nul
if exist ..\exclude\custom\ExcludeList-%1-%3.txt (
type ..\exclude\custom\ExcludeList-%1-%3.txt >>"%TEMP%\ExcludeList-%1.txt"
)
:ExcludeWindows
if exist ..\exclude\custom\ExcludeListForce-all.txt (
type ..\exclude\custom\ExcludeListForce-all.txt >>"%TEMP%\ExcludeList-%1.txt"
)
if exist "%TEMP%\ValidDynamicLinks-%1-%2.txt" del "%TEMP%\ValidDynamicLinks-%1-%2.txt"
%SystemRoot%\System32\findstr.exe /L /I /V /G:"%TEMP%\ExcludeList-%1.txt" "%TEMP%\DynamicDownloadLinks-%1-%2-pruned.txt" >>"%TEMP%\ValidDynamicLinks-%1-%2.txt"
if not exist "%TEMP%\ValidDynamicLinks-%1-%2.txt" ren "%TEMP%\DynamicDownloadLinks-%1-%2-pruned.txt" ValidDynamicLinks-%1-%2.txt
if exist "%TEMP%\ExcludeList-%1.txt" del "%TEMP%\ExcludeList-%1.txt"
if exist "%TEMP%\DynamicDownloadLinks-%1-%2-pruned.txt" del "%TEMP%\DynamicDownloadLinks-%1-%2-pruned.txt"
echo %TIME% - Done.
echo %DATE% %TIME% - Info: Determined dynamic update urls for %1 %2>>%DOWNLOAD_LOGFILE%
goto DoDownload
:DoDownload
rem End of function :DownloadCore
verify >nul
goto :eof
:DownloadError
:Error
:EoF
endlocal
Dieses Beispielskript kann aus dem Verzeichnis wsusoffline\cmd oder einem anderen Verzeichnis auf derselben Ebene aufgerufen werden.
Die vier verwendeten XSLT-Dateien sind dieselben wie im Beitrag:
Übersetzung in XSLT-Dateien (Teil 8)
viewtopic.php?f=5&t=5082#p16399
Diese XSLT-Dateien gehören in das Verzeichnis wsusoffline\xslt. Außerdem wird die Datei XSLT.vbs benötigt, die im selben Verzeichnis liegen muss wie das Beispielskript.
Edit: Setzen des Proxy Servers wurde auskommentiert