Add New-SamyPrinterProfileJson.ps1
This commit is contained in:
280
New-SamyPrinterProfileJson.ps1
Normal file
280
New-SamyPrinterProfileJson.ps1
Normal 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
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user