Public/Save-LatestUpdate.ps1
Function Save-LatestUpdate { <# .SYNOPSIS Downloads the latest cumulative update passed from Get-LatestUpdate. .DESCRIPTION Downloads the latest cumulative update passed from Get-LatestUpdate to a local folder. Then do one or more of the following: - Import the update into an MDT share with Import-LatestUpdate to speed up deployment of Windows (reference images etc.) - Apply the update to an offline WIM using DISM - Deploy the update with ConfigMgr (if not using WSUS) .NOTES Author: Aaron Parker Twitter: @stealthpuppy .LINK https://docs.stealthpuppy.com/latestupdate .PARAMETER Updates The array of latest cumulative updates retreived by Get-LatestUpdate. .PARAMETER Path A destination path for downloading the cumulative updates to. This path must exist. Uses the current diretory by default. .PARAMETER ForceWebRequest Forces the use of Invoke-WebRequest over Start-BitsTransfer on Windows PowerShell. .EXAMPLE Get-LatestUpdate | Save-LatestUpdate Description: Retreives the latest Windows 10 Cumulative Update with Get-LatestUpdate and passes the array of updates to Save-LatestUpdate on the pipeline. Save-LatestUpdate then downloads the latest updates to the current directory. .EXAMPLE $Updates = Get-LatestUpdate -WindowsVersion Windows10 -Build 14393 Save-LatestUpdate -Updates $Updates -Path C:\Temp\Update Description: Retreives the latest Windows 10 build 14393 (1607) Cumulative Update with Get-LatestUpdate, saved to the variable $Updates. Save-LatestUpdate then downloads the latest updates to C:\Temp\Update. .EXAMPLE $Updates = Get-LatestUpdate Save-LatestUpdate -Updates $Updates -Path C:\Temp\Update -ForceWebRequest Description: Retreives the latest Windows 10 build Cumulative Update with Get-LatestUpdate, saved to the variable $Updates. Save-LatestUpdate then downloads the latest updates to C:\Temp\Update using Invoke-WebRequest instead of Start-BitsTransfer. #> [CmdletBinding(SupportsShouldProcess = $True)] [OutputType([Array])] Param( [Parameter(Mandatory = $True, Position = 0, ValueFromPipeline = $True, ValueFromPipelineByPropertyName = $True, ` HelpMessage = "The array of updates from Get-LatestUpdate.")] [ValidateNotNullOrEmpty()] [Array] $Updates, [Parameter(Mandatory = $False, Position = 1, ValueFromPipeline = $False, ` HelpMessage = "Specify a target path to download the update(s) to.")] [ValidateNotNullOrEmpty()] [ValidateScript( { If (!(Test-Path -Path $_ -PathType 'Container')) { Throw "Cannot find path $_" } Return $True })] [String] $Path = $PWD, [Parameter(Mandatory = $False)] [switch] $ForceWebRequest ) Begin { $Path = Get-ValidPath $Path $output = @() } Process { # Step through each update in $Updates ForEach ($update in $Updates) { # Create the target file path where the update will be saved $filename = Split-Path $update.URL -Leaf $target = Join-Path $Path $filename $output += $target Write-Verbose "Download target will be $target" # If the update is not already downloaded, download it. If (!(Test-Path -Path $target)) { If ($ForceWebRequest -or (Test-PSCore)) { # Running on PowerShell Core or ForceWebRequest If ($pscmdlet.ShouldProcess($update.URL, "WebDownload")) { try { Invoke-WebRequest -Uri $update.URL -OutFile $target -UseBasicParsing -ErrorAction SilentlyContinue } catch { Throw $_ } } } Else { # Running on Windows PowerShell If ($pscmdlet.ShouldProcess($(Split-Path $update.URL -Leaf), "BitsDownload")) { try { Start-BitsTransfer -Source $update.URL -Destination $target ` -Priority High -ErrorAction SilentlyContinue -ErrorVariable $ErrorBits ` -DisplayName $update.Note -Description "Downloading $($update.URL)" } catch { Throw $_ } } } } Else { Write-Verbose "File exists: $target. Skipping download." } } } End { Write-Output $output } } |