-
Notifications
You must be signed in to change notification settings - Fork 193
feat: Add update deadline prompt system #1132
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Romanitho
merged 8 commits into
Romanitho:develop
from
rtylerdavis:feature/update-deadline-prompt
May 19, 2026
Merged
Changes from all commits
Commits
Show all changes
8 commits
Select commit
Hold shift + click to select a range
db3d5d7
feat: add update deadline prompt system with user-facing WPF dialog
rtylerdavis 92c53ff
fix: address review feedback from Copilot
rtylerdavis 1b0848a
chore: replace notify icon with official WAU icon
rtylerdavis a26e963
fix: rename $sender param to avoid PSScriptAnalyzer automatic variabl…
rtylerdavis e137cf8
fix: pass custom winget source to Update-App and Confirm-Installation
rtylerdavis c66bc67
refactor: consolidate ADMX policies into main WAU.admx
rtylerdavis 1c332ef
chore: bump ADMX/ADML revision to 5.3
rtylerdavis 0870aeb
fix: address PR #1132 review feedback (Copilot + Romanitho 2026-04-21)
rtylerdavis File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,164 @@ | ||
| <# | ||
| .SYNOPSIS | ||
| Installs pending updates selected by the user via the WAU deadline prompt. | ||
|
|
||
| .DESCRIPTION | ||
| Runs in SYSTEM context as the Winget-AutoUpdate-UpdateNow scheduled task. | ||
| Triggered when the user clicks "Update Now" in the WAU deadline prompt dialog. | ||
|
|
||
| Reads the list of apps to update from config\pending-updates.json (written by | ||
| the main WAU task), processes each app through WAU's standard Update-App pipeline | ||
| (which handles retries, mods, and per-app notifications), then cleans up registry | ||
| deadline entries for apps that were successfully updated. | ||
|
|
||
| Initialization mirrors Winget-Upgrade.ps1 so that Update-App and its dependencies | ||
| (Start-NotifTask, Write-ToLog, Confirm-Installation, etc.) have all required | ||
| script-scoped variables in scope. | ||
|
|
||
| .NOTES | ||
| Scheduled task: Winget-AutoUpdate-UpdateNow | ||
| Run as: SYSTEM (S-1-5-18), RunLevel Highest | ||
| Trigger: On demand (started by WAU-UpdatePrompt.ps1) | ||
| Instances: IgnoreNew (only one instance at a time) | ||
| #> | ||
|
|
||
| #region LOAD FUNCTIONS | ||
| [string]$Script:WorkingDir = $PSScriptRoot | ||
|
|
||
| Get-ChildItem -Path "$Script:WorkingDir\functions" -File -Filter "*.ps1" -Depth 0 | | ||
| ForEach-Object { . $_.FullName } | ||
| #endregion LOAD FUNCTIONS | ||
|
|
||
| #region INITIALIZATION | ||
| $null = & "$env:WINDIR\System32\cmd.exe" /c "" | ||
| [Console]::OutputEncoding = [System.Text.Encoding]::UTF8 | ||
| $Script:ProgressPreference = [System.Management.Automation.ActionPreference]::SilentlyContinue | ||
|
|
||
| [string]$LogFile = [System.IO.Path]::Combine($Script:WorkingDir, 'logs', 'updates.log') | ||
| #endregion INITIALIZATION | ||
|
|
||
| #region CONTEXT AND CONFIG | ||
| [bool]$Script:IsSystem = $true | ||
|
|
||
| Write-ToLog -LogMsg "USER-INITIATED UPDATE" -IsHeader | ||
|
|
||
| $Script:WAUConfig = Get-WAUConfig | ||
|
|
||
| [string]$Script:WingetSourceCustom = 'winget' | ||
| if ($null -ne $Script:WAUConfig.WAU_WingetSourceCustom) { | ||
| $Script:WingetSourceCustom = $Script:WAUConfig.WAU_WingetSourceCustom.Trim() | ||
| } | ||
|
|
||
| [string]$LocaleDisplayName = Get-NotifLocale | ||
| Write-ToLog "Notification Level: $($Script:WAUConfig.WAU_NotificationLevel). Notification Language: $LocaleDisplayName" "Cyan" | ||
| #endregion CONTEXT AND CONFIG | ||
|
|
||
| #region WINGET | ||
| [string]$Script:Winget = Get-WingetCmd | ||
|
|
||
| if (-not $Script:Winget) { | ||
| Write-ToLog "Critical: Winget not found -- cannot process updates" "Red" | ||
| Exit 1 | ||
| } | ||
|
|
||
| Write-ToLog "Selected winget instance: $Script:Winget" | ||
| #endregion WINGET | ||
|
|
||
| #region READ PENDING UPDATES | ||
| $JsonPath = [System.IO.Path]::Combine($Script:WorkingDir, 'config', 'pending-updates.json') | ||
|
|
||
| if (-not (Test-Path $JsonPath)) { | ||
| Write-ToLog "No pending-updates.json found -- nothing to update" "Cyan" | ||
| Exit 0 | ||
| } | ||
|
|
||
| try { | ||
| $pendingData = Get-Content -Path $JsonPath -Raw -Encoding UTF8 | ConvertFrom-Json | ||
| } | ||
| catch { | ||
| Write-ToLog "ERROR: Could not parse pending-updates.json -- $($_.Exception.Message)" "Red" | ||
| Exit 1 | ||
| } | ||
|
|
||
| if (-not $pendingData.Apps -or @($pendingData.Apps).Count -eq 0) { | ||
| Write-ToLog "pending-updates.json contains no apps -- nothing to update" "Cyan" | ||
| Remove-Item -Path $JsonPath -Force -ErrorAction SilentlyContinue | ||
| Exit 0 | ||
| } | ||
|
|
||
| Write-ToLog "$(@($pendingData.Apps).Count) apps queued for update" | ||
| #endregion READ PENDING UPDATES | ||
|
|
||
| #region PROCESS UPDATES | ||
| $Script:InstallOK = 0 | ||
| $DeadlineRegBase = "HKLM:\SOFTWARE\Romanitho\Winget-AutoUpdate\UpdateDeadlines" | ||
|
|
||
| # Split apps by scope -- user-scoped apps must be updated in user context. | ||
| $machineApps = @($pendingData.Apps | Where-Object { $_.Scope -ne 'user' }) | ||
| $userApps = @($pendingData.Apps | Where-Object { $_.Scope -eq 'user' }) | ||
|
|
||
| if ($machineApps.Count -gt 0) { | ||
| Write-ToLog "$($machineApps.Count) machine-scoped apps to update" | ||
| foreach ($app in $machineApps) { | ||
| Write-ToLog "-> $($app.Name) : $($app.Version) -> $($app.AvailableVersion)" | ||
|
|
||
| Update-App $app -src $Script:WingetSourceCustom | ||
|
|
||
| if (Confirm-Installation $app.Id $app.AvailableVersion $Script:WingetSourceCustom) { | ||
| $AppRegPath = Join-Path $DeadlineRegBase $app.Id | ||
| if (Test-Path $AppRegPath) { | ||
| Remove-Item -Path $AppRegPath -Recurse -Force -ErrorAction SilentlyContinue | ||
| Write-ToLog "Deadline entry purged (update confirmed): $($app.Id)" | ||
| } | ||
| } | ||
| else { | ||
| Write-ToLog "$($app.Name) : update could not be confirmed -- deadline entry preserved for next run" "Yellow" | ||
| } | ||
| } | ||
| } | ||
|
|
||
| # User-scoped apps: hand off to user context task for update. | ||
| # Deadline entries are cleaned up on the next SYSTEM cycle when the app | ||
| # no longer appears in user-context-outdated.csv (self-healing). | ||
| if ($userApps.Count -gt 0) { | ||
| if ($Script:WAUConfig.WAU_UserContext -eq 1) { | ||
| $userUpdateDir = [System.IO.Path]::Combine($env:ProgramData, 'Winget-AutoUpdate') | ||
| if (-not (Test-Path $userUpdateDir)) { New-Item -ItemType Directory -Path $userUpdateDir -Force | Out-Null } | ||
| $userUpdatePath = [System.IO.Path]::Combine($userUpdateDir, 'user-context-update.json') | ||
| try { | ||
| ConvertTo-Json -InputObject @($userApps) -Depth 3 | Set-Content -Path $userUpdatePath -Encoding UTF8 -Force | ||
| Write-ToLog "$($userApps.Count) user-scoped apps written to user-context-update.json" | ||
|
|
||
| $userContextTask = Get-ScheduledTask -TaskName 'Winget-AutoUpdate-UserContext' -ErrorAction SilentlyContinue | ||
| if ($userContextTask) { | ||
| $userContextTask | Start-ScheduledTask | ||
| Write-ToLog "UserContext task triggered for user-scoped updates" | ||
| } | ||
| else { | ||
| Write-ToLog "WARNING: UserContext task not found -- user-scoped apps will not be updated" "Yellow" | ||
| } | ||
| } | ||
| catch { | ||
| Write-ToLog "ERROR: Could not write user-context-update.json -- $($_.Exception.Message)" "Red" | ||
| } | ||
| } | ||
| else { | ||
| Write-ToLog "$($userApps.Count) user-scoped apps skipped (WAU_UserContext not enabled)" "Yellow" | ||
| } | ||
| } | ||
| #endregion PROCESS UPDATES | ||
|
|
||
| #region CLEANUP | ||
| Remove-Item -Path $JsonPath -Force -ErrorAction SilentlyContinue | ||
| Write-ToLog "pending-updates.json removed" | ||
|
|
||
| if ($Script:InstallOK -gt 0) { | ||
| Write-ToLog "$Script:InstallOK apps successfully updated" "Green" | ||
| } | ||
| else { | ||
| Write-ToLog "No apps were successfully updated" "Yellow" | ||
| } | ||
|
|
||
| Write-ToLog "End of user-initiated update" "Cyan" | ||
| Start-Sleep 3 | ||
| #endregion CLEANUP |
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.