Tom Joad
23-05-2013, 19:09
Ciao a tutti,
ho creato uno script per tenere aggiornate le ISO di Windows 7 e Windows 8 (x64 e x86) integrando tutti gli aggiornamenti rilasciati.
Link: https://www.sugarsync.com/pf/D6714227_8_8488788238
Per utilizzarlo è necessario scompattare l'archivio in un percorso che non contenga spazi (es: C:\IsoUpdater), copiare uno o più file ISO nella cartella \Iso e lanciare il file IsoUpdater.cmd con privilegi di amministratore.
FUNZIONAMENTO DELLO SCRIPT
Verifica dei privilegi dell'utente
Per eseguire lo Strumento gestione e manutenzione immagini distribuzione (dism.exe) è necessario che l'utente disponga dei privilegi di amministratore.
Se l'utente non dispone dei privilegi sufficienti, lo script termina:
http://s13.postimg.org/5yabxm6l3/image.png
:CheckPrivileges
net session >nul 2>&1
if not %ErrorLevel% == 0 (
echo L'utente non possiede i privilegi di amministratore
echo.
echo Il programma verra' terminato
goto End
)
Questa parte di codice è stata copiata spudoratamente da questo post: http://stackoverflow.com/questions/4051883/batch-script-how-to-check-for-admin-rights
Creazione cartella temporanea
Viene creata la cartella \Temp, dove verranno appoggiati tutti i file necessari. Se la cartella esiste già (può succedere quando si interrompe lo scipt prima di arrivare alla fine) viene cancellata e ricreata:
:MainLoop
cls
if exist %_tempDir% rd %_tempDir% /s /q
md %_tempDir%
Ricerca immagini iso
Viene effettuata una scansione della cartella \Iso. Se non è presente alcun file lo script termina:
http://s13.postimg.org/9cnx00clz/image.png
echo Ricerca file ISO
echo.
call :Iso.ScanDir
if !_foundIso! equ 0 (
cls
echo Nessun file trovato
echo.
echo Copiare un'immagine ISO nella seguente cartella e riavviare il programma:
echo.
echo %_isoDir%
echo.
goto End
)
...
:Iso.ScanDir
dir /b %_isoDir%\*.iso>%_isoDirList%
set /a _foundIso=0
for /f %%G in (%_isoDirList%) do set /a _foundIso+=1
goto :eof
Nel caso in cui vengano trovati uno o più file viene richiesto di selezionare la ISO da aggiornare:
http://s13.postimg.org/dpmgiflcn/image.png
echo !_foundIso! file trovati
echo.
echo Selezionare un file:
echo.
call :Iso.Select
cls
echo File: !_isoFile!
echo.
...
:Iso.Select
set _outputFile=%_tempDir%\SelectIso.cmd
echo @echo off>%_outputFile%
echo :_choice>>%_outputFile%
set /a _counter=0
for /f %%G in (%_isoDirList%) do (
set /a _counter+=1
echo echo !_counter!. %%G>>%_outputFile%
echo echo.>>%_outputFile%
)
set /a _counter=0
echo set /p _choice=SELEZIONE: >>%_outputFile%
for /f %%G in (%_isoDirList%) do (
set /a _counter+=1
echo if [%%_choice%%]==[!_counter!] set _isoFile=%%G>>%_outputFile%
)
echo if not defined _isoFile echo.^& echo SELEZIONE NON VALIDA^&echo. ^&goto _choice>>%_outputFile%
echo echo.>>%_outputFile%
call %_outputFile%
del %_outputFile% /q
set _outputFile=
goto :eof
Estrazione dei file ei.cfg e idwbinfo.txt
Questi due file servono nel prossimo step per rilevare il sistema operativo e l'edizione:
call :ISO.ExtractFiles
...
:ISO.ExtractFiles
start /wait /min %_binDir%\7Z.exe e %_isoDir%\!_isoFile! sources\ei.cfg sources\idwbinfo.txt -o%_tempDir% -y
goto :eof
Rilevamento del sistema operativo e dell'architetture (x86 o x64)
Lo script legge il file idwbinfo.txt per rilevare il sistema operativo. Prima di fare ciò è necessario accertarsi che tal file esista:
if not exist %_tempDir%\idwbinfo.txt (
echo Impossibile rilevare il sistema operativo. Il programma verra' terminato
echo.
goto End
)
http://s13.postimg.org/s7jnqfcnr/06a.png
Se il file è nel posto giusto:
http://s13.postimg.org/e7m7c10bb/06b.png
call :OS.DetectName
call :OS.DetectArch
...
:OS.DetectName
for /f "tokens=1 delims=," %%G in (%_osIndex%) do (
find /i "%%G" %_tempDir%\idwbinfo.txt >nul && set _osName=%%G
)
goto :eof
:OS.DetectArch
for /f "tokens=2 delims=," %%G in (%_osIndex%) do (
find /i "%%G" %_tempDir%\idwbinfo.txt >nul && set _osArch=%%G
)
goto :eof
Lettura file di configurazione
Per ogni sistema operativo c'è un file di configurazione (spiegherò i file di configurazione nel post successivo) nella cartella \Config
Ora che sono stati rilevati sistema operativo ed architettura lo script sa quale file di configurazione andare a leggere (il nome del file è composto da due parti: NomeOS_Architettura.ini, ad esempio Win7sp1amd64.ini). Le variabili necessarie sono state impostate nello step precedente (ad es: _osName=Win7sp1 e _osArch=amd64).
call :ConfigFile.Read
...
:ConfigFile.Read
set _configFile=%_configDir%\!_osName!!_osArch!.ini
for /f "delims=" %%G in (%_configFile%) do (
set _line=%%G
set _lineFirstChar=!_line:~0,1!
if "!_lineFirstChar!" == "[" (
set _currentArea=!_line:~1,-1!
set _outputFile=%_tempDir%\!_currentArea!.txt
type nul >!_outputFile!
) else (
echo !_line!>>!_outputFile!
)
)
goto :eof
Rilevamento (o selezione manuale) dell'edizione
Per rilevare l'edizione lo script legge il file ei.cfg. Tuttavia ho notato che nelle ISO di Windows 8 questo file non è presente. Lo script verifica prima se il file ei.cfg esiste nella cartella temporanea. In caso contrario chiede di selezionare manualmente l'edizione:
http://s13.postimg.org/4ociikct3/image.png
if exist %_tempDir%\ei.cfg (
call :OS.DetectEdition
echo Sistema Operativo: !_osDescription! !_osExtendedEdition!
echo.
) else (
echo Sistema Operativo: !_osDescription!
echo.
echo E' necessario selezionare manualmente l'edizione:
echo.
call :OS.SelectEdition
cls
echo File selezionato: !_isoFile!
echo.
echo Sistema Operativo: !_osDescription! !_osExtendedEdition!
echo.
)
...
:OS.DetectEdition
for /f "tokens=1-3 delims=," %%G in (%_editionsIndex%) do (
find /i "%%H" %_tempDir%\ei.cfg >nul && set _wimIndex=%%G&& set _osEdition=%%H&& set _osExtendedEdition=%%I
)
goto :eof
...
:OS.SelectEdition
set _outputFile=%_tempDir%\SelectOsEdition.cmd
echo @echo off>%_outputFile%
echo :_choice>>%_outputFile%
set /a _counter=0
for /f "tokens=1-3 delims=," %%G in (%_editionsIndex%) do (
set /a _counter+=1
echo echo !_counter!. %%I>>%_outputFile%
echo echo.>>%_outputFile%
)
set /a _counter=0
echo set /p _choice=Selezione: >>%_outputFile%
for /f "tokens=1-3 delims=," %%G in (%_editionsIndex%) do (
set /a _counter+=1
echo if [%%_choice%%]==[!_counter!] set _wimIndex=%%G^& set _osEdition=%%H^& set _osExtendedEdition=%%I>>%_outputFile%
)
echo if not defined _wimIndex echo.^& echo Selezione non valida^& echo. ^&goto _choice>>%_outputFile%
call %_outputFile%
del %_outputFile% /q
set _outputFile=
goto :eof
Interner Explorer
In Windows 8 è possibile utilizzare solo Internet Explorer 10. In Windows 7 invece ci sono Internet Explorer 8, 9 e 10.
Come prima cosa lo script rileva la versione di default, leggendo la prima riga di un file (IexploreIndex.txt) creato nella cartella temporanea leggendo il file di configurazione:
call :IE.DetectDefault
set _selectedIE=%_defaultIE%
...
:IE.DetectDefault
for /f "tokens=1 delims=," %%G in ('type %_iexploreIndex%') do (
set _defaultIE=%%G
exit /b
)
goto :eof
Dopo di che conta le righe del file e determina se ci sono più versioni di Internet Explorer supportate:
call :IE.CountVersions
...
:IE.CountVersions
set /a _ieCounter=0
for /f %%G in (%_iexploreIndex%) do set /a _ieCounter+=1
goto :eof
In quest'ultimo caso, chiede di selezionare la versione:
http://s24.postimg.org/y3s6z0rc5/image.png
if %_ieCounter% gtr 1 (
echo Selezionare la versione di Internet Explorer:
echo.
call :IE.Select
)
echo %_selectedIE%>>%_integrateList%
...
:IE.Select
set _outputFile=%_tempDir%\SelectIE.cmd
echo @echo off>%_outputFile%
echo :_choice>>%_outputFile%
set /a _counter=0
for /f "tokens=1,2 delims=," %%G in (%_iexploreIndex%) do (
set /a _counter+=1
echo echo !_counter!. %%H>>%_outputFile%
echo echo.>>%_outputFile%
)
echo set /p _choice=Selezione: >>%_outputFile%
set /a _counter=0
for /f "tokens=1,2 delims=," %%G in (%_iexploreIndex%) do (
set /a _counter+=1
echo if [%%_choice%%]==[!_counter!] set _selectedIE=%%G>>%_outputFile%
)
echo if not defined _selectedIE echo.^& echo Selezione non valida^&echo. ^&goto _choice>>%_outputFile%
echo echo.>>%_outputFile%
call %_outputFile%
del %_outputFile% /q
set _outputFile=
goto :eof
Scansione cartella Updates
In base alle informazioni fornite fino ad ora lo script costruisce un indice da confrontare con i file presenti nella cartella \Updates. Gli aggiornamenti non trovati vengono inclusi in una lista di file da scaricare:
echo Ricerca aggiornamenti
echo.
call :Updates.BuildIndex
call :Updates.ScanDir
...
:Updates.BuildIndex
set _tempFile=%_integrateIndex%.tmp
for /f "tokens=1-4 delims=," %%G in (%_integrateIndex%) do find "%%H" %_integrateList% >nul && echo %%G,%%H,%%I,%%J>>%_tempFile%
move %_tempFile% %_integrateIndex% >nul
set _tempFile=
goto :eof
...
:Updates.ScanDir
type nul >%_downloadIndex%
dir /b %_updatesDir%>%_updatesDirList%
set /a _totalUpdates=0
for /f %%G in (%_integrateIndex%) do set /a _totalUpdates+=1
for /f %%G in (%_setupcompleteIndex%) do set /a _totalUpdates+=1
if not [!_defaultIE!]==[!_selectedIE!] set /a _totalUpdates+=1
set /a _foundUpdates=0
set /a _notFoundUpdates=0
for /f "tokens=1-4 delims=," %%G in (%_integrateIndex%) do find /i "%%G" %_updatesDirList% >nul && (set /a _foundUpdates+=1) || (set /a _notFoundUpdates+=1 && echo %%G,%%J>>%_downloadIndex%)
for /f "tokens=1-4 delims=," %%G in (%_setupcompleteIndex%) do find /i "%%G" %_updatesDirList% >nul && (set /a _foundUpdates+=1) || (set /a _notFoundUpdates+=1 && echo %%G,%%J>>%_downloadIndex%)
if not [!_defaultIE!]==[!_selectedIE!] (
for /f "tokens=1-2 delims==" %%G in (%_tempDir%\%_selectedIE%.txt) do (set %%G=%%H)
if not exist %_updatesDir%\!_archiveName! (
set /a _notFoundUpdates+=1 && echo !_archiveName!,!_downloadURL!>>%_downloadIndex%
) else (
set /a _foundUpdates+=1
)
)
goto :eof
Download aggiornamenti mancanti
Nel caso in cui uno o più aggiornamenti non siano stati trovati nella cartella \Updates viene chiesto di effettuare il download (mediante curl.exe, presente nella cartella \Bin):
http://s13.postimg.org/5ny80j2l3/15a.png
echo %_totalUpdates% aggiornamenti totali
echo %_foundUpdates% aggiornamenti scaricati
echo %_notFoundUpdates% aggiornamenti da scaricare
echo.
if %_notFoundUpdates% gtr 0 (
echo E' necessario eseguire il download di %_notFoundUpdates% file prima di proseguire
echo.
choice /c SN /m "Eseguire il download ora?"
if errorlevel 2 goto End
if errorlevel 1 call :Updates.Download
echo.
)
...
:Updates.Download
for /f "tokens=1-2 delims=," %%G in (%_downloadIndex%) do (
echo.
echo Download di %%G in corso
echo.
%_binDir%\curl.exe -L -o %_updatesDir%\%%G "%%H" --progress-bar
)
goto :eof
Copia degli aggiornamenti
I file necessari vengono copiati nella cartella temporanea (gli aggiornamenti non integrabili saranno installati automaticamente al primo accesso):
echo Preparo gli aggiornamenti per l'integrazione
echo.
call :Updates.Copy
...
:Updates.Copy
for /f "tokens=1-3 delims=," %%G in (%_integrateIndex%) do xcopy /i %_updatesDir%\%%G %_integrateDir%\%%H\%%I\ >nul
md %_extractDir%\sources\$OEM$\$$\Setup\Scripts
echo @echo off>%_extractDir%\sources\$OEM$\$$\Setup\Scripts\SetupComplete.cmd
for /f "tokens=1-5 delims=," %%G in (%_setupcompleteIndex%) do (
xcopy /i %_updatesDir%\%%G %_setupcompleteDir%\%%H\ >nul
echo start /wait %%SYSTEMDRIVE%%\SETUPCOMPLETE\%%H\%%G %%K>>%_extractDir%\sources\$OEM$\$$\Setup\Scripts\SetupComplete.cmd
)
echo rd %%SYSTEMDRIVE%%\SETUPCOMPLETE /s /q>>%_extractDir%\sources\$OEM$\$$\Setup\Scripts\SetupComplete.cmd
goto :eof
Se la versione di Internet Explorer selezionata non è quella di default, è necessario scompattare l'archivio:
if not [!_defaultIE!]==[!_selectedIE!] call :IE.Extract
...
:IE.Extract
start /wait /min %_updatesDir%\!_archiveName! !_extractSwitch!%_tempDir%
for %%G in (!_integrateFiles!) do xcopy /i %_tempDir%\%%G %_integrateDir%\%_selectedIE%\SETUP\ >nul
goto :eof
Estrazione immagine ISO
A questo punto il file ISO viene scompattato nella cartella temporanea:
echo Estrazione immagine ISO
echo.
call :ISO.Extract
...
:ISO.Extract
start /wait /min %_binDir%\7Z.exe x %_isoDir%\!_isoFile! -o%_extractDir% -y
goto :eof
Montaggio file install.wim
http://s13.postimg.org/piov0e76f/image.png
echo Montaggio file WIM
echo.
call :Wim.Mount
...
:Wim.Mount
md %_mountDir%
set _logFile=%_tempDir%\MountWim.log
dism /mount-wim /wimfile:%_wimFile% /index:!_wimIndex! /mountdir:%_mountDir% /LogPath:%_logFile% /LogLevel:1
goto :eof
Integrazione aggiornamenti
http://s13.postimg.org/eqralarpz/20a.png
echo Integrazione aggiornamenti
echo.
call :Wim.Integrate
...
:Wim.Integrate
set _logFile=%_tempDir%\IntegrateWim.log
for /f %%G in (%_integrateList%) do (
if exist %_integrateDir%\%%G\SETUP dism /image:%_mountDir% /add-package /packagepath:%_integrateDir%\%%G\SETUP /LogPath:%_logFile% /LogLevel:1
if exist %_integrateDir%\%%G\IMPORTANT dism /image:%_mountDir% /add-package /packagepath:%_integrateDir%\%%G\IMPORTANT /LogPath:%_logFile% /LogLevel:1
if exist %_integrateDir%\%%G\RECOMMENDED dism /image:%_mountDir% /add-package /packagepath:%_integrateDir%\%%G\RECOMMENDED /LogPath:%_logFile% /LogLevel:1
if exist %_integrateDir%\%%G\OPTIONAL dism /image:%_mountDir% /add-package /packagepath:%_integrateDir%\%%G\OPTIONAL /LogPath:%_logFile% /LogLevel:1
)
goto :eof
Salvataggio del file install.wim
http://s13.postimg.org/cngvdmrx3/image.png
echo Salvataggio file WIM
echo.
call :Wim.Unmount
...
:Wim.Unmount
set _logFile=%_tempDir%\UnMountWim.log
dism /unmount-wim /mountdir:%_mountDir% /commit /LogPath:%_logFile% /LogLevel:1
if exist %_mountDir% rd %_mountDir% /s /q
goto :eof
Creazione ISO aggiornata
La ISO aggiornata si troverà nella cartella \Output alla fine del processo
echo Creazione file ISO
echo.
call :Iso.Build
...
:Iso.Build
start /wait /min %_binDir%\oscdimg.exe -h -u2 -m -b%_extractDir%\boot\etfsboot.com -l!_osName!!_osArch! %_extractDir% %_outputDir%\!_osName!_!_osArch!_!_osEdition!_!_selectedIE!.iso
goto :eof
FINE!
Alla fine dello script la cartella temporanea viene cancellate e le variabili sono annullate.
echo Operazione completata
echo.
goto End
...
:End
echo.
echo Premere un tasto per uscire
pause >nul
if exist %_tempDir% rd %_tempDir% /s /q
for /f "tokens=1 delims==" %%G in ('set _') do (set %%G=)
exit
CONSIGLI
Il montaggio/smontaggio dei file .wim ruchiede un sacco di tempo, per non parlare dell'integrazione degli aggiornamenti. Ho notato che con l'antivirus abilitato (NOD32 6.0) queste fasi sono estremamente lente. Disabilitate l'antivirus e, se possibile, lanciate lo script da un SSD.
Per determinare quali aggiornamenti andavano integrati ho creato una virtual machine per ogni SO ed ho lanciato Windows Update. Il codice non gestisce aggiornamenti opzionali come DotNet o Silverlight. Se volete integrare altro software basta andare a modificare la sezione [SetupCompleteIndex] aggiungendo, nell'ordine esatto, i file da installare al primo accesso. I delimitatori di campo sono le virgole, ed i campi sono i seguenti:
Nome File
Prodotto
Livello di gravità (Importante, Consigliato, Facoltativo)
URL per il download del file
Switch per l'installazione silenziosa
[SetupCompleteIndex]
; Aggiornamento per Windows 7 per sistemi x64 (KB2533552)
Windows6.1-KB2533552-x64.msu,WIN,IMPORTANT,http://download.microsoft.com/download/B/6/F/B6F95B10-8B74-42F2-B57A-2C559D43BC28/Windows6.1-KB2533552-x64.msu,/quiet /notesrtart
; Strumento di rimozione malware di Windows – maggio 2013 (KB890830)
Windows-KB890830-V4.20-x64.exe,MRT,IMPORTANT,http://download.microsoft.com/download/2/C/5/2C563B99-54D9-4D85-A82B-45D3CD2F53CE/Windows-KB890830-x64-V4.20.exe,/q
; Definition Update for Windows Defender - KB915597
mpas-fe-x64.exe,MPAS,IMPORTANT,http://go.microsoft.com/fwlink/?LinkID=121721&arch=x64&prod=925A3ACA-C353-458A-AC8D-A7E5EB378092,/q
Nell'ultima riga ci sono le definizioni di Windows Defender. Sono lì solo a scopo accademico: vengono aggiornate di frequente e quindi è impossibile avere l'ultima versione. Se non usate Windows Defender commentate o cancellate la riga
ho creato uno script per tenere aggiornate le ISO di Windows 7 e Windows 8 (x64 e x86) integrando tutti gli aggiornamenti rilasciati.
Link: https://www.sugarsync.com/pf/D6714227_8_8488788238
Per utilizzarlo è necessario scompattare l'archivio in un percorso che non contenga spazi (es: C:\IsoUpdater), copiare uno o più file ISO nella cartella \Iso e lanciare il file IsoUpdater.cmd con privilegi di amministratore.
FUNZIONAMENTO DELLO SCRIPT
Verifica dei privilegi dell'utente
Per eseguire lo Strumento gestione e manutenzione immagini distribuzione (dism.exe) è necessario che l'utente disponga dei privilegi di amministratore.
Se l'utente non dispone dei privilegi sufficienti, lo script termina:
http://s13.postimg.org/5yabxm6l3/image.png
:CheckPrivileges
net session >nul 2>&1
if not %ErrorLevel% == 0 (
echo L'utente non possiede i privilegi di amministratore
echo.
echo Il programma verra' terminato
goto End
)
Questa parte di codice è stata copiata spudoratamente da questo post: http://stackoverflow.com/questions/4051883/batch-script-how-to-check-for-admin-rights
Creazione cartella temporanea
Viene creata la cartella \Temp, dove verranno appoggiati tutti i file necessari. Se la cartella esiste già (può succedere quando si interrompe lo scipt prima di arrivare alla fine) viene cancellata e ricreata:
:MainLoop
cls
if exist %_tempDir% rd %_tempDir% /s /q
md %_tempDir%
Ricerca immagini iso
Viene effettuata una scansione della cartella \Iso. Se non è presente alcun file lo script termina:
http://s13.postimg.org/9cnx00clz/image.png
echo Ricerca file ISO
echo.
call :Iso.ScanDir
if !_foundIso! equ 0 (
cls
echo Nessun file trovato
echo.
echo Copiare un'immagine ISO nella seguente cartella e riavviare il programma:
echo.
echo %_isoDir%
echo.
goto End
)
...
:Iso.ScanDir
dir /b %_isoDir%\*.iso>%_isoDirList%
set /a _foundIso=0
for /f %%G in (%_isoDirList%) do set /a _foundIso+=1
goto :eof
Nel caso in cui vengano trovati uno o più file viene richiesto di selezionare la ISO da aggiornare:
http://s13.postimg.org/dpmgiflcn/image.png
echo !_foundIso! file trovati
echo.
echo Selezionare un file:
echo.
call :Iso.Select
cls
echo File: !_isoFile!
echo.
...
:Iso.Select
set _outputFile=%_tempDir%\SelectIso.cmd
echo @echo off>%_outputFile%
echo :_choice>>%_outputFile%
set /a _counter=0
for /f %%G in (%_isoDirList%) do (
set /a _counter+=1
echo echo !_counter!. %%G>>%_outputFile%
echo echo.>>%_outputFile%
)
set /a _counter=0
echo set /p _choice=SELEZIONE: >>%_outputFile%
for /f %%G in (%_isoDirList%) do (
set /a _counter+=1
echo if [%%_choice%%]==[!_counter!] set _isoFile=%%G>>%_outputFile%
)
echo if not defined _isoFile echo.^& echo SELEZIONE NON VALIDA^&echo. ^&goto _choice>>%_outputFile%
echo echo.>>%_outputFile%
call %_outputFile%
del %_outputFile% /q
set _outputFile=
goto :eof
Estrazione dei file ei.cfg e idwbinfo.txt
Questi due file servono nel prossimo step per rilevare il sistema operativo e l'edizione:
call :ISO.ExtractFiles
...
:ISO.ExtractFiles
start /wait /min %_binDir%\7Z.exe e %_isoDir%\!_isoFile! sources\ei.cfg sources\idwbinfo.txt -o%_tempDir% -y
goto :eof
Rilevamento del sistema operativo e dell'architetture (x86 o x64)
Lo script legge il file idwbinfo.txt per rilevare il sistema operativo. Prima di fare ciò è necessario accertarsi che tal file esista:
if not exist %_tempDir%\idwbinfo.txt (
echo Impossibile rilevare il sistema operativo. Il programma verra' terminato
echo.
goto End
)
http://s13.postimg.org/s7jnqfcnr/06a.png
Se il file è nel posto giusto:
http://s13.postimg.org/e7m7c10bb/06b.png
call :OS.DetectName
call :OS.DetectArch
...
:OS.DetectName
for /f "tokens=1 delims=," %%G in (%_osIndex%) do (
find /i "%%G" %_tempDir%\idwbinfo.txt >nul && set _osName=%%G
)
goto :eof
:OS.DetectArch
for /f "tokens=2 delims=," %%G in (%_osIndex%) do (
find /i "%%G" %_tempDir%\idwbinfo.txt >nul && set _osArch=%%G
)
goto :eof
Lettura file di configurazione
Per ogni sistema operativo c'è un file di configurazione (spiegherò i file di configurazione nel post successivo) nella cartella \Config
Ora che sono stati rilevati sistema operativo ed architettura lo script sa quale file di configurazione andare a leggere (il nome del file è composto da due parti: NomeOS_Architettura.ini, ad esempio Win7sp1amd64.ini). Le variabili necessarie sono state impostate nello step precedente (ad es: _osName=Win7sp1 e _osArch=amd64).
call :ConfigFile.Read
...
:ConfigFile.Read
set _configFile=%_configDir%\!_osName!!_osArch!.ini
for /f "delims=" %%G in (%_configFile%) do (
set _line=%%G
set _lineFirstChar=!_line:~0,1!
if "!_lineFirstChar!" == "[" (
set _currentArea=!_line:~1,-1!
set _outputFile=%_tempDir%\!_currentArea!.txt
type nul >!_outputFile!
) else (
echo !_line!>>!_outputFile!
)
)
goto :eof
Rilevamento (o selezione manuale) dell'edizione
Per rilevare l'edizione lo script legge il file ei.cfg. Tuttavia ho notato che nelle ISO di Windows 8 questo file non è presente. Lo script verifica prima se il file ei.cfg esiste nella cartella temporanea. In caso contrario chiede di selezionare manualmente l'edizione:
http://s13.postimg.org/4ociikct3/image.png
if exist %_tempDir%\ei.cfg (
call :OS.DetectEdition
echo Sistema Operativo: !_osDescription! !_osExtendedEdition!
echo.
) else (
echo Sistema Operativo: !_osDescription!
echo.
echo E' necessario selezionare manualmente l'edizione:
echo.
call :OS.SelectEdition
cls
echo File selezionato: !_isoFile!
echo.
echo Sistema Operativo: !_osDescription! !_osExtendedEdition!
echo.
)
...
:OS.DetectEdition
for /f "tokens=1-3 delims=," %%G in (%_editionsIndex%) do (
find /i "%%H" %_tempDir%\ei.cfg >nul && set _wimIndex=%%G&& set _osEdition=%%H&& set _osExtendedEdition=%%I
)
goto :eof
...
:OS.SelectEdition
set _outputFile=%_tempDir%\SelectOsEdition.cmd
echo @echo off>%_outputFile%
echo :_choice>>%_outputFile%
set /a _counter=0
for /f "tokens=1-3 delims=," %%G in (%_editionsIndex%) do (
set /a _counter+=1
echo echo !_counter!. %%I>>%_outputFile%
echo echo.>>%_outputFile%
)
set /a _counter=0
echo set /p _choice=Selezione: >>%_outputFile%
for /f "tokens=1-3 delims=," %%G in (%_editionsIndex%) do (
set /a _counter+=1
echo if [%%_choice%%]==[!_counter!] set _wimIndex=%%G^& set _osEdition=%%H^& set _osExtendedEdition=%%I>>%_outputFile%
)
echo if not defined _wimIndex echo.^& echo Selezione non valida^& echo. ^&goto _choice>>%_outputFile%
call %_outputFile%
del %_outputFile% /q
set _outputFile=
goto :eof
Interner Explorer
In Windows 8 è possibile utilizzare solo Internet Explorer 10. In Windows 7 invece ci sono Internet Explorer 8, 9 e 10.
Come prima cosa lo script rileva la versione di default, leggendo la prima riga di un file (IexploreIndex.txt) creato nella cartella temporanea leggendo il file di configurazione:
call :IE.DetectDefault
set _selectedIE=%_defaultIE%
...
:IE.DetectDefault
for /f "tokens=1 delims=," %%G in ('type %_iexploreIndex%') do (
set _defaultIE=%%G
exit /b
)
goto :eof
Dopo di che conta le righe del file e determina se ci sono più versioni di Internet Explorer supportate:
call :IE.CountVersions
...
:IE.CountVersions
set /a _ieCounter=0
for /f %%G in (%_iexploreIndex%) do set /a _ieCounter+=1
goto :eof
In quest'ultimo caso, chiede di selezionare la versione:
http://s24.postimg.org/y3s6z0rc5/image.png
if %_ieCounter% gtr 1 (
echo Selezionare la versione di Internet Explorer:
echo.
call :IE.Select
)
echo %_selectedIE%>>%_integrateList%
...
:IE.Select
set _outputFile=%_tempDir%\SelectIE.cmd
echo @echo off>%_outputFile%
echo :_choice>>%_outputFile%
set /a _counter=0
for /f "tokens=1,2 delims=," %%G in (%_iexploreIndex%) do (
set /a _counter+=1
echo echo !_counter!. %%H>>%_outputFile%
echo echo.>>%_outputFile%
)
echo set /p _choice=Selezione: >>%_outputFile%
set /a _counter=0
for /f "tokens=1,2 delims=," %%G in (%_iexploreIndex%) do (
set /a _counter+=1
echo if [%%_choice%%]==[!_counter!] set _selectedIE=%%G>>%_outputFile%
)
echo if not defined _selectedIE echo.^& echo Selezione non valida^&echo. ^&goto _choice>>%_outputFile%
echo echo.>>%_outputFile%
call %_outputFile%
del %_outputFile% /q
set _outputFile=
goto :eof
Scansione cartella Updates
In base alle informazioni fornite fino ad ora lo script costruisce un indice da confrontare con i file presenti nella cartella \Updates. Gli aggiornamenti non trovati vengono inclusi in una lista di file da scaricare:
echo Ricerca aggiornamenti
echo.
call :Updates.BuildIndex
call :Updates.ScanDir
...
:Updates.BuildIndex
set _tempFile=%_integrateIndex%.tmp
for /f "tokens=1-4 delims=," %%G in (%_integrateIndex%) do find "%%H" %_integrateList% >nul && echo %%G,%%H,%%I,%%J>>%_tempFile%
move %_tempFile% %_integrateIndex% >nul
set _tempFile=
goto :eof
...
:Updates.ScanDir
type nul >%_downloadIndex%
dir /b %_updatesDir%>%_updatesDirList%
set /a _totalUpdates=0
for /f %%G in (%_integrateIndex%) do set /a _totalUpdates+=1
for /f %%G in (%_setupcompleteIndex%) do set /a _totalUpdates+=1
if not [!_defaultIE!]==[!_selectedIE!] set /a _totalUpdates+=1
set /a _foundUpdates=0
set /a _notFoundUpdates=0
for /f "tokens=1-4 delims=," %%G in (%_integrateIndex%) do find /i "%%G" %_updatesDirList% >nul && (set /a _foundUpdates+=1) || (set /a _notFoundUpdates+=1 && echo %%G,%%J>>%_downloadIndex%)
for /f "tokens=1-4 delims=," %%G in (%_setupcompleteIndex%) do find /i "%%G" %_updatesDirList% >nul && (set /a _foundUpdates+=1) || (set /a _notFoundUpdates+=1 && echo %%G,%%J>>%_downloadIndex%)
if not [!_defaultIE!]==[!_selectedIE!] (
for /f "tokens=1-2 delims==" %%G in (%_tempDir%\%_selectedIE%.txt) do (set %%G=%%H)
if not exist %_updatesDir%\!_archiveName! (
set /a _notFoundUpdates+=1 && echo !_archiveName!,!_downloadURL!>>%_downloadIndex%
) else (
set /a _foundUpdates+=1
)
)
goto :eof
Download aggiornamenti mancanti
Nel caso in cui uno o più aggiornamenti non siano stati trovati nella cartella \Updates viene chiesto di effettuare il download (mediante curl.exe, presente nella cartella \Bin):
http://s13.postimg.org/5ny80j2l3/15a.png
echo %_totalUpdates% aggiornamenti totali
echo %_foundUpdates% aggiornamenti scaricati
echo %_notFoundUpdates% aggiornamenti da scaricare
echo.
if %_notFoundUpdates% gtr 0 (
echo E' necessario eseguire il download di %_notFoundUpdates% file prima di proseguire
echo.
choice /c SN /m "Eseguire il download ora?"
if errorlevel 2 goto End
if errorlevel 1 call :Updates.Download
echo.
)
...
:Updates.Download
for /f "tokens=1-2 delims=," %%G in (%_downloadIndex%) do (
echo.
echo Download di %%G in corso
echo.
%_binDir%\curl.exe -L -o %_updatesDir%\%%G "%%H" --progress-bar
)
goto :eof
Copia degli aggiornamenti
I file necessari vengono copiati nella cartella temporanea (gli aggiornamenti non integrabili saranno installati automaticamente al primo accesso):
echo Preparo gli aggiornamenti per l'integrazione
echo.
call :Updates.Copy
...
:Updates.Copy
for /f "tokens=1-3 delims=," %%G in (%_integrateIndex%) do xcopy /i %_updatesDir%\%%G %_integrateDir%\%%H\%%I\ >nul
md %_extractDir%\sources\$OEM$\$$\Setup\Scripts
echo @echo off>%_extractDir%\sources\$OEM$\$$\Setup\Scripts\SetupComplete.cmd
for /f "tokens=1-5 delims=," %%G in (%_setupcompleteIndex%) do (
xcopy /i %_updatesDir%\%%G %_setupcompleteDir%\%%H\ >nul
echo start /wait %%SYSTEMDRIVE%%\SETUPCOMPLETE\%%H\%%G %%K>>%_extractDir%\sources\$OEM$\$$\Setup\Scripts\SetupComplete.cmd
)
echo rd %%SYSTEMDRIVE%%\SETUPCOMPLETE /s /q>>%_extractDir%\sources\$OEM$\$$\Setup\Scripts\SetupComplete.cmd
goto :eof
Se la versione di Internet Explorer selezionata non è quella di default, è necessario scompattare l'archivio:
if not [!_defaultIE!]==[!_selectedIE!] call :IE.Extract
...
:IE.Extract
start /wait /min %_updatesDir%\!_archiveName! !_extractSwitch!%_tempDir%
for %%G in (!_integrateFiles!) do xcopy /i %_tempDir%\%%G %_integrateDir%\%_selectedIE%\SETUP\ >nul
goto :eof
Estrazione immagine ISO
A questo punto il file ISO viene scompattato nella cartella temporanea:
echo Estrazione immagine ISO
echo.
call :ISO.Extract
...
:ISO.Extract
start /wait /min %_binDir%\7Z.exe x %_isoDir%\!_isoFile! -o%_extractDir% -y
goto :eof
Montaggio file install.wim
http://s13.postimg.org/piov0e76f/image.png
echo Montaggio file WIM
echo.
call :Wim.Mount
...
:Wim.Mount
md %_mountDir%
set _logFile=%_tempDir%\MountWim.log
dism /mount-wim /wimfile:%_wimFile% /index:!_wimIndex! /mountdir:%_mountDir% /LogPath:%_logFile% /LogLevel:1
goto :eof
Integrazione aggiornamenti
http://s13.postimg.org/eqralarpz/20a.png
echo Integrazione aggiornamenti
echo.
call :Wim.Integrate
...
:Wim.Integrate
set _logFile=%_tempDir%\IntegrateWim.log
for /f %%G in (%_integrateList%) do (
if exist %_integrateDir%\%%G\SETUP dism /image:%_mountDir% /add-package /packagepath:%_integrateDir%\%%G\SETUP /LogPath:%_logFile% /LogLevel:1
if exist %_integrateDir%\%%G\IMPORTANT dism /image:%_mountDir% /add-package /packagepath:%_integrateDir%\%%G\IMPORTANT /LogPath:%_logFile% /LogLevel:1
if exist %_integrateDir%\%%G\RECOMMENDED dism /image:%_mountDir% /add-package /packagepath:%_integrateDir%\%%G\RECOMMENDED /LogPath:%_logFile% /LogLevel:1
if exist %_integrateDir%\%%G\OPTIONAL dism /image:%_mountDir% /add-package /packagepath:%_integrateDir%\%%G\OPTIONAL /LogPath:%_logFile% /LogLevel:1
)
goto :eof
Salvataggio del file install.wim
http://s13.postimg.org/cngvdmrx3/image.png
echo Salvataggio file WIM
echo.
call :Wim.Unmount
...
:Wim.Unmount
set _logFile=%_tempDir%\UnMountWim.log
dism /unmount-wim /mountdir:%_mountDir% /commit /LogPath:%_logFile% /LogLevel:1
if exist %_mountDir% rd %_mountDir% /s /q
goto :eof
Creazione ISO aggiornata
La ISO aggiornata si troverà nella cartella \Output alla fine del processo
echo Creazione file ISO
echo.
call :Iso.Build
...
:Iso.Build
start /wait /min %_binDir%\oscdimg.exe -h -u2 -m -b%_extractDir%\boot\etfsboot.com -l!_osName!!_osArch! %_extractDir% %_outputDir%\!_osName!_!_osArch!_!_osEdition!_!_selectedIE!.iso
goto :eof
FINE!
Alla fine dello script la cartella temporanea viene cancellate e le variabili sono annullate.
echo Operazione completata
echo.
goto End
...
:End
echo.
echo Premere un tasto per uscire
pause >nul
if exist %_tempDir% rd %_tempDir% /s /q
for /f "tokens=1 delims==" %%G in ('set _') do (set %%G=)
exit
CONSIGLI
Il montaggio/smontaggio dei file .wim ruchiede un sacco di tempo, per non parlare dell'integrazione degli aggiornamenti. Ho notato che con l'antivirus abilitato (NOD32 6.0) queste fasi sono estremamente lente. Disabilitate l'antivirus e, se possibile, lanciate lo script da un SSD.
Per determinare quali aggiornamenti andavano integrati ho creato una virtual machine per ogni SO ed ho lanciato Windows Update. Il codice non gestisce aggiornamenti opzionali come DotNet o Silverlight. Se volete integrare altro software basta andare a modificare la sezione [SetupCompleteIndex] aggiungendo, nell'ordine esatto, i file da installare al primo accesso. I delimitatori di campo sono le virgole, ed i campi sono i seguenti:
Nome File
Prodotto
Livello di gravità (Importante, Consigliato, Facoltativo)
URL per il download del file
Switch per l'installazione silenziosa
[SetupCompleteIndex]
; Aggiornamento per Windows 7 per sistemi x64 (KB2533552)
Windows6.1-KB2533552-x64.msu,WIN,IMPORTANT,http://download.microsoft.com/download/B/6/F/B6F95B10-8B74-42F2-B57A-2C559D43BC28/Windows6.1-KB2533552-x64.msu,/quiet /notesrtart
; Strumento di rimozione malware di Windows – maggio 2013 (KB890830)
Windows-KB890830-V4.20-x64.exe,MRT,IMPORTANT,http://download.microsoft.com/download/2/C/5/2C563B99-54D9-4D85-A82B-45D3CD2F53CE/Windows-KB890830-x64-V4.20.exe,/q
; Definition Update for Windows Defender - KB915597
mpas-fe-x64.exe,MPAS,IMPORTANT,http://go.microsoft.com/fwlink/?LinkID=121721&arch=x64&prod=925A3ACA-C353-458A-AC8D-A7E5EB378092,/q
Nell'ultima riga ci sono le definizioni di Windows Defender. Sono lì solo a scopo accademico: vengono aggiornate di frequente e quindi è impossibile avere l'ultima versione. Se non usate Windows Defender commentate o cancellate la riga