Loop through folder of multiple wim's

Discussion in 'Windows 8' started by hypedave, Nov 11, 2014.

  1. s1ave77

    s1ave77 Has left at his own request

    Aug 15, 2012
    16,104
    24,378
    340
    #21 s1ave77, Nov 14, 2014
    Last edited by a moderator: Apr 20, 2017
    Possible Way:

    #1. Export all Single WIM Files to Master:

    Code:
    for /r "C:\images" %%a in (*.wim) do Dism /Export-Image /SourceImageFile:%%a /SourceIndex:1 /DestinationImageFile:C:\master\install.wim /compress:max /CheckIntegrity
    #2. Copy Master from C:\master to c:\images:
    Code:
    xcopy "C:\master\install.wim" /s /q "C:\images\" /Y
    #3. Mount index by index, add updates and unmount/commit:

    Loop queries the WIM and for each found index performs mount, adds updates and unmounts/commits, then the next and so on.

    Code:
    for /f "tokens=2 delims=: " %%a in ('dism /english /Get-WimInfo /WimFile:"C:\images\install.wim" ^| findstr /i Index') do (
    DISM /mount-wim /wimfile:C:\images\install.wim /index:%%a /mountdir:C:\images\mount
    DISM /image:C:\images\mount /Add-Package /PackagePath:C:\images\wsusoffline\client\w63-x64\glb
    DISM /unmount-wim /mountdir:C:\images\mount /commit
    )
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  2. hypedave

    hypedave MDL Member

    Oct 14, 2014
    129
    30
    10
    Okay i'll try to run the final script from a WinPE session. Yes I would like backup the individual master wims before they are mounted and then updates injected. here is my folder structure


    Step #1 Merge *.wim to backup wim in c:\images\backup
    Step #2 Mount *.wim to c:\images\mount
    Step #3 Inject updates from c:\wsusoffline\client\w63-x64\glb folder path
    Step #4 unmount image commit changes
    Step #5 Loop back to WIM's 2 - XX until completed
    Step #6 Merge WIM's to new created master WIM in c:\master\install.wim

    I think that's all the of the process flow. If you have any better recommendation feel free.
     
  3. s1ave77

    s1ave77 Has left at his own request

    Aug 15, 2012
    16,104
    24,378
    340
    #23 s1ave77, Nov 14, 2014
    Last edited by a moderator: Apr 20, 2017
    That script should run within your system not on Win PE :D. Instead of Windows Setup i use DISM to apply WIM/ESD/SWM files directly from PE (Setup is very picky with SWMs).

    Better have the single WIMs in a sub-folder like c:\images\wim to avoid irritations in loop

    Code:
    @echo off
    :: get admin rights
    (NET FILE||(powershell -command Start-Process '%0' -Verb runAs -ArgumentList '%* '&EXIT /B))>NUL 2>&1
    setLocal EnableDelayedExpansion
    
    :: start procedure
    :: backup all WIMs to c:\images\backup\install.wim
    set "p=0"
    for /r "c:\images\wim" %%a in (*.wim) do set /a p+=1
    if /i "%p%"=="0" echo NO WIMs FOUND.&&pause&&exit
    for /r "c:\images\wim" %%a in (*.wim) do Dism /Export-Image /SourceImageFile:%%a /SourceIndex:1 /DestinationImageFile:C:\images\backup\install.wim /compress:max /CheckIntegrity
    
    :: mount single WIMs to c:\images\mount, add updates and unmount/commit
    for /r "C:\images\wim" %%a in (*.wim) do (
    DISM /mount-wim /wimfile:%%a /index:1 /mountdir:C:\images\mount
    DISM /image:C:\images\mount /Add-Package /PackagePath:C:\images\wsusoffline\client\w63-x64\glb
    DISM /unmount-wim /mountdir:C:\images\mount /commit
    )
    
    :: merge single WIMs to c:\images\master\install.wim
    for /r "c:\images\wim" %%a in (*.wim) do Dism /Export-Image /SourceImageFile:%%a /SourceIndex:1 /DestinationImageFile:C:\images\master\install.wim /compress:max /CheckIntegrity
    
    :: split master WIM
    Dism /Split-Image /ImageFile:C:\images\master\install.wim /SWMFile:C:\images\sources\install.swm /FileSize:256
    
    :: end procedure
    :: script will pause here
    pause
    
    :: EXIT
    endlocal
    exit
    
    

    With eye candy :cool2::
    Code:
    @echo off
    :: get admin rights
    (NET FILE||(powershell -command Start-Process '%0' -Verb runAs -ArgumentList '%* '&EXIT /B))>NUL 2>&1
    setLocal EnableDelayedExpansion
    
    :: start procedure
    :: backup all WIMs to c:\images\backup\install.wim
    echo.
    echo ===============================================================================
    echo Backing up to c:\images\backup
    echo ===============================================================================
    echo.
    set "p=0"
    for /r "c:\images\wim" %%a in (*.wim) do set /a p+=1
    if /i "%p%"=="0" echo NO WIMs FOUND.&&pause&&exit
    for /r "c:\images\wim" %%a in (*.wim) do (
    echo Exporting %%a to c:\backup\install.wim
    echo.
    Dism /Export-Image /SourceImageFile:%%a /SourceIndex:1 /DestinationImageFile:C:\images\backup\install.wim /compress:max /CheckIntegrity
    )
    
    :: mount single WIMs to c:\images\mount, add updates and unmount/commit
    echo.
    echo ===============================================================================
    echo Mounting to c:\images\mount
    echo Adding Updates
    echo Unmount/Commit
    echo ===============================================================================
    echo.
    for /r "C:\images\wim" %%a in (*.wim) do (
    echo Processing %%a
    echo.
    DISM /mount-wim /wimfile:%%a /index:1 /mountdir:C:\images\mount
    DISM /image:C:\images\mount /Add-Package /PackagePath:C:\images\wsusoffline\client\w63-x64\glb
    DISM /unmount-wim /mountdir:C:\images\mount /commit
    )
    
    :: merge single WIMs to c:\images\master\install.wim
    echo.
    echo ===============================================================================
    echo Exporting to c:\images\master
    echo ===============================================================================
    echo.
    for /r "c:\images\wim" %%a in (*.wim) do (
    echo Exporting %%a to c:\master\install.wim
    echo.
    Dism /Export-Image /SourceImageFile:%%a /SourceIndex:1 /DestinationImageFile:C:\images\master\install.wim /compress:max /CheckIntegrity
    )
    
    :: split master WIM
    echo.
    echo ===============================================================================
    echo Splitting WIM to c:\images\sources
    echo ===============================================================================
    echo.
    Dism /Split-Image /ImageFile:C:\images\master\install.wim /SWMFile:C:\images\sources\install.swm /FileSize:256
    
    :: end procedure
    :: script will pause here
    echo.
    echo ===============================================================================
    echo DONE ...
    echo ===============================================================================
    echo.
    pause
    
    :: EXIT
    endlocal
    exit
    
    
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  4. hypedave

    hypedave MDL Member

    Oct 14, 2014
    129
    30
    10
    You da man, worked like a charm.
     
  5. s1ave77

    s1ave77 Has left at his own request

    Aug 15, 2012
    16,104
    24,378
    340
    You're welcome :D. Thanks for feedback :good3:.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  6. hypedave

    hypedave MDL Member

    Oct 14, 2014
    129
    30
    10
    #26 hypedave, Nov 14, 2014
    Last edited by a moderator: Apr 20, 2017
    (OP)
    During the backup wim process, how do I append the current date and time to the wim file

    Code:
    
    :: start procedure
    :: backup all WIMs to c:\images\backup\install.wim
    set "p=0"
    for /r "c:\images\wim" %%a in (*.wim) do set /a p+=1
    if /i "%p%"=="0" echo NO WIMs FOUND.&&pause&&exit
    for /r "c:\images\wim" %%a in (*.wim) do Dism /Export-Image /SourceImageFile:%%a /SourceIndex:1 /DestinationImageFile:C:\images\backup\install.wim /compress:max /CheckIntegrity
    
    
    
    Would something like this work

    Code:
    
    @echo TIMESTAMP=%TIMESTAMP%
    
    :: start procedure
    :: backup all WIMs to c:\images\backup\install.wim
    set "p=0"
    for /r "c:\images\wim" %%a in (*.wim) do set /a p+=1
    if /i "%p%"=="0" echo NO WIMs FOUND.&&pause&&exit
    for /r "c:\images\wim" %%a in (*.wim) do Dism /Export-Image /SourceImageFile:%%a /SourceIndex:1 /DestinationImageFile:C:\images\backup\install_%TIMESTAMP%.wim /compress:max /CheckIntegrity
    
    
     
  7. s1ave77

    s1ave77 Has left at his own request

    Aug 15, 2012
    16,104
    24,378
    340
    #27 s1ave77, Nov 14, 2014
    Last edited by a moderator: Apr 20, 2017
    What info should be shown as timestamp.

    Unfortunately time and date output is different for each location. But it works to use system-time :cool2::

    Code:
    @echo off
    :: get admin rights
    (NET FILE||(powershell -command Start-Process '%0' -Verb runAs -ArgumentList '%* '&EXIT /B))>NUL 2>&1
    setLocal EnableDelayedExpansion
    
    :: get timestamp data: will show month.day.year.hour.min.sec
    set "X="
    for /f "skip=1 delims=" %%x in ('wmic os get localdatetime') do if not defined X set X=%%x
    set D.YEAR=%X:~0,4%
    set D.MONTH=%X:~4,2%
    set D.DAY=%X:~6,2%
    set D.HOUR=%X:~8,2%
    set D.MINUTE=%X:~10,2%
    set D.SECOND=%X:~12,2%
    set D.FRACTIONS=%X:~15,6%
    set D.OFFSET=%X:~21,4%
    set timestamp=%D.MONTH%.%D.DAY%.%D.YEAR%.%D.HOUR%.%D.MINUTE%.%D.SECOND%
    
    :: start procedure
    :: backup all WIMs to c:\images\backup\install.wim
    set "p=0"
    for /r "c:\images\wim" %%a in (*.wim) do set /a p+=1
    if /i "%p%"=="0" echo NO WIMs FOUND.&&pause&&exit
    for /r "c:\images\wim" %%a in (*.wim) do Dism /Export-Image /SourceImageFile:%%a /SourceIndex:1 /DestinationImageFile:C:\images\backup\install_%timestamp%.wim /compress:max /CheckIntegrity
    
    :: mount single WIMs to c:\images\mount, add updates and unmount/commit
    for /r "C:\images\wim" %%a in (*.wim) do (
    DISM /mount-wim /wimfile:%%a /index:1 /mountdir:C:\images\mount
    DISM /image:C:\images\mount /Add-Package /PackagePath:C:\images\wsusoffline\client\w63-x64\glb
    DISM /unmount-wim /mountdir:C:\images\mount /commit
    )
    
    :: merge single WIMs to c:\images\master\install.wim
    for /r "c:\images\wim" %%a in (*.wim) do Dism /Export-Image /SourceImageFile:%%a /SourceIndex:1 /DestinationImageFile:C:\images\master\install_%timestamp%.wim /compress:max /CheckIntegrity
    
    :: split master WIM
    Dism /Split-Image /ImageFile:C:\images\master\install.wim /SWMFile:C:\images\sources\install.swm /FileSize:256
    
    :: end procedure
    :: script will pause here
    pause
    
    :: EXIT
    endlocal
    exit
    
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  8. hypedave

    hypedave MDL Member

    Oct 14, 2014
    129
    30
    10
    #28 hypedave, Nov 14, 2014
    Last edited by a moderator: Apr 20, 2017
    (OP)
    Current Date and time the backup wim was created

    c:\images\backup\install_11-14-2014_5:05PM.wim

    I use that same TIMESTAMP=%TIMESTAMP% when creating folders with current date and time folder was created.

    Code:
    
    :: Use date /t and time /t from command line to get format of your date and
    :: time; change substring below as needed.
    
    :: This will create a timestamp like yyyy-mm-yy-hh-mm-ss.
    set TIMESTAMP=%DATE:~10,4%-%DATE:~4,2%-%DATE:~7,2%-%TIME:~0,2%-%TIME:~3,2%-%TIME:~6,2%
    
    @echo TIMESTAMP=%TIMESTAMP%
    
    :: Create new directory
    md "%1\projects\images\customer_%TIMESTAMP%"
    
    
    Folder ends up like this "customer_2014-10-22-15-02-53"
     
  9. s1ave77

    s1ave77 Has left at his own request

    Aug 15, 2012
    16,104
    24,378
    340
    #29 s1ave77, Nov 14, 2014
    Last edited by a moderator: Apr 20, 2017
    Ahh ... OK, see edit in previous post for localization proof timestamp.




    ===============================
    EDIT:

    To meet your form:

    Code:
    :: get timestamp data: will show month.day.year.hour.min.sec
    for /f "skip=1 delims=" %%x in ('wmic os get localdatetime') do if not defined X set X=%%x
    set D.YEAR=%X:~0,4%
    set D.MONTH=%X:~4,2%
    set D.DAY=%X:~6,2%
    set D.HOUR=%X:~8,2%
    set D.MINUTE=%X:~10,2%
    set D.SECOND=%X:~12,2%
    set D.FRACTIONS=%X:~15,6%
    set D.OFFSET=%X:~21,4%
    set timestamp=%D.YEAR%-%D.MONTH%-%D.DAY%-%D.HOUR%-%D.MINUTE%-%D.SECOND%
    
    timestamp would look:
    Code:
    2014-11-15-00-22-37
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  10. hypedave

    hypedave MDL Member

    Oct 14, 2014
    129
    30
    10
    Thanks, i'll give this a dry run and let you know how it goes.
     
  11. hypedave

    hypedave MDL Member

    Oct 14, 2014
    129
    30
    10
    #31 hypedave, Nov 15, 2014
    Last edited by a moderator: Apr 20, 2017
    (OP)
    Ok so I changed things up just a tad to clean up the directory structures, I renamed my Windows Update folder and placed individual subdirectories inside.

    Old Code
    Code:
    DISM /image:C:\images\mount /Add-Package /PackagePath:C:\images\wsusoffline\client\w63-x64\glb
    New Code
    Code:
    DISM /image:f:\mount /Add-Package /PackagePath:C:\images\windowsupdates
    Folder structure for "c:\images\windowsupdates" looks like this

    Code:
    C:\images\windowsupdates\
    C:\images\windowsupdates\Additional
    C:\images\windowsupdates\Baseline
    C:\images\windowsupdates\Extra
    C:\images\windowsupdates\General
    C:\images\windowsupdates\Hotfix
    C:\images\windowsupdates\Security
    
    Right now I have to move the updates to the top level folder.
     
  12. hypedave

    hypedave MDL Member

    Oct 14, 2014
    129
    30
    10
    #32 hypedave, Nov 15, 2014
    Last edited by a moderator: Apr 20, 2017
    (OP)
    Ok I think I may have figured this one out by using the set command

    Code:
    :: mount single WIMs to f:\mount, add updates and unmount/commit
    :Path to update packages
    set updates1=C:\images\windowsupdates\Additional
    set updates2=C:\images\windowsupdates\Baseline
    set updates3=C:\images\windowsupdates\Extra
    set updates4=C:\images\windowsupdates\General
    set updates5=C:\images\windowsupdates\Hotfix
    set updates6=C:\images\windowsupdates\Security
    for /r "f:\wim" %%a in (*.wim) do (
    DISM /mount-wim /wimfile:%%a /index:1 /mountdir:f:\mount
    DISM /image:C:\images\mount /Add-Package /PackagePath:%updates1%
    DISM /image:C:\images\mount /Add-Package /PackagePath:%updates2%
    DISM /image:C:\images\mount /Add-Package /PackagePath:%updates3%
    DISM /image:C:\images\mount /Add-Package /PackagePath:%updates4%
    DISM /image:C:\images\mount /Add-Package /PackagePath:%updates5%
    DISM /image:C:\images\mount /Add-Package /PackagePath:%updates6%
    DISM /unmount-wim /mountdir:f:\mount /commit
    )
    
     
  13. s1ave77

    s1ave77 Has left at his own request

    Aug 15, 2012
    16,104
    24,378
    340
    #33 s1ave77, Nov 15, 2014
    Last edited by a moderator: Apr 20, 2017
    Yep, looks good :good3:.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  14. hypedave

    hypedave MDL Member

    Oct 14, 2014
    129
    30
    10
    #34 hypedave, Nov 15, 2014
    Last edited by a moderator: Apr 20, 2017
    (OP)
    Here is my next challenge I present myself with. I need to copy additional files to the wim when it's mounted.

    Code:
    set path1=f:\c:\images\files
    set target=c:\images\mount
    DISM /mount-wim /wimfile:%%a /index:1 /mountdir:c:\images\mount
    xcopy.exe %path1%\*.* %target%\*.* /s /d /e /h /r /k /y
    
    Also I other issue is that when backing up the original wim file

    Code:
    :: get timestamp data: will show month.day.year.hour.min.sec
    set "X="
    for /f "skip=1 delims=" %%x in ('wmic os get localdatetime') do if not defined X set X=%%x
    set D.YEAR=%X:~0,4%
    set D.MONTH=%X:~4,2%
    set D.DAY=%X:~6,2%
    set D.HOUR=%X:~8,2%
    set D.MINUTE=%X:~10,2%
    set D.SECOND=%X:~12,2%
    set D.FRACTIONS=%X:~15,6%
    set D.OFFSET=%X:~21,4%
    REM set timestamp=%D.MONTH%.%D.DAY%.%D.YEAR%.%D.HOUR%.%D.MINUTE%.%D.SECOND%
    set timestamp=%D.MONTH%.%D.DAY%.%D.YEAR%.%D.HOUR%.%D.MINUTE%.%D.SECOND%
    :: start procedure
    :: backup all WIMs to f:\backup\install.wim
    set "p=0"
    for /r "f:\wim" %%a in (*.wim) do set /a p+=1
    if /i "%p%"=="0" echo NO WIMs FOUND.&&pause&&exit
    for /r "f:\wim" %%a in (*.wim) do Dism /Export-Image /SourceImageFile:%%a /SourceIndex:1 /DestinationImageFile:f:\backup\install_%timestamp%.wim /compress:max /CheckIntegrity
    
    Orginal WIM File Name
    Customer_XXX-11-01-2014.wim

    backup WIM File name
    Customer_XXX-11-01-20014_BAK_TIMESTAMP.wim
    I need for it to keep the original file name but add the backup date time stamp to the end of the file name.
     
  15. s1ave77

    s1ave77 Has left at his own request

    Aug 15, 2012
    16,104
    24,378
    340
    #35 s1ave77, Nov 15, 2014
    Last edited by a moderator: Apr 20, 2017
    Check the path1 in set :g:. Where those files have to go in the mounted WIM?

    Will think about the naming.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  16. hypedave

    hypedave MDL Member

    Oct 14, 2014
    129
    30
    10
    #36 hypedave, Nov 15, 2014
    Last edited by a moderator: Apr 20, 2017
    (OP)
    Typo on my part

    Code:
    set path1=c:\images\files
    set target=c:\images\mount
    DISM /mount-wim /wimfile:%%a /index:1 /mountdir:c:\images\mount
    xcopy.exe %path1%\*.* %target%\*.* /s /d /e /h /r /k /y
    
    The files will go to folder structure on the mounted wim example

    c:\images\files\windows\hello.txt
    c:\mounted\windows\hello.txt
     
  17. s1ave77

    s1ave77 Has left at his own request

    Aug 15, 2012
    16,104
    24,378
    340
    #37 s1ave77, Nov 15, 2014
    Last edited by a moderator: Apr 20, 2017
    OK. Then files should have the same folder structure like the mounted WIM and they will be copied over to correct place.


    Still don't get the naming theme of the WIM files :g:.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  18. s1ave77

    s1ave77 Has left at his own request

    Aug 15, 2012
    16,104
    24,378
    340
    #38 s1ave77, Nov 15, 2014
    Last edited by a moderator: Apr 20, 2017
    OK, i think i got it, correct me if wrong: you want to be the original name part of the backup name with BAK_%timestamp% added to it.

    BTW: although the long version of timestamp generation is nice for understanding it can be dramatically shortened.

    Code:
    @echo off
    :: get admin rights
    (NET FILE||(powershell -command Start-Process '%0' -Verb runAs -ArgumentList '%* '&EXIT /B))>NUL 2>&1
    setLocal EnableDelayedExpansion
    
    :: get timestamp data: will show MM-DD-YYYY-HH-MN-SS
    for /f "skip=1 delims=" %%x in ('wmic os get localdatetime') do if not defined X set X=%%x
    set timestamp=%X:~4,2%-%X:~6,2%-%X:~0,4%-%X:~8,2%-%X:~10,2%-%X:~12,2%
    
    :: start procedure
    :: checking WIM presence and setting customer string
    set "p=0"
    for /r "c:\images\wim" %%a in (*.wim) do (
    set /a p+=1
    set customer=%%a
    )
    set customer=%customer:~0,-11%
    if /i "%p%"=="0" echo NO WIMs FOUND.&&pause&&exit
    :: backup all WIMs to c:\images\backup\install.wim
    for /r "c:\images\wim" %%a in (*.wim) do Dism /Export-Image /SourceImageFile:%%a /SourceIndex:1 /DestinationImageFile:C:\images\backup\%customer%_BAK_%timestamp%.wim /compress:max /CheckIntegrity
    
    
    :: mount single WIMs to c:\images\mount, add updates, copy files and unmount/commit
    set path1=c:\images\files
    set target=c:\images\mount
    for /r "C:\images\wim" %%a in (*.wim) do (
    DISM /mount-wim /wimfile:%%a /index:1 /mountdir:C:\images\mount
    DISM /image:C:\images\mount /Add-Package /PackagePath:C:\images\wsusoffline\client\w63-x64\glb
    xcopy.exe %path1%\*.* %target%\*.* /s /d /e /h /r /k /y
    DISM /unmount-wim /mountdir:C:\images\mount /commit
    )
    
    :: merge single WIMs to c:\images\master\install.wim
    for /r "c:\images\wim" %%a in (*.wim) do Dism /Export-Image /SourceImageFile:%%a /SourceIndex:1 /DestinationImageFile:C:\images\master\%customer%_%timestamp%.wim /compress:max /CheckIntegrity
    
    :: split master WIM
    Dism /Split-Image /ImageFile:C:\images\master\install.wim /SWMFile:C:\images\sources\install.swm /FileSize:256
    
    :: end procedure
    :: script will pause here
    pause
    
    :: EXIT
    endlocal
    exit
    
    So far i only changed the naming of the backup, but left the master, if needed simply change master naming accordingly.


    ================================
    EDIT: Although idea wasn't that bad, using %%~na will create as much backups as WIMs available :g:. Slightly defeats the purpose.


    Edited above sample.

    File names now would be Customer_XXX_BAK_11-15-2014-22-13-50 (backup) and Customer_XXX_11-15-2014-22-13-50 (master).
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  19. hypedave

    hypedave MDL Member

    Oct 14, 2014
    129
    30
    10
    Yeah I changed the code back to just backing up to one merged wim backup file. Space for this project is critical since im operating off a 500GB Drive.

    Now for the time stamp, would be great to loose the seconds.
     
  20. s1ave77

    s1ave77 Has left at his own request

    Aug 15, 2012
    16,104
    24,378
    340
    #40 s1ave77, Nov 16, 2014
    Last edited by a moderator: Apr 20, 2017
    Timestamp without seconds:
    Code:
    set timestamp=%X:~4,2%-%X:~6,2%-%X:~0,4%-%X:~8,2%-%X:~10,2%
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...