Windows Offline Update Script

Discussion in 'Windows 8' started by ColdZero, May 17, 2014.

  1. ColdZero

    ColdZero MDL Addicted

    Nov 9, 2009
    640
    2,893
    30
    #1 ColdZero, May 17, 2014
    Last edited by a moderator: Apr 20, 2017
    The script will run all the Windows patches (.msu files) in a folder.
    Features:
    * Unblock the files.
    * Show the files count.
    * Show the progress. (Current file number of total.)
    * Installs .exe and .msu files.
    * Can make a list of installed patches.

    Instructions:
    Put the Windows patches and the script in a folder (any name)
    Then run the script as Administrator.

    Source Code: (Name this file "Patcher.cmd" or anything you like.)
    Code:
    @echo off
    setlocal EnableDelayedExpansion
    
    cls
    title Windows 8.1 Offline Updater by ColdZero
    color 1F
    
    
    rem [Select Current Directory]
    set BATDIR1=%~dp0
    cd /d %BATDIR1%
    
    :Check-Admin
    openfiles >nul 2>&1
    if %errorlevel% NEQ 0 goto :required
    
    :UnblockFiles
    cls
    echo Unblocking Files
    echo+
    echo Executing Powershell...
    echo+
    Powershell -Command "& {dir | Unblock-File}"
    title Windows 8 Offline Updater
    echo+
    
    
    :Counters
    set /A countermsu=0
    set /A counterexe=0
    set /A totalmsu=0
    set /A totalexe=0
    
    @for %%V in (*.msu) do (
    set /A totalmsu = totalmsu + 1
    )
    @for %%V in (*.exe) do (
    set /A totalexe = totalexe + 1
    )
    
    :Menu
    cls
    Echo+
    Echo -------------------------------------------------------------------------------
    Echo    Windows 8.1 Off-Line Updates                       Package:  OEM
    Echo -------------------------------------------------------------------------------
    Echo+
    echo Hello %USERNAME%, what do you want to do?
    echo+
    echo    A) Install Critical Updates (MSU: %totalmsu%) (EXE: %totalexe%)
    echo    B) View Installed Updates
    echo    Q) Exit
    echo+
    rem Menu Choose Option Code
    set /p userinp= ^> Select Option : 
    set userinp=%userinp:~0,1%
    if /i "%userinp%"=="Q" exit
    if /i "%userinp%"=="A" goto :Patches_Install
    if /i "%userinp%"=="B" goto :Patches_List
    goto :Menu
    
    :Patches_List
    ::Patches List Code
    If exist patchlist.txt del patchlist.txt
    wmic qfe get hotfixid >patchlist.txt
    start patchlist.txt
    goto :Menu
    exit
    
    
    
    :Patches_Install
    rem Code for Executing a .exe file and wait until its finish "Start /Wait File.exe /quiet /norestart"
    rem Code for silent update "KB00000.msu /quiet /norestart
    rem Patches Installation code
    cls
    Echo+
    Echo -------------------------------------------------------------------------------
    Echo    Windows 8.1 Off-Line Updates                       Package:  OEM
    Echo -------------------------------------------------------------------------------
    Echo+
    echo+
    rem Go to folder Critical Updates
    rem cd "Critical Updates"
    echo Installing OEM Patches...
    echo+
    
    rem This code install all .msu files in folder Critical Updates
    @for %%V in (*.exe) do (
    set /A counterexe = counterexe + 1
    echo Installing !counterexe! of %totalexe%
    echo %%V
    %%V /quiet /norestart
    If %errorlevel% NEQ 0 echo Warning: Minor error! "dont worry"
    echo+
    )
    
    @for %%V in (*.msu) do (
    set /A countermsu = countermsu + 1
    echo Installing !countermsu! of %totalmsu%
    echo %%V
    %%V /quiet /norestart
    If %errorlevel% NEQ 0 echo Warning: Minor error! "dont worry"
    echo+
    )
    
    echo+
    echo ***********
    echo  Complete!
    echo ***********
    echo+
    Pause
    cd..
    Exit
    
    rem -------------------------------------------------------------------------------------
    rem Other functions
    rem -------------------------------------------------------------------------------------
    :required
    cls
    color 0f
    echo Run the script as Administrator
    echo+
    echo Correr el script como Administrador
    echo+
    pause
    exit
    
     
  2. abbodi1406

    abbodi1406 MDL KB0000001

    Feb 19, 2011
    7,834
    25,575
    240
    Offline can be a misleading word for offline integration :D
     
  3. Mr.X

    Mr.X MDL Guru

    Jul 14, 2013
    5,928
    13,470
    180
    Totally agreed. I thought it was for offline integration :(
     
  4. Flipp3r

    Flipp3r MDL Expert

    Feb 11, 2009
    1,534
    659
    60
    Yeah me too. Assumed I'd run this from WinPE..
     
  5. ColdZero

    ColdZero MDL Addicted

    Nov 9, 2009
    640
    2,893
    30
    #5 ColdZero, May 19, 2014
    Last edited by a moderator: Apr 20, 2017
    (OP)
    Explain a little bit please...
    Do you want to integrate the updates via Dism command in a WIM file?

    In Dism to integrate all the patches just do:
    Code:
    DISM.exe /Image:C:\mount\Windows /Add-Package /PackagePath:C:\patches\packages
    
    This single line adds every msu file found inside the "packages" folder to the mounted wim file automatically.
     
  6. Marc05

    Marc05 MDL Novice

    Jan 3, 2010
    8
    1
    0
    #6 Marc05, May 20, 2014
    Last edited by a moderator: Apr 20, 2017
    I see I'm not the only one who thought this was for offline integration. Here's a little script I was working on. There's still stuff I want to do for it, but it's fine for now.

    Code:
    # Windows image (.wim) update integration
    # Required:
    # - DISM Tool (include in Windows PATH; you should have this by default)
    # - PowerShell
    # - Windows 7 ISO (extract to folder)
    # - *.msu and or *.cab update files
    # Recommended update list:  steven4554's list at msfn.org
    # Todo:
    # - Add support for .vhd files
    # - Some error checking
    # - Add option to prompt for variables instead of having to edit script (on by default maybe)
    
    # Cheks references to uninitialized variables, both directly and from within strings
    Set-StrictMode -Version 2
    
    # ========================================================================================================================
    # ----START BLOCK---- EDIT THE VALUES OF THESE VARIABLES TO MATCH YOUR ENVIRONMENT
    # ========================================================================================================================
    
    # Path to the .wim file (e.g. C:\win7x64\sources\install.wim)
    [string]$WIMFILE = ""
    # Path to a temporary folder to mount the .wim file (no trailing backslash!)
    [string]$MOUNTFOLDER = ""
    
    # Add the path to the folder with the 32-bit or 64-bit updates to the corresponding UPDATESFOLDER variables.
    # Do not include trailing backslashes. You may leave either X64 or X86 variables blank if
    # your image only conaints one architecture. Add the index numbers of the versions in the image to be updated.
    # E.G. $X86UPDATESFODLER = "C:\x64updates"
    #      $aX86Indexes = @(1,2,3)
    [string]$X86UPDATESFOLDER = ""
    [uint16[]]$aX86Indexes = @()
    
    [string]$X64UPDATESFOLDER = ""
    [uint16[]]$aX64Indexes = @()
    
    # Add 32-bit updates to be excluded here
    [string[]]$aExcludedX86Updates = @(
            # Non-integratable
            "Windows6.1-KB2533552-x86.msu", "Windows6.1-KB2603229-x86.msu"
        )
    
    # Add 64-bit updates to be excluded here
    [string[]]$aExcludedX64Updates = @(
            # Non-integratable
            "Windows6.1-KB2533552-x64.msu", "Windows6.1-KB2603229-x64.msu"
        )
    
    # ========================================================================================================================
    # ----END BLOCK----
    # ========================================================================================================================
    
    # Adds given updates to a .wim file
    Function AddPackageToWim
    {
        Param
        (
            [uint16]$nWIMIndex = 0,              # the index number of a version inside the .wim
            [string]$strUpdatesFolder = "",      # path to the updates folder to integrate in the .wim
            [string[]]$aExcludedUpdates = @()    # a list of updates to be excluded from the .wim
        )
    
        [string[]]$aUpdates = @()
        Get-ChildItem $strUpdatesFolder -Include @("*.cab","*.msu") -Recurse | Sort-Object LastWriteTime | `
            Foreach-Object
            {
                If($aExcludedUpdates -notcontains $_.Name)
                    {
                        $aUpdates += @($_.Name)
                    }
            }
    
        # Mount the WIM image
        Write-Host "Mounting `"$WIMFILE`" with index `"$nWIMIndex`" to `"$MOUNTFOLDER`""
        DISM /Mount-Wim /WimFile:$WIMFILE /MountDir:$MOUNTFOLDER /Index:$index
    
        foreach($strUpdate in $aUpdates)
        {
            Write-Host "Adding Update: "$strUpdate
            # Add the update to the image
            DISM /Image:$MOUNTFOLDER /Add-Package /PackagePath:$strUpdatesFolder\$strUpdate
        }
    
        Write-Host "Commiting changes..."
        # Commit the changes to the image and dismount
        DISM /Unmount-Wim /MountDir:$MOUNTFOLDER /commit
    }
    
    # Check variables are valid before proceeding
    # graceful program termination? lolololol
    
    If($X86UPDATESFOLDER -ne "")
    {
        # Edit 32-bit versions in the .wim file
        foreach($nIndex in $aX86Indexes)
        {
            AddPackageToWim $nElement $X86UPDATESFOLDER $aExcludedX86Updates
        }
    }
    
    If($X64UPDATESFOLDER -ne "")
    {
        # Edit x64 versions in the .wim file
        foreach($nIndex in $aX64Indexes)
        {
            AddPackageToWim $nElement $X64UPDATESFOLDER $aExcludedX64Updates
        }
    }