Windows Update step fails when topgrade runs in an SSH session
help wantedP-WindowsA-step
## Checklist
- [X] I have searched the issue tracker for relevant or duplicate issues.
## Erroneous Behavior
- Running topgrade on Windows over SSH (cmd → pwsh) fails the Windows Update step with Get-WindowsUpdate: Access is denied. (0x80070005 (E_ACCESSDENIED)) at
src/steps/os/windows.rs:242.
- Hits after PSWindowsUpdate's Install-WindowsUpdate accepts updates and tries to download/install them.
## Expected Behavior
- Symptom-level: The Windows Update step succeeds (checks for, downloads, and installs updates) when running topgrade in an SSH session, the same as it does in a local console session. Or, if that's not feasible, it skips cleanly with a clear explanation rather than failing with E_ACCESSDENIED.
- When topgrade detects it's running in an SSH session (SSH_CLIENT/SSH_TTY set), it routes the Windows Update step through a mechanism that's compatible with non-interactive logon sessions (e.g., Invoke-WUJob scheduling Install-WindowsUpdate as a SYSTEM task), so the step succeeds.
- As best I can tell this has never worked over SSH on any topgrade version — there's no prior-working version to cite.
## Steps to reproduce
1. Ensure there is at least one pending Windows Update on the host (e.g., a Defender definition update). The bug fires during download/install, not during the search phase
2. SSH into any Windows machine with OpenSSH server enabled and PSWindowsUpdate installed as a user with administrator permissions.
3. Run topgrade --only system (or any invocation including Windows Update).
## Possible Cause (Optional)
- The Windows Update Agent COM service refuses to be driven from a non-interactive logon session. Windows OpenSSH server creates a Network logon(type 3), and the WU Agent rejects it regardless of admin rights, sudo, or elevation.
- This is environment-dependent, not a topgrade-specific bug — but topgrade currently has no branch for the SSH case.
Note: #1125 is active work in the same windows_update function (sudo-elevation fallback for non-admin users). That is a distinct root cause from this one (sudo can't grant rights vs. WU Agent COM rejecting non-interactive logons), but a fix for either would touch the same code path — worth coordinating.
## Problem persists without calling from topgrade
- [X] Yes
- [ ] No
## Ran through `Remote Execution`
- [ ] Yes
- [X] No
If yes, does the issue still occur when you run topgrade directly in your
remote host?
N/A — bug is triggered by the SSH session environment itself, independent of topgrade's Remote Execution feature.
## Configuration file (Optional)
N/A
## Additional Details
- OS: Server 2016 (10.0.14393), but root cause applies to any Windows version (10, 11, Server 2019/2022/2025) with OpenSSH server enabled.
- Installation: Chocolatey
- Topgrade version: 17.5.0 (current main as of 4de8767)
- PowerShell: pwsh 7.6.1
- Client OS: Windows 11 25H2 (for context only — the bug is server-side)
## Verbose Output (`topgrade -v`)
<details>
<pre>
PS C:\Users\Administrator> topgrade -v
DEBUG Current system locale is en-US
DEBUG Configuration at C:\Users\Administrator\AppData\Roaming\topgrade/topgrade.toml
DEBUG Loaded configuration: ConfigFile { include: None, misc: Some(Misc { allow_root: None, pre_sudo pre_sudo: None, sudo_loop:
None, sudo_loop_interval: None, sudo_command: None, disable: Some([MicrosoftStore]), first: None, last: None, ignore_failures: N
one, remote_topgrades: None, remote_topgrade_path: None, ssh_arguments: None, tmux_arguments: None, set_title: None, display_tim
e: None, assume_yes: None, ask_retry: None, auto_retry: None, no_retry: None, show_skipped: None, run_in_tmux: None, tmux_sessio
n_mode: None, cleanup: None, notify_each_step: None, skip_notify: None, notify_end: None, bashit_branch: None, only: None, no_se
lf_update: None, log_filters: None, show_distribution_summary: None, nix_handler: None }), pre_commands: None, post_commands: No
ne, commands: None, conda: None, python: None, composer: None, brew: None, linux: None, mandb: None, git: None, go: None, contai
ners: None, windows: Some(Windows { accept_all_updates: None, updates_auto_reboot: None, self_rename: Some(true), open_remotes_i
n_new_terminal: None, wsl_update_pre_release: None, wsl_update_use_web_download: None, winget_silent_install: None, winget_use_s
udo: None }), npm: None, chezmoi: None, mise: None, yarn: None, deno: None, vim: None, firmware: None, vagrant: None, flatpak: N
one, pixi: None, distrobox: None, lensfun: None, julia: None, zigup: None, vscode: None, doom: None, cargo: None, rustup: None,
pkgfile: None, viteplus: None }
DEBUG Version: 17.5.0
DEBUG OS: x86_64-pc-windows-msvc
DEBUG Args { inner: ["C:\\ProgramData\\chocolatey\\lib\\topgrade\\files\\topgrade.exe", "-v"] } "] }
DEBUG Binary path: Ok("C:\\ProgramData\\chocolatey\\lib\\topgrade\\files\\topgrade.exe")
DEBUG self-update Feature Enabled: true
DEBUG Configuration: Config { opt: CommandLineArgs { edit_config: false, show_config_reference: falsnce: false, run_in_tmux: fal
se, no_tmux: false, cleanup: false, dry_run: false, run_type: Wet, no_retry: false, no_ask_retry: false, auto_retry: None, disab
le: [], only: [], custom_commands: [], env: [], verbose: true, keep_at_end: false, skip_notify: false, notify_end: Always, yes:
None, disable_predefined_git_repos: false, config: None, remote_host_limit: None, show_skipped: false, allow_root: false, sudo_l
oop: false, sudo_loop_interval: None, log_filter: "warn", gen_completion: None, gen_manpage: false, no_self_update: false }, con
fig_file: ConfigFile { include: None, misc: Some(Misc { allow_root: None, pre_sudo: None, sudo_loop: None, sudo_loop_interval: N
one, sudo_command: None, disable: Some([MicrosoftStore]), first: None, last: None, ignore_failures: None, remote_topgrades: None
, remote_topgrade_path: None, ssh_arguments: None, tmux_arguments: None, set_title: None, display_time: None, assume_yes: None,
ask_retry: None, auto_retry: None, no_retry: None, show_skipped: None, run_in_tmux: None, tmux_session_mode: None, cleanup: None
, notify_each_step: None, skip_notify: None, notify_end: None, bashit_branch: None, only: None, no_self_update: None, log_filter
s: None, show_distribution_summary: None, nix_handler: None }), pre_commands: None, post_commands: None, commands: None, conda:
None, python: None, composer: None, brew: None, linux: None, mandb: None, git: None, go: None, containers: None, windows: Some(W
indows { accept_all_updates: None, updates_auto_reboot: None, self_rename: Some(true), open_remotes_in_new_terminal: None, wsl_u
pdate_pre_release: None, wsl_update_use_web_download: None, winget_silent_install: None, winget_use_sudo: None }), npm: None, ch
ezmoi: None, mise: None, yarn: None, deno: None, vim: None, firmware: None, vagrant: None, flatpak: None, pixi: None, distrobox:
None, lensfun: None, julia: None, zigup: None, vscode: None, doom: None, cargo: None, rustup: None, pkgfile: None, viteplus: No
ne }, allowed_steps: [AM, AndroidStudio, Antigravity, AppMan, Aqua, Asdf, Atom, Atuin, Audit, AutoCpufreq, Bin, Bob, BrewCask, B
rewFormula, Bun, BunPackages, Cargo, Certbot, Chezmoi, Chocolatey, Choosenim, CinnamonSpices, ClamAvDb, ClaudeCode, Colima, Comp
oser, Conda, ConfigUpdate, Containers, Cursor, CustomCommands, DebGet, Deno, Distrobox, DkpPacman, Dotnet, Elan, Emacs, Falconf,
Firmware, Flatpak, Flutter, Fossil, Gcloud, Gearlever, Gem, Getnf, Ghcup, GitRepos, GithubCliExtensions, GnomeShellExtensions,
Go, Guix, Haxelib, Helix, HelixDb, Helm, HomeManager, Hyprpm, InstallRelease, JetbrainsAqua, JetbrainsClion, JetbrainsDatagrip,
JetbrainsDataspell, JetbrainsGateway, JetbrainsGoland, JetbrainsIdea, JetbrainsMps, JetbrainsPhpstorm, JetbrainsPycharm, Jetbrai
nsRider, JetbrainsRubymine, JetbrainsRustrover, JetbrainsToolbox, JetbrainsWebstorm, Jetpack, Julia, Juliaup, Kakoune, Krew, Len
sfun, Lure, Macports, Mamba, Mandb, Mas, Maza, Micro, MicrosoftOffice, Miktex, Mise, Myrepos, Nix, Node, Ollama, Opam, Pacdef, P
acstall, Pearl, Pi, Pip3, PipReview, PipReviewLocal, Pipupgrade, Pipx, Pipxu, Pixi, Pkg, Pkgfile, Pkgin, PlatformioCore, Pnpm, P
oetry, Powershell, Protonplus, Protonup, Pyenv, Raco, Rcm, Remotes, Restarts, Rtcl, RubyGems, Rustup, Rye, Scoop, Sdkman, SelfUp
date, Sheldon, Shell, Skills, Snap, Sparkle, Spicetify, Stack, Stew, System, Tldr, Tlmgr, Tmux, Toolbx, Tpack, Typst, Uv, Vagran
t, Vcpkg, Vim, VitePlus, VoltaPackages, Vscode, VscodeInsiders, Vscodium, VscodiumInsiders, Waydroid, Windsurf, Winget, Wsl, Wsl
Update, Xcodes, Yadm, Yarn, Yazi, Zigup, Zvm] }
DEBUG Detected elevated process
DEBUG Sudo: Ok(Sudo { path: None, kind: Null })
DEBUG Step "Self Update"
<!-- TRUNCATED IRRELEVANT OUTPUT TO SAVE SPACE AND MAKE IT MORE READABLE -->
── 20:35:11 - Windows Update ───────────────────────────────────────────────────
DEBUG Executing command `C:\Program Files\PowerShell\7\pwsh.exe -NoProfile -Command 'Get-Module -ListAvailable PSWindowsUpdate'`
DEBUG Executing command `C:\Program Files\PowerShell\7\pwsh.exe -NoProfile -Command Get-ExecutionPolicy`
DEBUG Found PowerShell ExecutionPolicy: Ok("RemoteSigned")
DEBUG Executing command `C:\Program Files\PowerShell\7\pwsh.exe -NoProfile -Command 'Import-Module PSWindowsUpdate; Install-Wind
owsUpdate -Verbose -AcceptAll -IgnoreReboot'`
VERBOSE: MATRIX (5/15/2026 8:35:14 PM): Connecting to Microsoft Update server. Please wait...
VERBOSE: Found [1] Updates in pre search criteria
VERBOSE: Found [1] Updates in post search criteria
X ComputerName Result KB Size Title
- ------------ ------ -- ---- -----
1 MATRIX Accepted KB2267602 1GB Security Intelligence Update for Microsoft Defender Antivirus - KB2267602 (Version …
VERBOSE: Accepted [1] Updates ready to Download
Get-WindowsUpdate: Access is denied. (0x80070005 (E_ACCESSDENIED))
DEBUG Command failed: Err(
0: \x1b[91mCommand failed: `C:\Program Files\PowerShell\7\pwsh.exe -NoProfile -Command 'Import-Module PSWindowsUpdate; Instal
l-WindowsUpdate -Verbose -AcceptAll -IgnoreReboot'`\x1b[0m
1: \x1b[91m`C:\Program Files\PowerShell\7\pwsh.exe` failed: exit code: 1\x1b[0m
Location:
\x1b[35msrc\steps\os\windows.rs\x1b[0m:\x1b[35m242\x1b[0m)
DEBUG Step "Windows update" failed:
0: \x1b[91mCommand failed: `C:\Program Files\PowerShell\7\pwsh.exe -NoProfile -Command 'Import-Module PSWindowsUpdate; Instal
l-WindowsUpdate -Verbose -AcceptAll -IgnoreReboot'`\x1b[0m
1: \x1b[91m`C:\Program Files\PowerShell\7\pwsh.exe` failed: exit code: 1\x1b[0m
Location:
\x1b[35msrc\steps\os\windows.rs\x1b[0m:\x1b[35m242\x1b[0m
Windows update failed:
0: Command failed: `C:\Program Files\PowerShell\7\pwsh.exe -NoProfile -Command 'Import-Module PSWindowsUpdate; Install-Window
sUpdate -Verbose -AcceptAll -IgnoreReboot'`
1: `C:\Program Files\PowerShell\7\pwsh.exe` failed: exit code: 1
Location:
src\steps\os\windows.rs:242
Retry? (y)es/(N)o/(s)hell/(q)uit
DEBUG Interrupted (possibly with 'q' during retry prompt). Printing summary.
</pre>
</details>
0 条评论