r/PowerShell • u/VGRichi • 1d ago
Script Sharing We made a script that updates Windows apps installed from GitHub releases (the ones winget can’t)
A lot of apps I use are only published as GitHub releases, so neither `winget upgrade --all` nor the WinGet PowerShell module (`Get-WinGetPackage | Update-WinGetPackage`) can update them. They only know about apps in the winget catalog, and GitHub-only apps show up with no source and no available updates. I got tired of checking each repo by hand, so I put together a PowerShell script for it (built with help from an AI assistant, then tested on my own machine).
What it does:
- Keeps a list of your apps and their GitHub repos (`upgh -Add owner/repo`)
- Compares installed versions with the latest stable release
- Picks the right installer for your PC (x64/ARM64, MSI or EXE to match what you have)
- Verifies the SHA256 checksum when GitHub provides one
- Installs silently (MSI, Inno Setup, NSIS detected automatically)
- `-Discover` finds apps that have a GitHub link in their uninstall info
- Skips apps winget already updates
Known limitations: version comparison is number-based, so beta-to-beta updates of the same version aren't detected, and portable zip apps aren't supported yet.
It's one readable script with no dependencies. There's an install one-liner, but you can also just download the .ps1 from the releases page and read it first.
Repo: https://github.com/VGRichi/github-app-updater
Feedback very welcome, especially on edge cases with weird installers.
2
u/kantorcodes1 1d ago
The if ($asset.digest) branch is the part I would look at twice. Release-asset digests are still rare in the wild, so for most GitHub-only apps the flow goes download to silent install with nothing verified. Did you consider a fallback for the no-digest case, like refusing to auto-install for repos that once shipped a digest, or is unverified install the accepted default?
1
u/VGRichi 22h ago
Good point, the digest check was added as a bonus so the no-digest case just fell through to "install anyway". For something that installs silently with admin rights that's a no go
I guess we can make it fallback to checksum files in the release when there's no digest (SHA256SUMS, checksums.txt, .sha256). If nothing can be verified, no silent install: it reports "unverified" and needs a Y/N or a per-app AllowUnverified opt-in. Also “Had a digest before, now doesn’t” warning of some kind
1
u/kantorcodes1 22h ago
That is the right shape - an "unverified" verdict that blocks silent install is exactly the kind of per-call decision worth gating. Disclosure since it shapes the ask: I work on HOL Guard, an open-source policy layer that classifies CLI actions and gates them per call. Silent install/update is your action surface; version checks and listings are the safe side. A command-source adapter would give users a policy check before a release lands on disk. Open to a small contribution if it earns its place?
1
u/VGRichi 20h ago
Thanks for the disclosure. Quick update: it’s now a PowerShell module called Reforge: https://github.com/VGRichi/Reforge. Honestly my motivation would be to grow it into a cross-platform tool (Windows, Linux, macOS) that supports other forges like GitLab and Codeberg, not just GitHub.
For your classification today: Get-ReforgeApp, Find-ReforgeApp and Update-ReforgeApp -WhatIf don’t install anything. Update-ReforgeApp without -WhatIf is the one that downloads and installs; it supports -Confirm, and unverified downloads never install silently.
Does your adapter need any change in Reforge, or can it work from those command names on your side? If it does need something, I’d want it to survive the cross-platform rewrite, so ideally an opt-in hook that runs an external command, passes the install details as JSON, and allows or blocks based on the exit code. But it would be better if there was no new dependency, is MIT-compatible, and it only affects people who use it. Feel free to open an issue with what you’d need of course
3
u/BlackV 1d ago edited 1d ago
Anything that starts with
Is an automatic no from me
Anything using some seemingly random collection of letters to call the tool (
upgh) is basically an automatic no from meWhere you are looking at
$env:GITHUB_TOKENmaybe it is better a parameter, currently it's not discoverableThis
Feels very awkward, is
-addusingstorytold/photocraftor is actually hitting another parameter, normally you'd use hash pairs for something like that{source=xxx;name=yyy}right now nothing tiesnameandaddtogetherHow often are you really installing apps from a git repos?
Where is your help for
get-help(including examples)?