Param($CsvPath, $PackageDir, $LogDir) if ($PSBoundParameters.Count -ne 3) { Write-host "Error: -CsvPath -PackageDir -LogDir " ;exit 1} If ( -not (Test-Path $CsvPath)) { Write-host "Error: -CsvPath does not exist." ;exit 1} If ( -not (Test-Path $packagedir)) { Write-host "Error: -PackageDir does not exist." ;exit 1} If ( -not (Test-Path $LogDir)) { Write-host "Error: -LogDir does not exist." ;exit 1} # Keywords that are not downloaded based on part of the file name. 'KB9999999' is dummy (you can delete it). # 'KB5043080' is a checkpoint cumulative update for Windows 11 24H2 and Windows Server 2025 or later, and does not require installation. # Detail: https://learn.microsoft.com/ja-jp/windows/deployment/update/catalog-checkpoint-cumulative-updates $ExcludeLists = 'KB5043080','KB9999999' function Write-Log { param ( [string]$Message, [string]$LogPath = "$env:TEMP\onlinepatch.log" ) #Output to Console Write-Host $Message $timestamp = Get-Date -Format "yyyy-MM-dd HH:mm:ss" $entry = "[$timestamp] $Message" Add-Content -Path $LogPath -Value $entry } # for .\get-updateids.ps1 # for .\get-downloadLinks { Set-Location -Path $PSScriptRoot function Start-Download { param ( [string]$downloaduri, [string]$PackageDir ) $filename = Split-Path $downloaduri -Leaf if (Test-Path (Join-Path $PackageDir $filename)) { Write-Log -Message "File $($filename) has already beed downloaded. Skip download." -LogPath $LogPath } else { Write-Log -Message "Downloading $($filename) ..." -LogPath $LogPath if (Test-Path "$env:WINDIR\System32\curl.exe") { & curl.exe -L --fail --retry 3 --retry-delay 2 -o (Join-Path $PackageDir $filename) $downloaduri } else { $ProgressPreference = 'SilentlyContinue' Invoke-WebRequest -Uri $downloaduri -OutFile (Join-Path $PackageDir $filename) $ProgressPreference = 'Continue' } if (Test-Path (Join-Path $PackageDir $filename)) { Write-Log -Message "Download completed." -LogPath $LogPath } else { Write-Log -Message "Download failed." -LogPath $LogPath } } } $LogPath = "$LogDir\downloadupdates.log" if (Test-Path $logPath) { $logTime = (get-item $logPath).LastWriteTime } else { $logTime = get-Date("1900/1/1") } Write-Log -Message "Start download-updates.ps1" -LogPath $LogPath Write-Log -Message "Import CSV from $($CsvPath)" -LogPath $LogPath $csvrows = Import-Csv -Path $CsvPath Write-Log -Message "Found $($csvrows.Count) udpates." -LogPath $LogPath foreach ($csvrow in $csvrows) { $KBID = $csvrow.KBId $TITLE = $csvrow.TITLE $HINTID = $csvrow.UpdateId $HINT = "NOTMATCHTITLE" if ($TITLE -match "Server") { $HINT = "Server" } elseif ($TITLE -match "x64-based") { $HINT = "x64-based" } elseif ($TITLE -match "arm64-based") { $HINT = "arm64-based" } $UpdateIds = .\Get-UpdateIds.ps1 -KB $KBID if ($UpdateIds.Count -eq 0) { Write-Log -Message "UpdateID corresponding to $($KBID) not found." -LogPath $LogPath } else { foreach ($UpdateId in $UpdateIds) { $DownloadID = "" if($UpdateId.UpdateId -eq $HINTID) { $DownloadId = $UpdateId.UpdateId } elseif($UpdateId.TITLE -match $HINT) { $DownloadId = $UpdateId.UpdateId } if ($DownloadId -ne "") { $downloadlinks = .\Get-DownloadLinks.ps1 -UpdateId $DownloadId if ($downloadlinks.Count -eq 0) { Write-Log -Message "DownloadLinks corresponding to $($KBID) : $($UpdateId.UpdateId) not found." -LogPath $LogPath } else { foreach ($downloadlink in $downloadLinks) { if ($downloadlink.FileName | Select-String -Pattern $ExcludeLists -SimpleMatch -Quiet) { Write-Log -Message "Skip UpdateID: $($UpdateId.UpdateId) FileName $($downloadlink.FileName -replace '^(?s)(.{0,25}).*','$1') ... based on the ExcludeLists." -LogPath $LogPath } else { Start-Download -downloaduri $downloadlink.URL -PackageDir $PackageDir } } } } else { Write-Log -Message "Skip UpdateID: $($UpdateId.UpdateId) based on the hint (ID or Platform)." -LogPath $LogPath } } } }