IronShell is a self-hosted flask-waitress server for distributing Windows applications via PowerShell one-liners. It dynamically generates PowerShell installer scripts for your apps, supporting version selection, custom install folders, and user-friendly display names.
Still in development, but it simplifies install proccess of my apps.
yeah thats a lie, i didnt even start it.
-
App descriptions and hyperlinks
-
Force remove installation folder on uninstall or config value to configure what should be deleted aswell (with * meaninng force entire folder removal)
-
Create shortcuts on install
-
Non-binary apps support (.py script with wrappers etc., additional subscripts for checking machine env. like installed python etc.) | 25% done (via autorun prefix, left to do: env checking, dependencies, run helpers, winget integration? etc.)
-
Env dependencies (set dependencies like powershell and python and use error syntax in powershell to detect if binary responded)
-
Env presets? (e.g. in config you set preset: "python_env" and with the install it includes minimalistic python install or smth)
- Custom Pufferpanel template
- Autoupdate server (install/uninstall scripts) on boot. (pufferpannel only? preboot script)
- Linux Support/Port with .sh scripts or krwutils only port.
- Serve PowerShell install scripts for any app hosted on GitHub
- Supports custom binary names, install folders, and display names
- Flexible version selection (latest, oldest, specific, wildcards, etc.)
- Easy to extend: just edit
config.json
/list
endpoint for discoverability
- Python 3.7+ // Tho i recommend 3.11
- flask // For Server framework
- waitress // For WSGI part of the server
- requests // For Retriving GitHub page to scrape
- beautifulsoup4 // For scraping version tags
-
Clone this repo and
cd
into it. -
Edit
config.json
to add your apps. -
Run the server:
python server.py
-
From a Windows machine, install an app with:
iwr http://yourserver/install/appname | iex
Or list available apps:
iwr http://yourserver/list | iex
Want to use a custom domain instead of an IP address? Or just general help with setting this project up?
See the generalSetup.md guide for setup instructions.
-
To install the latest version of
SASM
from Nuitka builds:iwr https://utils.krwclassic.com/install/sasm-nuitka | iex
-
To see all available apps:
iwr https://utils.krwclassic.com/list | iex
The server uses a config.json
file to define which apps are available for installation and how their installers are generated.
{
"apps": {
"endpoint-name": {
"owner": "GitHubOwner", // (required) GitHub username or organization
"repo": "RepositoryName", // (required) GitHub repository name
"binary": "binary.exe", // (required) Name of the binary to download from the release/tag
"version": "latest", // (optional) Version/tag selection rule (see below)
"name": "Display Name", // (optional) User-friendly name for display in the installer (defaults to repo)
"folder": "installfolder", // (optional) Folder name for installation (defaults to repo)
"autorun": false, // (optional) Autorun app after install (default: false)
"autorunPrefix": "", // (optional) Prefix for autorun command (e.g. "cmd /k", "python -m")
"autorunArguments": "", // (optional) Arguments for autorun command
"postInstallMessage": "", // (optional) Message shown after install, before 'press any key'
"postUninstallMessage": "" // (optional) Message shown after uninstall, before 'press any key'
},
// ... more apps ...
}
}
- endpoint-name: The name used in the URL, e.g.
/install/weget
. - owner: The GitHub username or organization that owns the repository.
- repo: The repository name on GitHub.
- binary: The name of the binary file to download from the release/tag assets.
- version: (Optional) Controls which tag to use for the download. Supports:
"latest"
— The newest tag (default)"latest-N"
— The Nth latest tag (e.g.,latest-1
is the previous tag)"first"
— The oldest tag"first+"
— The Nth oldest tag (e.g.,first+1
is the second oldest tag)"<tag>"
— A specific tag name- Wildcards:
"*-Nuitka"
,"?.?.?-Nuitka"
— Uses the first tag matching the pattern (shell-style wildcards)
- name: (Optional) User-friendly display name for the app, shown in the PowerShell output. Defaults to the repo name if not set.
- folder: (Optional) The folder name under
%APPDATA%\<owner>\<folder>
where the app will be installed. Defaults to the repo name if not set. - autorun: (Optional, default: false) If true, the app will be run automatically after installation completes.
- autorunPrefix: (Optional) If set, this prefix will be prepended to the autorun command (e.g.
python -m
,cmd /k
). If set, the autorun command will be launched in a new PowerShell window. *see Notes and Autorun Behavior for more info - autorunArguments: (Optional) Arguments to pass to the autorun command (e.g.
--help
). - postInstallMessage: (Optional) If set, this message will be shown after installation completes.
- postUninstallMessage: (Optional) If set, this message will be shown after uninstallation completes.
{
"apps": {
"sasm-nuitka": {
"owner": "KRWCLASSIC",
"repo": "Steam-Account-Switcher-Manager",
"binary": "sasm.exe",
"version": "*-Nuitka",
"name": "SASM",
"folder": "steamaccountswitchermanager",
"autorun": false,
"autorunPrefix": "",
"autorunArguments": "",
"postInstallMessage": "SASM installed! Enjoy switching your Steam accounts.",
"postUninstallMessage": "SASM has been removed. Come back soon!"
},
"my-python-app": {
"owner": "me",
"repo": "my-python-repo",
"binary": "myscript.py",
"version": "latest",
"name": "MyPythonApp",
"folder": "mypythonapp",
"autorun": true,
"autorunPrefix": "python -m",
"autorunArguments": "--help",
"autorunArguments": "",
"postInstallMessage": "",
"postUninstallMessage": ""
}
}
}
If autorun
is set to true, the installer will automatically run the app after installation:
- If
autorunPrefix
is set (e.g.python
,cmd /k
), the command will be launched in a new PowerShell window so apps dont collide with execution of the installer. *see Notes for more info - If
autorunPrefix
is not set, the binary will be run directly in the current session. autorunArguments
are appended to the command.
Examples:
-
Run a CLI app and keep the window open:
"autorun": true, "autorunPrefix": "cmd /k", "autorunArguments": ""
-
Run a Python script:
"autorun": true, "autorunPrefix": "python -m", "autorunArguments": "--help"
- You can set
autorunPrefix
to" "
to run the app in new window without any actual prefix. - The
owner
,repo
, andbinary
fields are required for each app. Other fields have default values if not specified. - The
version
field in config supports wildcards (*
,?
) for flexible tag selection. - The
name
field is used for all user-facing output in the PowerShell installer. - The
folder
field controls the install directory name; use it to match the folder your app creates or expects. - The endpoint name (e.g.,
weget
) is what users will use in the install URL:iwr http://yourserver/install/weget | iex
This project is licensed under KRW LICENSE v1
Free for non-commercial use and public forks.
💬 Contact me even for personal uses — I might feature your project!
📬 classic.krw@gmail.com • Discord: @krwclassic