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
Loading…

View on GitHub

prinstall_scan.ps1— multi-method subnet scan (TCP + IPP + SNMP + mDNS)
Loading…

View on GitHub

prinstall_id.ps1— SNMP query one host: model, serial, status
Loading…

View on GitHub

prinstall_add.ps1— install a network or USB printer via the full pipeline cascade
Loading…

View on GitHub

prinstall_remove.ps1— remove queue + orphan driver + orphan port, idempotent
Loading…

View on GitHub

prinstall_list.ps1— enumerate every printer queue on the box
Loading…

View on GitHub

prinstall_driver_add.ps1— stage a driver into the Windows driver store
Loading…

View on GitHub

prinstall_driver_remove.ps1— unstage a driver; --force cascades dependent queues
Loading…

View on GitHub

prinstall_driver_list.ps1— list every driver in the Windows driver store
Loading…

View on GitHub

prinstall_drivers.ps1— show ranked driver-match candidates for a printer IP
Loading…

View on GitHub

prinstall_trust_codesign.ps1— push the limehawk self-signed cert to the box's TrustedPublisher store (fleet trust rollout)
Loading…

View on GitHub

Commands

CommandFlagsEffectAdmin
prinstall--subnetLaunch the interactive TUIno
prinstall scan [SUBNET]--method (all|snmp|port|mdns), --timeout, --network-only, --usb-onlyMulti-method subnet probe + USB enum. Auto-detects subnet from NIC. /24+ needs --force.no
prinstall id <ip>--communitySNMP query one host. Description, serial, status. 2 s timeout.no
prinstall add <target>--driver, --name, --model, --usb, --no-sdi, --no-catalog, --sdi-fetch, --no-verifyWalks 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-portQueue → driver (if orphaned) → port (if orphaned). Idempotent. Target can be IP or queue name.yes
prinstall list--verboseEnumerate every queue Windows knows. Name, driver, port, IP, source.no
prinstall driver add <path|model>--driver, --no-verifyStage from INF file, INF folder, or model string. Auto-picks unambiguous matches.yes
prinstall driver remove <name|fuzzy>--forceUnstage from driver store. Refuses if bound to a queue. --force cascades dependent queues. System drivers protected.yes
prinstall driver listEvery staged driver — manufacturer, version, date.no
prinstall driver show <ip>--modelRanked match candidates for a printer. ★ exact / ● fuzzy / ○ low.no
prinstall sdi statusCache contents, total size, mirror URL.no
prinstall sdi refreshPull latest index files (~1 MB).no
prinstall sdi prefetchDownload all printer driver packs (~1.5 GB, one time).no
prinstall sdi verifyAuthenticode-check every cached .cat.no
prinstall sdi listList cached indexes + packs.no
prinstall sdi cleanLRU-evict past the size budget.no
prinstall setup install--dirSelf-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--dirRemoves the install dir, PATH entry, and firewall rule. Idempotent.yes
prinstall versionAlias for --version.no

Global flags

--jsonMachine-readable JSON output
--verbose, -vRaw PS commands + structured report
--community <str>SNMP community (default: public)
--forcePermit /24+ scans, skip add fail-fast, cascade driver remove
--subnet <cidr>Override auto-detected subnet for TUI

TUI keys

j / kMove up / down
h / lFocus prev / next panel
TabCycle panel focus
g / GTop / bottom
EnterSelect / install
EscBack / close overlay
sRescan
?Help overlay
qQuit

Driver pipeline

Tier 1Local driver store — reuse what's installed
Tier 2Local bundle — drivers dropped next to exe
Tier 3Vendor download — HP, Xerox, Kyocera direct URLs
Tier 4Update Catalog + INF HWID match
Tier 5SDI Origin — verified .cat required
Tier 6IPP 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.tomlPersistent config
…\history.tomlInstall audit log

Environment

PRINSTALL_BUNDLE_DIROverride the Tier 2 bundle directory
NO_COLORSuppress ANSI color

Exit status

0Success
1Failure — detail on stderr, full payload via --json
2Invalid 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