Public/Get-ZbxMaintenance.ps1
|
function Get-ZbxMaintenance { <# .SYNOPSIS Gets maintenance windows from Zabbix server. .DESCRIPTION Queries Zabbix API (maintenance.get) for maintenance windows. Returns rich PSCustomObject results in both default and detailed modes - the default returns a compact view (Name, Active since, Active till, State), while -Details additionally includes time periods, host groups, hosts and description. Both modes return objects that flow through the pipeline (suitable for Where-Object / Export-Csv / Format-Table etc.). The State column is calculated locally: Active (now between Active since and Active till), Expired (now past Active till), or Approaching (now before Active since). Objects carry the type name 'psZBX.Maintenance' so a custom Format.ps1xml can later style the State column (colors etc.). .PARAMETER Name Filter by maintenance name. Use * for all maintenances. Supports partial matching with wildcards. Default is * (all maintenances). .PARAMETER Details Return full maintenance information including time periods, host groups, hosts and description. .EXAMPLE Get-ZbxMaintenance Lists all maintenance windows (compact view). .EXAMPLE Get-ZbxMaintenance | Format-Table -AutoSize Same as above, explicitly formatted as a table. .EXAMPLE Get-ZbxMaintenance -Name 'Weekly Patching' Gets a specific maintenance window (exact match). .EXAMPLE Get-ZbxMaintenance -Name 'Patch*' Lists maintenance windows with names starting with 'Patch'. .EXAMPLE Get-ZbxMaintenance -Details Lists all maintenance windows with full details. .EXAMPLE Get-ZbxMaintenance -Details | Where-Object { $_.'Host groups' -like '*Linux*' } Finds maintenance windows applying to Linux host groups. .EXAMPLE Get-ZbxMaintenance | Where-Object { $_.State -eq 'Active' } Lists only currently active maintenance windows. .EXAMPLE # Manual colored output if desired Get-ZbxMaintenance | ForEach-Object { $color = switch ($_.State) { 'Active' { 'Green' } 'Expired' { 'Red' } 'Approaching' { 'DarkYellow' } default { 'Gray' } } Write-Host ('{0,-30} {1,-19} {2,-19} {3}' -f $_.Name, $_.'Active since', $_.'Active till', $_.State) -ForegroundColor $color } Replicates the legacy colored output from pre-1.0.0 versions. .OUTPUTS PSCustomObject[] with one object per maintenance window. #> [CmdletBinding()] param( [Parameter(Position = 0)] [string]$Name = '*', [Parameter()] [switch]$Details ) $apiParams = @{ output = 'extend' selectTimeperiods = 'extend' selectHosts = @('hostid', 'host', 'name') selectHostGroups = @('groupid', 'name') selectGroups = @('groupid', 'name') sortfield = @('name') sortorder = 'ASC' } # Name filter if ($Name -ne '*') { if ($Name -match '\*') { $searchName = $Name -replace '\*', '' $apiParams['search'] = @{ name = $searchName } $apiParams['searchWildcardsEnabled'] = $true } else { $apiParams['filter'] = @{ name = $Name } } } try { $maintenances = Invoke-ZabbixAPI -Method 'maintenance.get' -Params $apiParams if (-not $maintenances -or $maintenances.Count -eq 0) { Write-Verbose "No maintenance windows found matching the specified criteria." return } $now = Get-Date foreach ($maint in $maintenances) { $activeSince = Convert-UnixTimestamp -Timestamp $maint.active_since $activeTill = Convert-UnixTimestamp -Timestamp $maint.active_till $state = if ($now -lt $activeSince) { 'Approaching' } elseif ($now -le $activeTill) { 'Active' } else { 'Expired' } if ($Details) { # Human-readable period descriptions $periodsText = if ($maint.timeperiods -and $maint.timeperiods.Count -gt 0) { $periodsList = foreach ($period in $maint.timeperiods) { $periodType = switch ($period.timeperiod_type) { '0' { 'One-time' } '2' { 'Daily' } '3' { 'Weekly' } '4' { 'Monthly' } default { 'Unknown' } } $durSec = [int]$period.period $durStr = if ($durSec -ge 86400) { "{0}d {1}h" -f [int]($durSec / 86400), [int](($durSec % 86400) / 3600) } elseif ($durSec -ge 3600) { "{0}h {1}m" -f [int]($durSec / 3600), [int](($durSec % 3600) / 60) } else { "{0}m" -f [int]($durSec / 60) } if ($period.timeperiod_type -eq '0') { $startDate = Convert-UnixTimestamp -Timestamp $period.start_date "$periodType at $($startDate.ToString('yyyy-MM-dd HH:mm')) for $durStr" } else { $startSec = [int]$period.start_time $hr = [int]($startSec / 3600) $mn = [int](($startSec % 3600) / 60) "$periodType at $('{0:00}:{1:00}' -f $hr, $mn) for $durStr" } } $periodsList -join '; ' } else { 'None' } # Host groups - prefer hostgroups (6.2+), fall back to groups $groupList = @() if ($null -ne $maint.hostgroups -and $maint.hostgroups.Count -gt 0) { $groupList = $maint.hostgroups } elseif ($null -ne $maint.groups -and $maint.groups.Count -gt 0) { $groupList = $maint.groups } $hostGroupsText = if ($groupList.Count -gt 0) { ($groupList | ForEach-Object { $_.name }) -join ', ' } else { 'None' } $hostsText = if ($maint.hosts -and $maint.hosts.Count -gt 0) { ($maint.hosts | ForEach-Object { $_.name }) -join ', ' } else { 'None' } [PSCustomObject]@{ PSTypeName = 'psZBX.Maintenance' Name = $maint.name 'Active since' = $activeSince.ToString('yyyy-MM-dd HH:mm:ss') 'Active till' = $activeTill.ToString('yyyy-MM-dd HH:mm:ss') State = $state Periods = $periodsText 'Host groups' = $hostGroupsText Hosts = $hostsText Description = if ([string]::IsNullOrWhiteSpace($maint.description)) { 'None' } else { $maint.description } } } else { [PSCustomObject]@{ PSTypeName = 'psZBX.Maintenance' Name = $maint.name 'Active since' = $activeSince.ToString('yyyy-MM-dd HH:mm:ss') 'Active till' = $activeTill.ToString('yyyy-MM-dd HH:mm:ss') State = $state } } } } catch { throw "Failed to get maintenance information: $_" } } |