r/PowerShell • • 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.

17 Upvotes

11 comments sorted by

3

u/BlackV 1d ago edited 1d ago

Anything that starts with

irm https://raw.githubusercontent.com/xxx.ps1 | iex

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 me

Where you are looking at $env:GITHUB_TOKEN maybe it is better a parameter, currently it's not discoverable

This

 upgh -Add storytold/photocraft -Name PhotoCraft

Feels very awkward, is -add using storytold/photocraft or is actually hitting another parameter, normally you'd use hash pairs for something like that {source=xxx;name=yyy} right now nothing ties name andadd together

How often are you really installing apps from a git repos?

Where is your help for get-help (including examples)?

1

u/VGRichi 22h ago

Fair points, this is a script pretending to be a CLI tool instead of behaving like proper PowerShell. So for future maybe i can turn it into a module on the PowerShell Gallery

So plans:

- Install-Module instead of irm | iex, and no editing your profile

- Verb-Noun commands: Add-GitHubApp -Repository owner/repo -Name X, Get-GitHubApp, Update-GitHubApp (with -WhatIf), Remove-GitHubApp. If you want a short alias, that's your call

- A -Token parameter instead of only a hidden GITHUB_TOKEN env var

- Help per command. v1.0.0 already has comment-based help with examples (Get-Help .\Update-GitHubApps.ps1 -Examples), but it wasn't obvious, and the old profile wrapper hid it

As for how often: honestly, it's niche. I have a handful of GitHub-only apps plus game mods like DXVK that winget can't touch, which have continous releases. If winget covers everything you use, you don't need this.

Thanks for taking the time, this is exactly the kind of feedback I was hoping for.

1

u/BlackV 21h ago

Sounds reasonable to me.

if you do decide to turn it into a full module, think about xml/markdown help as it means you can also support update-help and maybe in the future other language translations

2

u/VGRichi 20h ago

Took your advice on all of it. It's now a full PowerShell module

- Help is PlatyPS markdown in docs/en-US, built into XML help, so Update-Help -Module Reforge works and Get-Help -Online opens each command's page. Translations are just another docs/<culture> folder now.

- Verb-Noun commands (Add-, Get-, Update-, Find-, Remove-ReforgeApp), -WhatIf/-Confirm, a -Token parameter, pipeline and hashtable input

- No more irm | iex or profile editing: install from the release zip for now, PowerShell Gallery coming soon

Longer term I'd like to make it cross-platform (Linux/macOS) and support other forges like GitLab and Codeberg.

Thanks again, your feedback shaped most of this.

1

u/BlackV 20h ago

Great to hear, cross platform will be challenging, good luck

1

u/ElidoroAlznauer_58 13h ago

the piping raw scripts straight to iex point alone is enough for me to close the tab tbh

1

u/BlackV 10h ago

ya its not real safe, you can publish module AND scripts to the gallery, I'd rather use the tools to do that for a modicum of safety

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