[Batch] Automate .msu and .cab updates

Discussion in 'Scripting' started by wk-952, Jun 27, 2014.

  1. wk-952

    wk-952 MDL Member

    Sep 2, 2012
    115
    281
    10
    #1 wk-952, Jun 27, 2014
    Last edited by a moderator: Apr 20, 2017
    This is a batch script to automate the installation of .msu and .cab updates.

    Features:
    • Installs all .msu and .cab updates from the user defined locations including or not sub-directories.
    • Installs separately specified .msu and .cab updates.

      1) Ability to install updates from multiple directories (separated by a semi-colon ";").
      2) Multiple directories and separate updates can be combined together.
      .

    • Accepts external parameters, so it can be called from another batch script without any user
      interaction (for full automation).
    • Reports the status of the currently installed update (installed successfully, restart needed,...etc.).
    • Ability to generate a log file with a user defined location,
      containing simple information about succeeded and failed updates.

      1) If the log directory doesn't exist, the script will automatically attempt to create it.
      2) No error messages if log creation failed (in a protected directory like C:\Windows) due to lack of admin. permissions.
      .
    • Inside the console UI of the script (not called from outside with parameters) no double quotes are needed
      for paths with spaces.
      (you can still write them if you want but they'll be ignored anyway)
    • Error safety, the script will print error message with beep sound if you tried to:

      1) Use a wrong syntax for paths.
      2) Use a non-existing directory / file.
      3) Use a file that is not a .msu nor .cab.
      .

    Notes / Limitations:
    • The caret character "^" is not allowed to be used, it will be ignored from the input.
    • The installation of .cab files requires: Deployment Image Servicing and Management (DISM) tool,
      and if it's present the script must be run with administrator privileges (otherwise .cab files will be ignored).
    • .cab files installation is slow because the script queries the updates list per .cab file installation to check whether it's installed or not;
      this behavior eliminates the need to use external temporary file containing the updates list (everything is done in the memory).

    Parameters:
    The script can take every required input as a parameter, this is useful in case it should be used without any user interactions (fully automated).
    The number of parameters accepted are '6':


    1. Full path of the updates folder (and additionally the update filename and extension if it's not a directory)
    2. Y or N (include or not sub-directories)

      Y ---> search in sub-directories.
      N ---> do not search in sub-directories.
      .
    3. Y or N (create or not a log file)

      Y ---> create a log file.
      N ---> do not create a log file.
      .
    4. Full path to the log files
      The folder where the log files will be created.
      .
    5. R or X (restart or exit the script after the installation process)

      R ---> restart when finished.
      X ---> exit this script when finished.
      .
    6. runAs
      Attempt to run this script with administrator privileges.
      .
    *** Unused parameters should be left empty by typing an empty pair of double-quotes ***

    Example 1:
    If you don't want to log events, the 4th parameter should be left empty like so:
    Code:
    call "automate_msu_cab_updates.bat" "E:\my updates" "y" "n" "" "x"
    
    Example 2:
    If the target updates are specific ones, then searching in sub-directories (2nd parameter) isn't required:
    Code:
    call "automate_msu_cab_updates.bat" "E:\my updates\update 2.msu" "" "y" "E:\my logs" "x"
    

    Special keywords:
    Those keywords when used as parameters (1st or 4th only), or typed in the console UI of the script
    will have the following effects:


    • "current":
      As a 1st parameter: will make the script search for .msu and .cab updates in the current folder of the script.
      As a 4th parameter: will set the log directory to that of the script.
    • "/?":
      As a 1st or 4th parameter: display a simple help page.
    • "exit":
      As a 1st or 4th parameter: will exit this script,
      this script only so when it's called from another script, the caller script won't be terminated
    • "#admin#":
      As a 1st or 4th parameter: elevate/raise the access level of the script to that of the admin.
      1. needed if the log files should be written to a protected directory.
      2.needed to workaround an issue where the CMD window will sometimes crash if you tried to
      run this script as admin. from a very long location containing spaces and/or the ampersand '&' character.


    • "RunAs": (only to be used as a 6th parameter and not allowed in the console UI)
      run the script with elevated permissions, this is different than the keyword "#admin#"
      since it preserves the first parameter.


    Usage example:
    To install all .msu and .cab updates from the following 3 directories:
    "D:\security updates"
    "E:\hotfix updates"
    "F:\8.1 updates"
    Plus those 2 random separate updates:
    "D:\my Updates\U1.cab"
    "D:\my Updates\U8.msu"
    you should type it like this in the console UI: (no double quotes are needed for paths with spaces)
    Code:
    D:\security updates;E:\hotfix updates;F:\8.1 updates;D:\my Updates\U1.cab;D:\my Updates\U8.msu
    
    If this input is used as a parameter (to be called from a major script) it should be used this way:
    Code:
    call automate_msu_cab_updates.bat "D:\security updates;E:\hotfix updates;F:\8.1 updates;D:\my Updates\U1.cab;D:\my Updates\U8.msu" "y" "n" "" "x"
    
    Considering the above mentioned directories and files are valid.

    Screenshots:
    Console UI
    con_ui_inp.jpg
    Success log
    success_log.jpg
    Failure log
    fail_log.jpg

    Changes / Fixes and known bugs:
    • V4 --- *V4.2 (major update)

    • fixed the long time issue in which the exclamation mark cannot be used by
      the user due to the usage of the 'delayed variable expansion'. FINALLY!
    • fixed the bug in which the percentage mark '%' is removed from the user input.
    • updated parameters acceptance/manipulation order to reflect the above mentioned 2 major fixes.
    • added a function to convert decimal errorlevel to 'HEX' format, to be used when the tool
      ('wusa.exe' or 'dism.exe') is terminated with an unknown exit code.
      Credits to dbenham @DosTips.com
    • added the special keyword "runAs" (only to be used as a sixth parameter) to raise the access level of the script,
      should be used in case this script is called from a non-admin. script and ".cab" updates installation is involved.
    • fixed an infinite loop occurrence, where if the 1st parameter is "#admin#" the script gets stuck in an infinite loop.
    • prevented searching for ".cab" files if admin. privileges are not detected, even if 'DISM.exe' is found.
    • added another error message for "pending update" status, since 'dism.exe' attempts to install the same update
      again despite its pending status, this is completely different than "/PreventPending" switch.
    • 'wusa.exe' and 'dism.exe' locations are now stored as variables, so they can be changed later on by the user.
    • *fixed dirs footer writer; when multiple ".msu" files (with success and failure states) are installed then one ".cab"
      file is installed, the success and failure log counters were reset, so one log file don't get a footer.

    • Bug in log files: if the update directory/name contains any exclamation marks, they won't be displayed in the 'Directories' section of the log files.
    old:
    • V3.6 --- *V3.6.1

    • added a custom parsing function to change the word "current" to the actual current directory
      at every occurrence of the word, this allows the word to be used in the middle (or any place)
      of the user inputs (example input: D:\update 1.msu;current;D:\update 2.cab).
    • prevented searching for ".msu" or ".cab" files if the corresponding tool ('wusa.exe' / 'dism.exe') is not
      found, to decrease processing (searching) time.
    • the 2 'setLocal' shells are now merged into one as the 'delayed variable expansion' will not be
      disabled under any circumstances.
    • removed the extra space that was being added if the hours counter was only one digit (before 10 AM).
    • fixed the dirs/files header writer in the console UI;
      it won't be shown if non of the tools ('wusa.exe' / 'dism.exe') are found,
      or one of them found but no corresponding files (".msu" / ".cab") are found.
    • changed the prompt and the log directory view (for more space with long paths).
    • removed the 'color' statement at the end since it's useless;
      it restores the console color only if it's used from a CMD window.
    • *suppressed an error message not meant to be displayed (was used in debugging).
    • compacted small part of the code.

    • V3.5.2

    • fixed windows build check (was set to prevent Windows 7 pre SP1).
    • fixed wrong code (was used in debugging) where if the log directory contains
      a semi-colon ';' it will be removed.
    • changed the writing logic of the directories footer;it won't be shown when no updates are installed.

    • V3.5 (major update)

    • added support for .cab updates.
    • updated error/warning messages and existence checks to support ".cab" files.
    • added the exit code of the program (wusa.exe or dism.exe) when it exits with an unknown error.
    • added a special keyword: "#admin#" to allow the elevation of the access level of the script.
    • added a warning message when dism.exe is detected and admin. privileges are not
      (needed for ".cab" files installation).
    • added a header and footer to indicate the start/end of directories/files,
      also another one to indicate the beginning/end of .cab files installation.
    • updated the console UI, the log files and the help page to reflect the new additions and accordingly
      changed the name of the script to "automate_msu_cab_updates".
    • compacted code as much as possible.
    • removed Windows Vista support.

    • V3.1.1

    • added 2 more error messages for corrupted updates and unsupported data type.
    • added a small summary at the end of the log files and the console UI.
    • added a counter to show how many directories are being processed
      (example: Directory #2 of 5).
    • updated the log files to reflect the new changes.
    • minor improvement to the separate updates counter.

    • V3.1

    • added back error messages for non-existing directories/files instead of ignoring them.
    • added the beep sound for errors/notifications.
    • fixed/removed the concept of 'parameters-restricted mode' after the script is called from outside
      to make it usable again when restarted.
    • no second backslash is needed for root directories (C:\ or D:\ or ...).
    • improved help page.
    • cleaned up code.

    • V3 (major update)

    • new logic to the script to distinguish between files and folders and separate them.
    • based on the previous implementation multiple inputs (directories and/or update files) are allowed.
    • fixed wrong code to show correct updates count when searching in sub-directories.
    • minor fixes.

    • V2
    minor (but critical) fixes to the code.​

    • V1
    initial release.​
    Code:
    automate_msu_cab_updates.bat
    CRC-32: cb2ee520
    MD5: 20a7ba13bfa54cc9b52644301272bffe
    SHA-1: 8f7db436a4b31d6ffe4da6dbf6c9fa71d5efddbb
    
    
    View attachment automate_msu_cab_updates__V4.2.zip
    
    
    
     
  2. Experties

    Experties MDL Novice

    Jun 11, 2014
    13
    1
    0
    Thank you very much @wk-952 for your good work , But I think that there is something deficient what about the apility to start this script in windows DvD’s vi setupcomplete.cmd , for example If i want to add Update to my custmized DvD and i but the update in file call update in %DVDROOT%\SOURCE\UPDATE\ my setupcomplete call your script to install the update that are there are in this path : %DVDROOT%\SOURCE\UPDATE\*.* , can you moded your script to do this o_O ..
    cheer and regards ..
     
  3. wk-952

    wk-952 MDL Member

    Sep 2, 2012
    115
    281
    10
    @Experties

    sorry i didn't get you properly, do you mean that all your updates are in: "%DVDROOT%\SOURCE\UPDATE\"
    if so you can simply type this: %DVDROOT%\SOURCE\UPDATE\ as a working directory
    but make sure to substitute %DVDROOT% with the actual value,
    for example in your setupcomplete.cmd you should type something like this: call automate_msu_updates.bat "G:\SOURCE\UPDATE\" "y" "n" "" "x"

    this should install all .msu updates in "G:\SOURCE\UPDATE\" and all its sub-directories without creating a log then exit when finished.
     
  4. Experties

    Experties MDL Novice

    Jun 11, 2014
    13
    1
    0
    @wk-952

    sorry becuse my eng , yes i thinks it will be something like you said , my setupcomplete.cmd will started at the end of installtion the cmd start update there aare inside update folder the cmd will call automate_msu_updates.bat to install all .msu stored in this path : dvd\source\$oem$\$1\update\*.* .
     
  5. Dos_Probie

    Dos_Probie MDL Senior Member

    Jul 18, 2012
    250
    84
    10
    #5 Dos_Probie, Jul 21, 2014
    Last edited by a moderator: Apr 20, 2017
    Thanks for the post WK, nice script!, I also run a update post install script that is completley unattended and called
    from my autounattend.xml root file, (should work from setupcomplete as well) and includes a voice .vbs file to notify me when the updates start and when done, does a count down on each update and also sets a log file in systemdrive. I am happy with mine but thanks again for all your work on this.

    ~DP :)
    Code:
    @echo off&setlocal ENABLEDELAYEDEXPANSION&color 1f&&title, [ WUSA - 8.1 UPDATE INSTALLER ]
    pushD "%~dp0" & cd /d "%~dp0"
    :: ~DosProbie - 10.25.13 - WPI.cmd
    
    :: Voice..Starting Updates..
    regsvr32 /s wintrust.dll
    %~dp0\sw\vbs\StartUpdates.vbs
    
    :: ### SCAN FOR UPDATES ---------------------------------------------------------
    for /F %%a in ('dir Updates\msu\*.msu ^|findstr /i "file(s)"') do set z=%%a
            echo Number Of Updates Found: %z%
    echo:&echo:
    
    :: ### INSTALLING UPDATES (reads updates in numerical order) --------------------
            echo == Installing %z% Windows Updates..(This may take a while, Please Wait)
    echo:
    for /R "%~dp0" %%A IN (*.MSU) DO (
            SET /A COUNT+=1
            ECHO= Installing !COUNT! of %z% = %%~nA
            >NUL TIMEOUT /t 3
            start /wait WUSA "%%A" /quiet /norestart
    )
    popD
    endlocal
    goto :wpi
    :wpi
    :: ### DATED UPDATE LOG FILE WHEN DONE ------------------------------------------
    set wusa=%systemdrive%\HotFixes-%date:~10,4%-%date:~4,2%-%date:~7,2%-%date:~0,3%.htm
    wmic qfe list full /format:htable>%wusa%
    
    :: DEPLOY WI-FI PROFILE (Auto-connects without prompting for wi-fi security key)
    cd %~dp0
    for /f "delims=" %%a in ('dir/b %cd%\*.xml') do (start "" netsh wlan add profile filename="%%a")
    
    :: Voice..Completed Updates..
    %~dp0\sw\vbs\FinsUpdates.vbs
    
    exit /b
     
    
    
     
  6. mabaega

    mabaega MDL Senior Member

    Dec 30, 2010
    269
    166
    10
    Setup Complete autounattend.xml

    @Dos_Probie
    would you like to share your full script, plzzz... :)
     
  7. Dos_Probie

    Dos_Probie MDL Senior Member

    Jul 18, 2012
    250
    84
    10
    #7 Dos_Probie, Jul 21, 2014
    Last edited: Jul 22, 2014
    lol, I thought I just did with the remarks and all, what else do you need to know?

    FYI, I pieced together the code for my specific needs from right here: http://forums.mydigitallife.net/printthread.php?t=46212&page=3
    ~DP

     
  8. mabaega

    mabaega MDL Senior Member

    Dec 30, 2010
    269
    166
    10
    Just want to know, script in %~dp0\sw\vbs\StartUpdates.vbs and %~dp0\sw\vbs\FinsUpdates.vbs :D
     
  9. Dos_Probie

    Dos_Probie MDL Senior Member

    Jul 18, 2012
    250
    84
    10
    #9 Dos_Probie, Jul 21, 2014
    Last edited by a moderator: Apr 20, 2017
    Just a simple .vbs voice script to notify me when updates begin and finish while away from my machine, here you go
    ~DP

    START UPDATES
    Code:
    CreateObject("SAPI.SpVoice").Speak "Installing Windows Eight Point One Critical Updates!" 
    FINISHED UPDATES
    Code:
    CreateObject("SAPI.SpVoice").Speak "Your Updates for Windows Eight Point One, have completed Successfully!" 
    
     
  10. hdmdl

    hdmdl MDL Junior Member

    Aug 9, 2014
    90
    30
    0
    Have you shared this in WHDownloader thread? it will very useful tool with that script
     
  11. murphy78

    murphy78 MDL DISM Enthusiast

    Nov 18, 2012
    6,787
    10,376
    210
    #11 murphy78, Aug 21, 2014
    Last edited by a moderator: Apr 20, 2017
    This is a neat script, but functionally it could be one line long:
    Code:
    forfiles /m *.msu /c "cmd /c = Installing Update: @FILE =&wusa @FILE /quiet /norestart"
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  12. NICK@NUMBER11

    NICK@NUMBER11 MDL Expert

    Mar 23, 2010
    1,354
    633
    60
    #12 NICK@NUMBER11, Aug 21, 2014
    Last edited by a moderator: Apr 20, 2017
    this is what i use nice and simple and easy to use, just place in the same dir as the updates

    Code:
    echo off
    TITLE WUSA: Windows Update Installer
    ::Code by NICK@NUMBER11 and s1ave77
    CLS
    setlocal ENABLEDELAYEDEXPANSION
    pushd "%~dp0"
    echo:
    echo Getting Ready Windows Update
    echo:
    for /F %%a in ('dir *.msu ^| find /i "file(s)"') do set z=%%a
    if "%z%"=="" goto :Failure
    echo Updates found: %z%
    echo:
    echo Installing Windows Updates...please wait. This may take a while.
    echo:
    FOR /R "%~dp0" %%A IN (*.MSU) DO (
            SET /A COUNT+=1
            ECHO= Installing !COUNT! of %z% = %%~nA
            >NUL TIMEOUT /t 3
            WUSA "%%A" /quiet /norestart
    )
    echo Done installing %z% updates on %date% at %time%.
    echo:
    echo You should reboot now!
    CHOICE /C YN /N /M "Reboot now? [Y]es [N]o :"
    if %errorlevel%==1 goto :Reboot
    if %errorlevel%==2 goto :Exit
    :Failure
    CLS
    echo ==========================================================
    echo:
    echo    NO UPDATES FOUND
    echo:
    echo    NOTE: Updates must be in same directory as this script.
    echo:
    echo ==========================================================
    echo:
    pause
    goto :Exit
    :Reboot
    ENDLOCAL
    start shutdown.exe /r /t 0    
    :Exit
    ENDLOCAL
    exit
     
  13. wk-952

    wk-952 MDL Member

    Sep 2, 2012
    115
    281
    10
    Update:
    -added support for the installation of .cab updates and tweaked the UI and logs a little bit, more in the "Changes / Fixes" spoiler.

    @Mods
    i can't change the title of the thread, could you please change it to be the same as the OP title, thanks in advance.
     
  14. yro

    yro MDL Senior Member

    Jul 26, 2009
    473
    82
    10
    #14 yro, Oct 11, 2014
    Last edited by a moderator: Apr 20, 2017
    Hi.

    What will your script do if the update is already installed on the system? Will it force the installation or ignore the particular update file and jump to the other update on the folder?
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  15. oldsh_t

    oldsh_t MDL Expert

    Dec 23, 2009
    1,010
    477
    60
    #15 oldsh_t, Oct 11, 2014
    Last edited: Oct 11, 2014
    It will ignore the particular update file and jump to the next update in the folder!!
     
  16. wk-952

    wk-952 MDL Member

    Sep 2, 2012
    115
    281
    10
    #16 wk-952, Oct 11, 2014
    Last edited: Oct 11, 2014
    (OP)
    Not my script nor the one written by NICK@NUMBER11 and s1ave77 will do that since both are using "WUSA.exe" for ".msu" files installation,
    if "WUSA.exe" found the target update already installed, it will terminate with an exit code: 0x00240006 which means that the update is already installed.

    EDIT:
    you can check this by ECHO-ing the !errorlevel! environment variable exactly after the START command,
    its value will be "2359302" which is the 'Dword Decimal' format of the above mentioned code.
     
  17. oldsh_t

    oldsh_t MDL Expert

    Dec 23, 2009
    1,010
    477
    60
    Well now I am at a loss here. I posted that NICK@NUMBER11 and s1ave77 batch file will only reinstall the updates, and s1ave77 Thanked me for the post and did not correct me??
    Then you post that their file will skip over an already installed file, and AGAIN s1ave77 thanked you for your post:confused::confused:
    I said it will not.....You say it will and s1ave77 says nothing LOL

    @s1ave77 What say you:biggrin:
     
  18. s1ave77

    s1ave77 MDL Guide Dog/Dev

    Aug 15, 2012
    14,964
    19,878
    340
    Wasn't sure about WUSA, so i checked after wk-952s post and found he's right :cool2:.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...
  19. oldsh_t

    oldsh_t MDL Expert

    Dec 23, 2009
    1,010
    477
    60
    Well Thank you slave77. I am going to try this out some day. It did not make any difference to me one way or another, but it is nice to know:D

    I will have to edit my post above to reflect the correct information.
     
  20. s1ave77

    s1ave77 MDL Guide Dog/Dev

    Aug 15, 2012
    14,964
    19,878
    340
    Checking the updates against installed ones is still the better way as it spares some time :good3:.
     
    Stop hovering to collapse... Click to collapse... Hover to expand... Click to expand...