There are updates that have to be installed after the OS has been installed. .Net Framework is an example. When I am building a reference image, I cannot inject the updates as packages to .Net Framework as it is not installed until after the OS has been installed. There have also been cases where an MSU could not be injected before the OS was installed. It would kill the build. I don't want to waste time having to wait on the windows update task to download, verify, and install the update. This script will solve these issues. The script is designed to get all EXE and MSU files in the same directory as the InstallOnlineUpdates.ps1 PowerShell script and install them.
The first thing you want to do is let the reference image complete. Once it is finished, look at the ZTIWindowsUpdate.log file. It will show all updates that were downloaded and installed during the Windows Update task. The next thing is to download the updates, which can easily be done at https://catalog.update.microsoft.com/. Once you have the updates downloaded, place them in the same directory as this PowerShell script. In order to sequence these out, number them starting from 01 and etc. You can see how I have done mine in the screenshot below. I put EXE and MSU in the front of the filename so they would be separated and easy to find.
Source from: http://mickitblog.blogspot.hk/2016/01/installing-microsoft-updates-in-build.html
Source from: http://mickitblog.blogspot.hk/2016/01/installing-microsoft-updates-in-build.html
Now all you have to do is to create an application to execute the PowerShell script and it will install all of your EXE and MSU files that need to be installed post-OS.
You can download the script from here.
1: <#
2: .NOTES
3: ===========================================================================
4: Created with: SAPIEN Technologies, Inc., PowerShell Studio 2015 v4.2.99
5: Created on: 1/18/2016 1:41 PM
6: Created by: Mick Pletcher
7: Organization:
8: Filename: InstallOnlineUpdates.ps1
9: ===========================================================================
10: .DESCRIPTION
11: This script will install both exe updates and msu updates. It is
12: intended to be used during the generation of a reference image. Not
13: all updates can be injected offline into the OS. This script takes
14: care of those by running post-OS install.
15: #>
16:
17:
18: function Install-EXEUpdates {
19: #Declare Variables
20: Set-Variable -Name Arguments -Scope Local -Force
21: Set-Variable -Name ErrCode -Scope Local -Force
22: Set-Variable -Name File -Scope Local -Force
23: Set-Variable -Name EXEFiles -Scope Local -Force
24: Set-Variable -Name RelativePath -Scope Local -Force
25:
26: $RelativePath = (split-path $SCRIPT:MyInvocation.MyCommand.Path -parent) + "\"
27: $EXEFiles = Get-ChildItem -Path $RelativePath -Force | where { $_.Name -like "*.exe*" }
28: If ($EXEFiles.Count -ge 1) {
29: $EXEFiles | Sort-Object
30: cls
31: foreach ($File in $EXEFiles) {
32: $Arguments = "/passive /norestart"
33: Write-Host "Installing"$File.Name"....." -NoNewline
34: $ErrCode = (Start-Process -FilePath $File.Fullname -ArgumentList $Arguments -Wait -Passthru).ExitCode
35: If ($ErrCode -eq 0) {
36: Write-Host "Success" -ForegroundColor Yellow
37: } else {
38: Write-Host "Failed with error code"$ErrCode -ForegroundColor Red
39: }
40: }
41: }
42:
43: #Cleanup Local Variables
44: Remove-Variable -Name Arguments -Scope Local -Force
45: Remove-Variable -Name ErrCode -Scope Local -Force
46: Remove-Variable -Name File -Scope Local -Force
47: Remove-Variable -Name EXEFiles -Scope Local -Force
48: Remove-Variable -Name RelativePath -Scope Local -Force
49: }
50:
51: function Install-MSUUpdates {
52: #Declare Variables
53: Set-Variable -Name Arguments -Scope Local -Force
54: Set-Variable -Name ErrCode -Scope Local -Force
55: Set-Variable -Name Executable -Value $env:windir"\System32\wusa.exe" -Scope Local -Force
56: Set-Variable -Name File -Scope Local -Force
57: Set-Variable -Name MSUFiles -Scope Local -Force
58: Set-Variable -Name RelativePath -Scope Local -Force
59:
60: $RelativePath = (split-path $SCRIPT:MyInvocation.MyCommand.Path -parent) + "\"
61: $MSUFiles = Get-ChildItem -Path $RelativePath -Force | where { $_.Name -like "*.msu*" }
62: If ($MSUFiles.Count -ge 1) {
63: $MSUFiles | Sort-Object
64: cls
65: foreach ($File in $MSUFiles) {
66: $Arguments = $File.FullName + [char]32 + "/quiet /norestart"
67: Write-Host "Installing"$File.Name"....." -NoNewline
68: $ErrCode = (Start-Process -FilePath $Executable -ArgumentList $Arguments -Wait -Passthru).ExitCode
69: If (($ErrCode -eq 0) -or ($ErrCode -eq 2359302)) {
70: Write-Host "Success" -ForegroundColor Yellow
71: } else {
72: Write-Host "Failed with error code"$ErrCode -ForegroundColor Red
73: }
74: }
75: }
76:
77: #Cleanup Local Variables
78: Remove-Variable -Name Arguments -Scope Local -Force
79: Remove-Variable -Name ErrCode -Scope Local -Force
80: Remove-Variable -Name Executable -Scope Local -Force
81: Remove-Variable -Name File -Scope Local -Force
82: Remove-Variable -Name MSUFiles -Scope Local -Force
83: Remove-Variable -Name RelativePath -Scope Local -Force
84: }
85:
86: cls
87: Install-EXEUpdates
88: Install-MSUUpdates
89: Start-Sleep -Seconds 5
90:
No comments:
Post a Comment