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 .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. .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. #> [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.")] [ValidateScript( { If (Test-Path $_ -PathType 'Container') { $True } Else { Throw "Cannot find path $_" } })] [String] $Path = $PWD ) Begin { $Path = Get-ValidPath $Path } Process { # $Urls = $Updates | Select-UniqueUrl ForEach ($update in $Updates) { $filename = Split-Path $update.url -Leaf $target = "$($Path)\$($filename)" Write-Verbose "Download target will be $target" # $displayName = $Updates | Where-Object { $_.Url -eq $url } | Select-Object -ExpandProperty Note | Select-Object -First 1 $displayName = $update.Note # If the update is not already downloaded, download it. If (!(Test-Path -Path $target)) { If (Get-Command Start-BitsTransfer -ErrorAction SilentlyContinue) { If ($pscmdlet.ShouldProcess($(Split-Path $update.url -Leaf), "BitsDownload")) { Start-BitsTransfer -Source $update.url -Destination $target ` -Priority High -ErrorAction Continue -ErrorVariable $ErrorBits ` -DisplayName $displayName -Description "Downloading $($update.url)" } } Else { # BITS isn't available (likely PowerShell Core) If ($pscmdlet.ShouldProcess($update.url, "WebDownload")) { Invoke-WebRequest -Uri $update.url -OutFile $target -UseBasicParsing } } } Else { Write-Verbose "File exists: $target. Skipping download." } } } End { # Write-Output $urls } } |