Public/Dism/Update-WindowsImageOSD.ps1
<#
.SYNOPSIS Updates a mounted WIM .DESCRIPTION Updates a mounted WIM files. Requires OSDSUS Catalog .LINK https://osd.osdeploy.com/module/functions/dism/update-windowsimageosd .NOTES 19.11.19 David Segura @SeguraOSD #> function Update-WindowsImageOSD { [CmdletBinding()] Param ( #Specifies the full path to the root directory of the offline Windows image that you will service. [Parameter(ValueFromPipelineByPropertyName)] [string[]]$Path, #Check or Install the specified Update Group #Check = Validate installed Updates #All = Install all required Updates #AdobeSU = Adobe Security Update #DotNet = DotNet Update #DotNetCU = DotNet Cumulative Update #LCU = Latest Cumulative Update #SSU = Servicing Stack Update [ValidateSet('Check','All','AdobeSU','DotNet','DotNetCU','LCU','SSU')] [string]$Update = 'Check', #Download the file using BITS-Transfer #Interactive Login required [switch]$BitsTransfer, #Updates are only installed if they are needed. Force parameter will install the update even if it is already installed [switch]$Force ) Begin { #=================================================================================================== # Require Admin Rights #=================================================================================================== if ((Get-OSDGather -Property IsAdmin) -eq $false) { Write-Warning 'Update-WindowsImageOSD: This function requires Admin Rights ELEVATED' Break } #=================================================================================================== # Require OSDSUS Module #=================================================================================================== if (-not (Get-Module -ListAvailable -Name OSDSUS)) { Write-Warning "Update-WindowsImageOSD: PowerShell Module OSDSUS is required" Break } #=================================================================================================== # Get-WindowsImage Mounted #=================================================================================================== if ($null -eq $Path) { $Path = (Get-WindowsImage -Mounted | Select-Object -Property Path).Path } } Process { foreach ($Input in $Path) { #=================================================================================================== # Path #=================================================================================================== $MountPath = (Get-Item -Path $Input | Select-Object FullName).FullName Write-Verbose "Path: $MountPath" -Verbose #=================================================================================================== # Validate Mount Path #=================================================================================================== if (-not (Test-Path $Input -ErrorAction SilentlyContinue)) { Write-Warning "Update-WindowsImageOSD: Unable to locate Mounted WindowsImage at $Input" Break } #=================================================================================================== # Get Registry Information #=================================================================================================== $global:GetRegCurrentVersion = Get-RegCurrentVersion -Path $Input #=================================================================================================== # Require OSMajorVersion 10 #=================================================================================================== if ($global:GetRegCurrentVersion.CurrentMajorVersionNumber -ne 10) { Write-Warning "Update-WindowsImageOSD: OS MajorVersion 10 is required" Break } #=================================================================================================== # Get-OSDSUS and Filter Results #=================================================================================================== $global:GetOSDSUS = Get-OSDSUS -Catalog OSDBuilder | Sort-Object UpdateGroup -Descending $global:GetOSDSUS = $global:GetOSDSUS | Where-Object {$_.UpdateBuild -eq $global:GetRegCurrentVersion.ReleaseId} if ($global:GetRegCurrentVersion.BuildLabEx -match 'amd64') { $global:GetOSDSUS = $global:GetOSDSUS | Where-Object {$_.UpdateArch -eq 'x64'} } else { $global:GetOSDSUS = $global:GetOSDSUS | Where-Object {$_.UpdateArch -eq 'x86'} } if ($global:GetRegCurrentVersion.InstallationType -match 'WindowsPE') { $global:GetOSDSUS = $global:GetOSDSUS | Where-Object {$_.UpdateOS -eq 'Windows 10'} $global:GetOSDSUS = $global:GetOSDSUS | Where-Object {$_.UpdateGroup -notmatch 'Adobe'} $global:GetOSDSUS = $global:GetOSDSUS | Where-Object {$_.UpdateGroup -notmatch 'DotNet'} } if ($global:GetRegCurrentVersion.InstallationType -match 'Core') { $global:GetOSDSUS = $global:GetOSDSUS | Where-Object {$_.UpdateGroup -notmatch 'Adobe'} } if ($global:GetRegCurrentVersion.InstallationType -match 'Client') { $global:GetOSDSUS = $global:GetOSDSUS | Where-Object {$_.UpdateOS -notmatch 'Server'} } if ($global:GetRegCurrentVersion.InstallationType -match 'Server') { $global:GetOSDSUS = $global:GetOSDSUS | Where-Object {$_.UpdateOS -match 'Server'} } #Don't install Optional Updates $global:GetOSDSUS = $global:GetOSDSUS | Where-Object {$_.UpdateGroup -ne ''} if ($Update -ne 'Check' -and $Update -ne 'All') { $global:GetOSDSUS = $global:GetOSDSUS | Where-Object {$_.UpdateGroup -match $Update} } #=================================================================================================== # Get-SessionsXml #=================================================================================================== $global:GetSessionsXml = Get-SessionsXml -Path "$Input" | Where-Object {$_.targetState -eq 'Installed'} | Sort-Object id #=================================================================================================== # Apply Update #=================================================================================================== foreach ($item in $global:GetOSDSUS) { if (! ($Force.IsPresent)) { if ($global:GetSessionsXml | Where-Object {$_.KBNumber -match "$($item.FileKBNumber)"}) { Write-Verbose "Installed: $($item.Title) $($item.FileName)" -Verbose Continue } else { Write-Warning "Not Installed: $($item.Title) $($item.FileName)" } } if ($Update -eq 'Check') {Continue} if ($BitsTransfer.IsPresent) { $UpdateFile = Save-OSDDownload -SourceUrl $item.OriginUri -BitsTransfer -Verbose } else { $UpdateFile = Save-OSDDownload -SourceUrl $item.OriginUri -Verbose } $CurrentLog = "$env:TEMP\OSD\$((Get-Date).ToString('yyyy-MM-dd-HHmmss'))-Update-WindowsImageOSD.log" if (! (Test-Path "$env:TEMP\OSD")) {New-Item -Path "$env:TEMP\OSD" -Force | Out-Null} if (Test-Path $UpdateFile.FullName) { #Write-Verbose "Add-WindowsPackage -PackagePath $($UpdateFile.FullName) -Path $Input" -Verbose Try { Write-Verbose "Add-WindowsPackage -Path $Input -PackagePath $($UpdateFile.FullName)" -Verbose Add-WindowsPackage -Path $Input -PackagePath $UpdateFile.FullName -LogPath $CurrentLog | Out-Null } Catch { if ($_.Exception.Message -match '0x800f081e') { Write-Verbose "Update-WindowsImageOSD: 0x800f081e The package is not applicable to this image" -Verbose} Write-Verbose $CurrentLog -Verbose } } else { Write-Warning "Unable to download $($UpdateFile.FullName)" } } #=================================================================================================== # Return for PassThru #=================================================================================================== Get-WindowsImage -Mounted | Where-Object {$_.Path -eq $MountPath} } } End {} } |