Public/Export-CwCustomField.ps1
|
function Export-CwCustomField { <# .SYNOPSIS Maps snapshot key metrics onto RMM-specific custom-field writes (NinjaOne / Datto RMM / N-central). .DESCRIPTION Derives the standard metric set from a snapshot: NextExpiryDays, ExpiringCount, CrlHealthy, CaService, LastCheck and writes it to the target RMM: NinjaOne - via the agent-provided Ninja-Property-Set CLI DattoRMM - UDF via HKLM:\SOFTWARE\CentraStage Custom<N> NCentral - key=value lines on stdout (Automation Manager parsing) Always returns the metrics object, so the caller can also feed other systems. Provider writes are skipped with a warning when the agent context is not available (e.g. Ninja CLI missing). .EXAMPLE Get-CwSnapshot -IncludeCrl -IncludeCA | Export-CwCustomField -Provider NinjaOne #> [CmdletBinding(SupportsShouldProcess)] [OutputType([pscustomobject])] param( [Parameter(Mandatory, ValueFromPipeline, Position = 0)] [object]$Snapshot, [Parameter(Mandatory)] [ValidateSet('NinjaOne', 'DattoRMM', 'NCentral')] [string]$Provider, # NinjaOne custom field name prefix (fields: <prefix>NextExpiryDays, ...) [string]$FieldPrefix = 'cert', # Datto RMM UDF number (writes Custom<N>) [ValidateRange(1, 30)] [int]$DattoUdf = 10 ) process { $certs = @($Snapshot.Certificates) $warnDays = 30 if ($Snapshot.PSObject.Properties['Thresholds'] -and $Snapshot.Thresholds -and $Snapshot.Thresholds.PSObject.Properties['WarnDays']) { $warnDays = [double]$Snapshot.Thresholds.WarnDays } $next = $certs | Sort-Object { [double]$_.DaysRemaining } | Select-Object -First 1 $crls = @($Snapshot.Crls) $crlHealthy = if ($crls.Count -eq 0) { $null } else { @($crls | Where-Object { $_.Severity -in 'WARNING', 'CRITICAL' }).Count -eq 0 } $caService = $null if ($Snapshot.CaHealth -and $Snapshot.CaHealth.IsCa) { $caService = $Snapshot.CaHealth.ServiceStatus } $metrics = [pscustomobject]@{ PSTypeName = 'CertWatchtower.Metrics' Host = $Snapshot.Host NextExpiryDays = if ($next) { [math]::Floor([double]$next.DaysRemaining) } else { $null } NextSubject = if ($next) { $next.Subject } else { $null } NextRole = if ($next) { $next.Role } else { $null } ExpiringCount = @($certs | Where-Object { [double]$_.DaysRemaining -le $warnDays }).Count CrlHealthy = $crlHealthy CaService = $caService LastCheck = (Get-Date -Format o) } switch ($Provider) { 'NinjaOne' { if (Get-Command -Name 'Ninja-Property-Set' -ErrorAction SilentlyContinue) { if ($PSCmdlet.ShouldProcess('NinjaOne custom fields', 'Ninja-Property-Set')) { Ninja-Property-Set "$($FieldPrefix)NextExpiryDays" $metrics.NextExpiryDays Ninja-Property-Set "$($FieldPrefix)ExpiringCount" $metrics.ExpiringCount Ninja-Property-Set "$($FieldPrefix)CrlHealthy" $metrics.CrlHealthy Ninja-Property-Set "$($FieldPrefix)CaService" $metrics.CaService Ninja-Property-Set "$($FieldPrefix)LastCheck" $metrics.LastCheck } } else { Write-Warning 'Ninja-Property-Set CLI not found - not running in a NinjaOne agent context.' } } 'DattoRMM' { $regPath = 'HKLM:\SOFTWARE\CentraStage' if ($PSCmdlet.ShouldProcess("$regPath Custom$DattoUdf", 'Write UDF')) { if (-not (Test-Path -Path $regPath)) { Write-Warning "Registry path $regPath not found - not running under a Datto RMM agent." } else { $value = "NextExpiry=$($metrics.NextExpiryDays)d Expiring=$($metrics.ExpiringCount) CRL=$(if ($null -eq $metrics.CrlHealthy) { 'n/a' } elseif ($metrics.CrlHealthy) { 'ok' } else { 'FAIL' })" New-ItemProperty -Path $regPath -Name "Custom$DattoUdf" -Value $value -PropertyType String -Force | Out-Null } } } 'NCentral' { # N-central Automation Manager reads stdout key=value pairs Write-Output "certNextExpiryDays=$($metrics.NextExpiryDays)" Write-Output "certExpiringCount=$($metrics.ExpiringCount)" Write-Output "certCrlHealthy=$($metrics.CrlHealthy)" Write-Output "certCaService=$($metrics.CaService)" Write-Output "certLastCheck=$($metrics.LastCheck)" } } $metrics } } |