Add New-SamyPrinterProfileJson.ps1

This commit is contained in:
2025-12-08 21:09:05 -05:00
committed by syelle
parent dc4113d253
commit 1cef79c52b

View File

@@ -0,0 +1,280 @@
function New-SamyPrinterProfileJson {
<#
.SYNOPSIS
Generates a SAMY printer profile JSON template from existing printers
and optionally uploads it to a Git (Gitea) repository.
.DESCRIPTION
Enumerates local printers via Get-Printer, maps them into SAMY printer
profile objects, and writes them to a JSON file. The JSON is intended
as a starting point / template for building printers.json used by SAMY.
Each profile includes:
- ClientCode (from parameter)
- Location (from parameter)
- ProfileName (defaults to printer Name)
- DisplayName (printer Name)
- Type (TcpIp or Shared, best-effort guess)
- Address (for TCP/IP printers)
- PrintServer (for shared printers)
- ShareName (for shared printers)
- DriverName (printer DriverName)
- DriverInfPath, DriverPackagePath, DriverInfName (empty placeholders)
- IsDefault (true if this printer is default)
Optionally, the generated JSON can be uploaded to a Git repo using
a personal access token (PAT) passed as a SecureString.
.PARAMETER ClientCode
MSP/client code to stamp into each profile (for example "SVS").
.PARAMETER Location
Human-friendly location (for example "Embrun"). Used both as a field in
each profile and as part of the default JSON file name.
.PARAMETER OutputPath
Folder where the JSON file will be saved. Default is:
C:\ProgramData\SVS\Samy\Printers
.PARAMETER UploadToGit
When set, the function will attempt to upload the generated JSON file
to the specified Git (Gitea) repository and path.
.PARAMETER GitApiBase
Base URL for the Git API, for example:
https://git.svstools.ca/api/v1
.PARAMETER GitRepo
Repository identifier in the form "Owner/Repo", for example:
SVS_Public_Repo/SAMY
.PARAMETER GitBranch
Branch name to write to. Default is "beta".
.PARAMETER GitPath
Path inside the repo where the JSON should be written, for example:
Printers/SVS/Embrun/printers.json
.PARAMETER GitToken
Personal access token as a SecureString. Recommended source:
a secret environment variable (for example $env:GIT_PAT) converted via
ConvertTo-SecureString.
.EXAMPLE
New-SamyPrinterProfileJson -ClientCode "SVS" -Location "Embrun"
Generates a printers_SVS_Embrun.json in:
C:\ProgramData\SVS\Samy\Printers
.EXAMPLE
$secureToken = ConvertTo-SecureString $env:GIT_PAT -AsPlainText -Force
New-SamyPrinterProfileJson `
-ClientCode "SVS" `
-Location "Embrun" `
-UploadToGit `
-GitApiBase "https://git.svstools.ca/api/v1" `
-GitRepo "SVS_Public_Repo/SAMY" `
-GitBranch "beta" `
-GitPath "Printers/SVS/Embrun/printers.json" `
-GitToken $secureToken
Generates the JSON locally and uploads it to the specified path
in the Git repository.
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $true)]
[string]$ClientCode,
[Parameter(Mandatory = $true)]
[string]$Location,
[string]$OutputPath = "C:\ProgramData\SVS\Samy\Printers",
[switch]$UploadToGit,
[string]$GitApiBase,
[string]$GitRepo,
[string]$GitBranch = "beta",
[string]$GitPath,
[SecureString]$GitToken
)
# Helper: safe logging that prefers Write-LogHybrid if available
function _WriteLog {
param(
[string]$Message,
[string]$Level = "Info",
[string]$Task = "PrinterJson"
)
if (Get-Command Write-LogHybrid -ErrorAction SilentlyContinue) {
Write-LogHybrid $Message $Level $Task
} else {
Write-Host "[$Level] [$Task] $Message"
}
}
try {
_WriteLog "Starting New-SamyPrinterProfileJson for ClientCode='$ClientCode' Location='$Location'." "Info"
# ------------------------------------------------------------------
# 1) Ensure output folder exists and build a safe file name
# ------------------------------------------------------------------
if (-not (Test-Path $OutputPath)) {
_WriteLog "Creating output folder '$OutputPath'." "Info"
New-Item -Path $OutputPath -ItemType Directory -Force | Out-Null
}
$safeLocation = $Location -replace '[^A-Za-z0-9_-]', '_'
$fileName = "printers_{0}_{1}.json" -f $ClientCode, $safeLocation
$filePath = Join-Path $OutputPath $fileName
# ------------------------------------------------------------------
# 2) Enumerate printers and build profile objects
# ------------------------------------------------------------------
$printers = Get-Printer -ErrorAction SilentlyContinue
if (-not $printers) {
_WriteLog "No printers found on this system. JSON will be empty." "Warning"
} else {
_WriteLog ("Found {0} printer(s)." -f $printers.Count) "Info"
}
$profiles = @()
foreach ($p in $printers) {
$profileName = $p.Name
$displayName = $p.Name
$driverName = $p.DriverName
$portName = $p.PortName
$isDefault = $p.Shared -eq $false -and $p.Default -eq $true
# Try to resolve port details
$port = $null
if ($portName) {
$port = Get-PrinterPort -Name $portName -ErrorAction SilentlyContinue
}
$type = "TcpIp"
$address = $null
$printServer = $null
$shareName = $null
if ($port -and $port.PrinterHostAddress) {
# Standard TCP/IP port
$type = "TcpIp"
$address = $port.PrinterHostAddress
}
elseif ($p.Shared -and $p.ShareName) {
# Best guess at a shared printer
$type = "Shared"
$shareName = $p.ShareName
$printServer = $env:COMPUTERNAME
}
$profiles += [PSCustomObject]@{
ClientCode = $ClientCode
Location = $Location
ProfileName = $profileName
DisplayName = $displayName
Type = $type
Address = $address
PrintServer = $printServer
ShareName = $shareName
DriverName = $driverName
DriverInfPath = ""
DriverPackagePath = ""
DriverInfName = ""
IsDefault = $isDefault
_comment1 = "Review Type/Address/PrintServer/ShareName before use."
_comment2 = "Fill DriverPackagePath and DriverInfName for repo-based install."
}
}
# ------------------------------------------------------------------
# 3) Write JSON to disk
# ------------------------------------------------------------------
$json = $profiles | ConvertTo-Json -Depth 5
$json | Set-Content -Path $filePath -Encoding UTF8
_WriteLog ("Wrote {0} profile(s) to '{1}'." -f $profiles.Count, $filePath) "Success"
# ------------------------------------------------------------------
# 4) Optional: upload to Git (Gitea)
# ------------------------------------------------------------------
if ($UploadToGit) {
if (-not $GitApiBase -or -not $GitRepo -or -not $GitPath -or -not $GitToken) {
_WriteLog "UploadToGit requested but GitApiBase, GitRepo, GitPath, or GitToken is missing. Skipping upload." "Warning"
}
else {
_WriteLog "Uploading JSON to Git repo '$GitRepo' (branch '$GitBranch', path '$GitPath')." "Info"
# Convert SecureString token to plain text (in memory only)
$bstr = [Runtime.InteropServices.Marshal]::SecureStringToBSTR($GitToken)
try {
$plainToken = [Runtime.InteropServices.Marshal]::PtrToStringAuto($bstr)
}
finally {
if ($bstr -ne [IntPtr]::Zero) {
[Runtime.InteropServices.Marshal]::ZeroFreeBSTR($bstr)
}
}
# Prepare API URL and content
$apiUrl = "{0}/repos/{1}/contents/{2}" -f $GitApiBase.TrimEnd('/'), $GitRepo, $GitPath
$contentB64 = [Convert]::ToBase64String([Text.Encoding]::UTF8.GetBytes($json))
$headers = @{
Authorization = "token $plainToken"
}
# Try to see if file already exists to retrieve its SHA
$existingSha = $null
try {
$existing = Invoke-RestMethod -Uri ($apiUrl + "?ref=$GitBranch") -Headers $headers -Method Get -ErrorAction Stop
if ($existing.sha) {
$existingSha = $existing.sha
}
}
catch {
# 404 is fine (file does not exist yet), anything else we log
if ($_.Exception.Response.StatusCode.Value__ -ne 404) {
_WriteLog ("Git pre-check failed: {0}" -f $_.Exception.Message) "Warning"
}
}
$body = @{
message = "Update printers for $ClientCode / $Location"
branch = $GitBranch
content = $contentB64
}
if ($existingSha) {
$body.sha = $existingSha
}
try {
$bodyJson = $body | ConvertTo-Json -Depth 5
$null = Invoke-RestMethod -Uri $apiUrl -Headers $headers -Method Put -Body $bodyJson -ContentType "application/json" -ErrorAction Stop
_WriteLog "Git upload completed successfully." "Success"
}
catch {
_WriteLog ("Git upload failed: {0}" -f $_.Exception.Message) "Error"
}
}
}
return $filePath
}
catch {
_WriteLog ("New-SamyPrinterProfileJson failed: {0}" -f $_.Exception.Message) "Error"
throw
}
}