281 lines
10 KiB
PowerShell
281 lines
10 KiB
PowerShell
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
|
|
}
|
|
}
|