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
prinstallPrint the CLI command listno
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 initCreate drivers\ next to this exe. Drop extracted vendor packs there. Sibling folders are not scanned.no
prinstall driver add <path|url|model>--driver, --no-verifyStage from INF file, INF folder, http(s) URL (zip/cab/7z/exe), 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

Driver pipeline

Tier 1Local driver store — reuse what's installed
Tier 2Local bundle — packs in drivers\ next to the 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

# Download a pack URL (zip, cab, 7z, or self-extracting exe)
prinstall driver add https://example.com/upd.zip

# 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)

# Create drivers\ next to this exe, then drop extracted vendor packs in it
prinstall driver init

# Layout — one subfolder per pack, each with 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