prinstall · docs
Every command, every flag, on one page. Each subcommand has its own --help with examples.
Install
# Download the default build (includes SDI Tier 5, Authenticode-verified)
iwr https://github.com/limehawk/prinstall/releases/latest/download/prinstall.exe -OutFile prinstall.exe
# Or download the lean build (no SDI; Tiers 1–4 + IPP fallback)
iwr https://github.com/limehawk/prinstall/releases/latest/download/prinstall-nosdi.exe -OutFile prinstall.exe
# Optional one-shot install: the command below copies the exe into
# C:\ProgramData\prinstall\, adds that dir to Machine PATH, and opens
# UDP 5353 in Windows Firewall (needed for mDNS discovery). Idempotent.
.\prinstall.exe setup install
RMM scripts
PowerShell wrappers around each prinstall command — structured stdout, exit codes for RMM dispatch, README headers inline. Drop into any RMM that runs PS scripts. Source: limehawk/rmm-scripts. Click to expand and copy.
prinstall_setup.ps1— bootstrap a box: download prinstall.exe, install to C:\ProgramData\prinstall\, add to PATH, open UDP 5353
prinstall_scan.ps1— multi-method subnet scan (TCP + IPP + SNMP + mDNS)
prinstall_id.ps1— SNMP query one host: model, serial, status
prinstall_add.ps1— install a network or USB printer via the full pipeline cascade
prinstall_remove.ps1— remove queue + orphan driver + orphan port, idempotent
prinstall_list.ps1— enumerate every printer queue on the box
prinstall_driver_add.ps1— stage a driver into the Windows driver store
prinstall_driver_remove.ps1— unstage a driver; --force cascades dependent queues
prinstall_driver_list.ps1— list every driver in the Windows driver store
prinstall_drivers.ps1— show ranked driver-match candidates for a printer IP
prinstall_trust_codesign.ps1— push the limehawk self-signed cert to the box's TrustedPublisher store (fleet trust rollout)
Commands
| Command | Flags | Effect | Admin |
| prinstall | --subnet | Launch the interactive TUI | no |
| prinstall scan [SUBNET] | --method (all|snmp|port|mdns), --timeout, --network-only, --usb-only | Multi-method subnet probe + USB enum. Auto-detects subnet from NIC. /24+ needs --force. | no |
| prinstall id <ip> | --community | SNMP query one host. Description, serial, status. 2 s timeout. | no |
| prinstall add <target> | --driver, --name, --model, --usb, --no-sdi, --no-catalog, --sdi-fetch, --no-verify | Walks the 6-tier driver pipeline. Network: ID → match → stage → install. USB: queue name target, hot-swap via Set-Printer. | yes |
| prinstall remove <target> | --keep-driver, --keep-port | Queue → driver (if orphaned) → port (if orphaned). Idempotent. Target can be IP or queue name. | yes |
| prinstall list | --verbose | Enumerate every queue Windows knows. Name, driver, port, IP, source. | no |
| prinstall driver add <path|model> | --driver, --no-verify | Stage from INF file, INF folder, or model string. Auto-picks unambiguous matches. | yes |
| prinstall driver remove <name|fuzzy> | --force | Unstage from driver store. Refuses if bound to a queue. --force cascades dependent queues. System drivers protected. | yes |
| prinstall driver list | | Every staged driver — manufacturer, version, date. | no |
| prinstall driver show <ip> | --model | Ranked match candidates for a printer. ★ exact / ● fuzzy / ○ low. | no |
| prinstall sdi status | | Cache contents, total size, mirror URL. | no |
| prinstall sdi refresh | | Pull latest index files (~1 MB). | no |
| prinstall sdi prefetch | | Download all printer driver packs (~1.5 GB, one time). | no |
| prinstall sdi verify | | Authenticode-check every cached .cat. | no |
| prinstall sdi list | | List cached indexes + packs. | no |
| prinstall sdi clean | | LRU-evict past the size budget. | no |
| prinstall setup install | --dir | Self-installs: copies the running exe to C:\ProgramData\prinstall\, adds that dir to Machine PATH, opens UDP 5353 in Windows Firewall. | yes |
| prinstall setup uninstall | --dir | Removes the install dir, PATH entry, and firewall rule. Idempotent. | yes |
| prinstall version | | Alias for --version. | no |
Global flags
| --json | Machine-readable JSON output |
| --verbose, -v | Raw PS commands + structured report |
| --community <str> | SNMP community (default: public) |
| --force | Permit /24+ scans, skip add fail-fast, cascade driver remove |
| --subnet <cidr> | Override auto-detected subnet for TUI |
TUI keys
| j / k | Move up / down |
| h / l | Focus prev / next panel |
| Tab | Cycle panel focus |
| g / G | Top / bottom |
| Enter | Select / install |
| Esc | Back / close overlay |
| s | Rescan |
| ? | Help overlay |
| q | Quit |
Driver pipeline
| Tier 1 | Local driver store — reuse what's installed |
| Tier 2 | Local bundle — drivers dropped next to exe |
| Tier 3 | Vendor download — HP, Xerox, Kyocera direct URLs |
| Tier 4 | Update Catalog + INF HWID match |
| Tier 5 | SDI Origin — verified .cat required |
| Tier 6 | IPP Class Driver — always-works fallback |
Files
| C:\ProgramData\prinstall\ | Data root |
| …\drivers\ | Bundle dir (Tier 2 fallback) |
| …\staging\ | Downloaded driver staging area |
| …\sdi\ | SDI cache (indexes + driver packs) |
| …\config.toml | Persistent config |
| …\history.toml | Install audit log |
Environment
| PRINSTALL_BUNDLE_DIR | Override the Tier 2 bundle directory |
| NO_COLOR | Suppress ANSI color |
Exit status
| 0 | Success |
| 1 | Failure — detail on stderr, full payload via --json |
| 2 | Invalid arguments |
Examples — scan
# Auto-detect subnet from NIC, run every method in parallel
prinstall scan
# Scan a specific subnet
prinstall scan 192.168.1.0/24
prinstall scan 10.0.0.0/24 --community private
# Single-method probes (faster when you know the network)
prinstall scan --method snmp
prinstall scan --method port # TCP 9100 only
prinstall scan --method mdns # multicast browse, no subnet needed
# Tune timing
prinstall scan --timeout 200 # 200 ms per-host
prinstall scan --timeout 2000 # slower network, longer wait
# Network vs USB isolation
prinstall scan --network-only # skip USB enumeration
prinstall scan --usb-only # skip network, USB only
# Wide scan (requires --force above /24)
prinstall scan 10.0.0.0/16 --force
# JSON for RMM
prinstall scan --json | ConvertFrom-Json | Where-Object { $_.model -like "HP*" }
Examples — id
# Identify one host via SNMP
prinstall id 192.168.1.100
prinstall id 10.0.0.50 --community private
# JSON shape: { ip, model, serial, status, manufacturer }
prinstall id 192.168.1.100 --json
Examples — add (network)
# Full pipeline cascade — discovers driver automatically
prinstall add 192.168.1.100
# Pick the driver yourself
prinstall add 192.168.1.100 --driver "HP Universal Print Driver PCL6"
# Override the auto-detected display name
prinstall add 192.168.1.100 --name "Front Desk Printer"
# Bypass SNMP — supply the model directly
prinstall add 192.168.1.100 --model "HP LaserJet Pro M404dn"
# Skip specific tiers for this run
prinstall add 192.168.1.100 --no-sdi # skip Tier 5
prinstall add 192.168.1.100 --no-catalog # skip Tier 4
prinstall add 192.168.1.100 --no-sdi --no-catalog
# First-run SDI fetch — allow auto-pick to pull a 1.5 GB pack
prinstall add 192.168.1.100 --sdi-fetch
# Skip Authenticode verification (vendor packs that legitimately ship unsigned)
prinstall add 192.168.1.100 --no-verify
# Verbose audit trail — raw PS commands + structured report
prinstall add 192.168.1.100 --verbose
# JSON for RMM
prinstall add 192.168.1.100 --json
Examples — add (USB)
# Swap driver on an existing USB queue (target is the queue name, not an IP)
prinstall add "Brother MFC-L2750DW" --usb
# With a specific driver
prinstall add "HP OfficeJet Pro" --usb --driver "HP Universal PCL6"
# Override the model string (when the queue name is wrong)
prinstall add "Generic / Text Only" --usb --model "Brother HL-L2370DW"
Examples — remove
# Full cleanup by IP — port name resolves via IP_<ip> convention
prinstall remove 192.168.1.100
# By queue name
prinstall remove "HP LaserJet Pro"
# Keep the driver in the store (e.g. you'll re-add the same printer later)
prinstall remove 192.168.1.100 --keep-driver
# Keep both driver and port — queue removal only
prinstall remove 192.168.1.100 --keep-driver --keep-port
# Idempotent — succeeds even if the printer doesn't exist
prinstall remove 192.168.1.999
Examples — list
# Every queue Windows knows about
prinstall list
# JSON for scripting
prinstall list --json
prinstall list --json | ConvertFrom-Json | Where-Object { $_.source -eq "network" }
# Raw Get-Printer output for debugging
prinstall list --verbose
Examples — driver add
# Stage from an extracted INF folder
prinstall driver add C:\Drivers\HP_LaserJet_1320
# Stage from a single INF file
prinstall driver add C:\Drivers\brother.inf
# Stage by model string — auto-resolves curated matches
prinstall driver add "HP LaserJet 1320"
prinstall driver add "HP Universal Print Driver PS"
# Multiple candidates? Pick one explicitly
prinstall driver add "HP LaserJet" --driver "HP Universal Print Driver PCL6"
# Skip Authenticode (only for unsigned-but-legitimate vendor packs)
prinstall driver add C:\Drivers\legacy_brother --no-verify
Examples — driver remove
# Exact driver name
prinstall driver remove "HP Universal Print Driver PCL6"
# Fuzzy match (resolves to one staged driver)
prinstall driver remove "hp 1320"
# Cascade — remove dependent queues first, then the driver
prinstall driver remove "Brother MFC" --force
# System drivers are protected — this is a no-op
prinstall driver remove "Microsoft IPP Class Driver"
Examples — driver list / show
# Every staged driver — no admin required
prinstall driver list
prinstall driver list --json
# Ranked match candidates for a printer (★ exact / ● fuzzy / ○ low)
prinstall driver show 192.168.1.100
# Bypass SNMP — use a specified model
prinstall driver show 192.168.1.100 --model "HP LaserJet Pro MFP M428fdw"
# Inspect match scores in JSON
prinstall driver show 192.168.1.100 --json
Examples — sdi
# First-time setup on a freshly-deployed box
prinstall sdi refresh # pull index files (~1 MB)
prinstall sdi prefetch # download all printer packs (~1.5 GB, one time)
# Inspect what's cached
prinstall sdi status
prinstall sdi list
prinstall sdi list --json
# Verify every cached pack's .cat signature against Microsoft's chain
prinstall sdi verify
# Trim cache past the size budget (LRU eviction)
prinstall sdi clean
Examples — setup
# Bootstrap: this command copies the running exe to C:\ProgramData\prinstall\,
# adds that dir to Machine PATH, and creates a Windows Firewall rule for UDP 5353.
.\prinstall.exe setup install
# Same, but installs to a custom location
.\prinstall.exe setup install --dir C:\Tools\prinstall
# Reverses all three (removes install dir, PATH entry, firewall rule).
# Run from a copy outside the install dir so the file lock doesn't block removal.
prinstall setup uninstall
prinstall setup uninstall --dir C:\Tools\prinstall
Examples — install from a local driver bundle (Tier 2)
# Layout — drop extracted vendor packs in a drivers\ folder next to the exe
# (one subfolder per pack, each with the extracted INF + payload + .cat)
C:\Tools\prinstall\
├── prinstall.exe
└── drivers\
├── hp-laserjet-m404\
│ ├── hppcl6.inf
│ ├── hppcl6.cat
│ └── ...
├── brother-mfc-l2750dw\
│ ├── brimg18a.inf
│ ├── brimg18a.cat
│ └── ...
└── kyocera-ecosys-m5526\
├── oemsetup.inf
├── oemsetup.cat
└── ...
# Confirm prinstall sees the bundle and a printer matches before installing
prinstall driver show 192.168.1.47
# → ranked candidates with "source: bundle" for matches from drivers\
# Install — pipeline auto-picks the bundle match (Tier 2 before catalog/SDI)
prinstall add 192.168.1.47
# Override the bundle dir without moving files
$env:PRINSTALL_BUNDLE_DIR = "D:\msp-drivers"
prinstall add 192.168.1.47
# System-wide fallback path (no env var, no adjacent folder needed)
# C:\ProgramData\prinstall\drivers\hp-laserjet-m404\...
# Resolution order — first directory with a matching INF wins:
# 1. $env:PRINSTALL_BUNDLE_DIR
# 2. drivers\ adjacent to prinstall.exe
# 3. C:\ProgramData\prinstall\drivers\
# Pre-stage a bundled driver into the Windows driver store (without installing
# a printer yet — useful right before a PnP event fires)
prinstall driver add C:\Tools\prinstall\drivers\hp-laserjet-m404
# Force a specific bundle driver onto a printer (bypass auto-match)
prinstall add 192.168.1.47 --driver "HP Universal Printing PCL 6"
# Skip Authenticode for legitimately-unsigned vendor packs (rare; .cat absent)
prinstall add 192.168.1.47 --no-verify
# Verify what the bundle tier would pick, in JSON
prinstall driver show 192.168.1.47 --json | ConvertFrom-Json |
Where-Object { $_.source -eq "bundle" }
Examples — pipelines
# RMM: install + capture JSON result
$result = .\prinstall.exe add 10.0.0.50 --json | ConvertFrom-Json
if ($result.success) { Write-Host "Installed: $($result.detail.queue)" }
# Batch install — loop over scan results
prinstall scan --json | ConvertFrom-Json | ForEach-Object {
prinstall add $_.ip --json
}
# RMM remote shell — no color, JSON only
$env:NO_COLOR = "1"
.\prinstall.exe scan --json