From 6bff8f3c0c23370bc8f395cccf97f20dd14ed3d7 Mon Sep 17 00:00:00 2001 From: Kawa Date: Fri, 10 Apr 2026 13:35:05 +0200 Subject: [PATCH] feat(04-02): add render_uninstall and render_detect with Jinja2 templates - render_uninstall(printer_name, driver_name, port_name): Remove-Printer/Driver/Port in safe order - render_detect(printer_name): Get-Printer check with Write-Output + exit 0/1 Intune contract - uninstall.ps1.j2: all Remove-* with -ErrorAction SilentlyContinue - detect.ps1.j2: Intune detection contract template --- imptune/generators/script_generator.py | 46 ++++++++++++++++++++-- imptune/templates/scripts/detect.ps1.j2 | 8 ++++ imptune/templates/scripts/uninstall.ps1.j2 | 4 ++ 3 files changed, 55 insertions(+), 3 deletions(-) create mode 100644 imptune/templates/scripts/detect.ps1.j2 create mode 100644 imptune/templates/scripts/uninstall.ps1.j2 diff --git a/imptune/generators/script_generator.py b/imptune/generators/script_generator.py index 5c03a7f..7512682 100644 --- a/imptune/generators/script_generator.py +++ b/imptune/generators/script_generator.py @@ -1,8 +1,10 @@ """Script generator module — renders PowerShell scripts from Jinja2 templates. -Provides render_install() which produces a complete PowerShell install script -containing WOW64 guard, UAC self-elevation, pnputil two-step driver staging, -idempotent port/printer creation, and Set-PrintConfiguration with duplex mapping. +Provides render_install(), render_uninstall(), and render_detect() which produce +complete PowerShell scripts for Intune deployment: +- render_install: WOW64 guard, UAC self-elevation, pnputil two-step, idempotent setup +- render_uninstall: Ordered removal of printer, driver, and port +- render_detect: Intune detection contract (Write-Output + exit 0/1) """ from pathlib import Path @@ -63,3 +65,41 @@ def render_install( paper_size=paper_size, collate=str(collate).lower(), ) + + +def render_uninstall(printer_name: str, driver_name: str, port_name: str) -> str: + """Render uninstall.ps1.j2 — removes printer, driver, and port in safe order. + + Removal order: Printer first (so driver is no longer referenced), then Driver, + then Port. All operations use -ErrorAction SilentlyContinue for idempotency. + + Args: + printer_name: Display name of the printer to remove. + driver_name: Exact driver name as registered in Windows. + port_name: Port name (e.g. "IP_192.168.1.10"). + + Returns: + Rendered PowerShell script as a string. + """ + tpl = _env.get_template("uninstall.ps1.j2") + return tpl.render( + printer_name=printer_name, + driver_name=driver_name, + port_name=port_name, + ) + + +def render_detect(printer_name: str) -> str: + """Render detect.ps1.j2 — Intune detection script. + + Follows the Intune detection contract: Write-Output + exit 0 when printer + is found, exit 1 when absent. Intune considers exit 0 as "app installed". + + Args: + printer_name: Display name of the printer to detect. + + Returns: + Rendered PowerShell script as a string. + """ + tpl = _env.get_template("detect.ps1.j2") + return tpl.render(printer_name=printer_name) diff --git a/imptune/templates/scripts/detect.ps1.j2 b/imptune/templates/scripts/detect.ps1.j2 new file mode 100644 index 0000000..d555a5b --- /dev/null +++ b/imptune/templates/scripts/detect.ps1.j2 @@ -0,0 +1,8 @@ +# Generated by ImpTune — Detection script for {{ printer_name }} +$printer = Get-Printer -Name "{{ printer_name }}" -ErrorAction SilentlyContinue +if ($printer) { + Write-Output "Installed: {{ printer_name }}" + exit 0 +} else { + exit 1 +} diff --git a/imptune/templates/scripts/uninstall.ps1.j2 b/imptune/templates/scripts/uninstall.ps1.j2 new file mode 100644 index 0000000..60c4a81 --- /dev/null +++ b/imptune/templates/scripts/uninstall.ps1.j2 @@ -0,0 +1,4 @@ +# Generated by ImpTune — Uninstall script for {{ printer_name }} +Remove-Printer -Name "{{ printer_name }}" -ErrorAction SilentlyContinue +Remove-PrinterDriver -Name "{{ driver_name }}" -ErrorAction SilentlyContinue +Remove-PrinterPort -Name "{{ port_name }}" -ErrorAction SilentlyContinue