From 8f7f7cd9843df3f84c7f7ace63b794cab0e1dcbf Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Fri, 30 Jun 2023 11:00:41 +0200 Subject: [PATCH] Adds new Hyper-V data provider --- doc/100-General/10-Changelog.md | 1 + .../Get-IcingaProviderDataValuesHyperV.psm1 | 110 ++++++++++++++++++ .../core/New-IcingaProviderObject.psm1 | 15 +-- 3 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 lib/provider/assets/hyperv/Get-IcingaProviderDataValuesHyperV.psm1 diff --git a/doc/100-General/10-Changelog.md b/doc/100-General/10-Changelog.md index b7c9e446..26e72884 100644 --- a/doc/100-General/10-Changelog.md +++ b/doc/100-General/10-Changelog.md @@ -33,6 +33,7 @@ Released closed milestones can be found on [GitHub](https://github.com/Icinga/ic * [#640](https://github.com/Icinga/icinga-powershell-framework/issues/640) Adds support to set the flag `-NoSSLValidation` for Cmdlets `icinga` and `Install-Icinga`, to ignore errors on self-signed certificates within the environment * [#643](https://github.com/Icinga/icinga-powershell-framework/pull/643) Adds support for `-RebuildCache` flag on `icinga` cmd to rebuild component cache as well * [#644](https://github.com/Icinga/icinga-powershell-framework/pull/644) Adds progress bar output to repository interaction (sync, update, new) instead of plain text output +* [#649](https://github.com/Icinga/icinga-powershell-framework/pull/649) Adds new basic data provider base for Hyper-V information ## 1.10.1 (2022-12-20) diff --git a/lib/provider/assets/hyperv/Get-IcingaProviderDataValuesHyperV.psm1 b/lib/provider/assets/hyperv/Get-IcingaProviderDataValuesHyperV.psm1 new file mode 100644 index 00000000..4949b70f --- /dev/null +++ b/lib/provider/assets/hyperv/Get-IcingaProviderDataValuesHyperV.psm1 @@ -0,0 +1,110 @@ +function Get-IcingaProviderDataValuesHyperV() +{ + param ( + [switch]$IncludeDetails = $FALSE + ); + + $HyperVData = New-IcingaProviderObject -Name 'Hyper-V'; + + # Check if the Hyper-V is installed. If not, we will simply return an empty object + if ($null -eq (Get-Service -Name 'vmms' -ErrorAction SilentlyContinue)) { + $HyperVData.FeatureInstalled = $FALSE; + + return $HyperVData; + } + + $HyperVData.Metrics | Add-Member -MemberType NoteProperty -Name 'ClusterData' -Value (New-Object PSCustomObject); + $HyperVData.Metrics | Add-Member -MemberType NoteProperty -Name 'BlackoutTimes' -Value (New-Object PSCustomObject); + $HyperVData.Metrics.BlackoutTimes | Add-Member -MemberType NoteProperty -Name 'Information' -Value (New-Object PSCustomObject); + $HyperVData.Metrics.BlackoutTimes | Add-Member -MemberType NoteProperty -Name 'Warning' -Value (New-Object PSCustomObject); + $HyperVData.Metrics.ClusterData | Add-Member -MemberType NoteProperty -Name 'NodeCount' -Value 1; # We always have at least 1 node + $HyperVData.Metrics.ClusterData | Add-Member -MemberType NoteProperty -Name 'VMList' -Value (New-Object PSCustomObject); + $HyperVData.Metrics.ClusterData.VMList | Add-Member -MemberType NoteProperty -Name 'Duplicates' -Value (New-Object PSCustomObject); + $HyperVData.Metrics.ClusterData.VMList | Add-Member -MemberType NoteProperty -Name 'VMs' -Value (New-Object PSCustomObject); + + try { + if (Test-IcingaFunction 'Get-ClusterNode') { + $ClusterInformation = Get-ClusterNode -Cluster '.' -ErrorAction Stop; + + $HyperVData.Metrics.ClusterData.NodeCount = $ClusterInformation.Count; + } + + [array]$VMRessources = @(); + + if (Test-IcingaFunction 'Get-ClusterResource') { + [array]$VMRessources = Get-ClusterResource -Cluster '.' -ErrorAction Stop | Where-Object ResourceType -EQ 'Virtual Machine'; + } else { + [array]$VMRessources = Get-VM -ErrorAction Stop; + } + + if ($null -ne $VMRessources -And $VMRessources.Count -ne 0) { + foreach ($VMRessource in $VMRessources) { + if ((Test-PSCustomObjectMember -PSObject $HyperVData.Metrics.ClusterData.VMList.VMs -Name $VMRessource.Name) -eq $FALSE) { + $HyperVData.Metrics.ClusterData.VMList.VMs | Add-Member -MemberType NoteProperty -Name $VMRessource.Name -Value 1; + } else { + $HyperVData.Metrics.ClusterData.VMList.VMs.($VMRessource.Name) += 1; + + if ((Test-PSCustomObjectMember -PSObject $HyperVData.Metrics.ClusterData.VMList.Duplicates -Name $VMRessource.Name) -eq $FALSE) { + $HyperVData.Metrics.ClusterData.VMList.Duplicates | Add-Member -MemberType NoteProperty -Name $VMRessource.Name -Value 0; + } + $HyperVData.Metrics.ClusterData.VMList.Duplicates.($VMRessource.Name) = $HyperVData.Metrics.ClusterData.VMList.VMs.($VMRessource.Name); + } + } + } + + # Blackout Times + # => Info + [array]$InformationBlackoutTimes = Get-WinEvent -FilterHashtable @{ 'LogName'='Microsoft-Windows-Hyper-V-VMMS-Admin'; 'Id' = '20415'; } -MaxEvents 300 -ErrorAction SilentlyContinue; + + if ($null -ne $InformationBlackoutTimes -Or $InformationBlackoutTimes.Count -ne 0) { + foreach ($event in $InformationBlackoutTimes) { + $XMLEventData = ([xml]$event.ToXml()).Event; + + if ((Test-PSCustomObjectMember -PSObject $HyperVData.Metrics.BlackoutTimes.Information -Name $XMLEventData.UserData.VmlEventLog.Parameter0) -eq $FALSE) { + $EventObject = New-Object PSCustomObject; + $EventObject | Add-Member -MemberType NoteProperty -Name 'Timestamp' -Value $event.TimeCreated; + $EventObject | Add-Member -MemberType NoteProperty -Name 'BlackoutTime' -Value $XMLEventData.UserData.VmlEventLog.Parameter2; + + $HyperVData.Metrics.BlackoutTimes.Information | Add-Member -MemberType NoteProperty -Name $XMLEventData.UserData.VmlEventLog.Parameter0 -Value $EventObject; + } + } + } + + # Blackout Times + # => Warning + [array]$WarningBlackoutTimes = Get-WinEvent -FilterHashtable @{ 'LogName'='Microsoft-Windows-Hyper-V-VMMS-Admin'; 'Id' = '20417'; } -MaxEvents 300 -ErrorAction SilentlyContinue; + + if ($null -ne $WarningBlackoutTimes -Or $WarningBlackoutTimes.Count -ne 0) { + foreach ($event in $WarningBlackoutTimes) { + $XMLEventData = ([xml]$event.ToXml()).Event; + + if ((Test-PSCustomObjectMember -PSObject $HyperVData.Metrics.BlackoutTimes.Warning -Name $XMLEventData.UserData.VmlEventLog.Parameter0) -eq $FALSE) { + $EventObject = New-Object PSCustomObject; + $EventObject | Add-Member -MemberType NoteProperty -Name 'Timestamp' -Value $event.TimeCreated; + $EventObject | Add-Member -MemberType NoteProperty -Name 'BlackoutTime' -Value $XMLEventData.UserData.VmlEventLog.Parameter2; + + [bool]$IsAcknowledged = $FALSE; + + foreach ($InfoBlackoutTime in $HyperVData.Metrics.BlackoutTimes.Information.PSObject.Properties.Name) { + if ($InfoBlackoutTime -eq $XMLEventData.UserData.VmlEventLog.Parameter0) { + if($HyperVData.Metrics.BlackoutTimes.Information.$InfoBlackoutTime.Timestamp -gt $event.TimeCreated) { + $IsAcknowledged = $TRUE; + break; + } + } + } + + if ($IsAcknowledged) { + continue; + } + + $HyperVData.Metrics.BlackoutTimes.Warning | Add-Member -MemberType NoteProperty -Name $XMLEventData.UserData.VmlEventLog.Parameter0 -Value $EventObject; + } + } + } + } catch { + Exit-IcingaThrowException -ExceptionType 'Custom' -CustomMessage 'Hyper-V Error' -ExceptionThrown $_.Exception.Message -Force; + } + + return $HyperVData; +} diff --git a/lib/provider/core/New-IcingaProviderObject.psm1 b/lib/provider/core/New-IcingaProviderObject.psm1 index 26d591ac..1fc7f320 100644 --- a/lib/provider/core/New-IcingaProviderObject.psm1 +++ b/lib/provider/core/New-IcingaProviderObject.psm1 @@ -5,13 +5,14 @@ function New-IcingaProviderObject() ); $ProviderObject = New-Object PSCustomObject; - $ProviderObject | Add-Member -MemberType NoteProperty -Name 'Name' -Value $Name; - $ProviderObject | Add-Member -MemberType NoteProperty -Name 'Metadata' -Value (New-Object PSCustomObject); - $ProviderObject | Add-Member -MemberType NoteProperty -Name 'Metrics' -Value (New-Object PSCustomObject); - $ProviderObject | Add-Member -MemberType NoteProperty -Name 'MetricsOverTime' -Value (New-Object PSCustomObject); - $ProviderObject.MetricsOverTime | Add-Member -MemberType NoteProperty -Name 'MetricContainer' -Value (New-Object PSCustomObject); - $ProviderObject.MetricsOverTime | Add-Member -MemberType NoteProperty -Name 'Cache' -Value (New-Object PSCustomObject); - $ProviderObject.MetricsOverTime | Add-Member -MemberType NoteProperty -Name 'Compiled' -Value (New-Object PSCustomObject); + $ProviderObject | Add-Member -MemberType NoteProperty -Name 'Name' -Value $Name; + $ProviderObject | Add-Member -MemberType NoteProperty -Name 'FeatureInstalled' -Value $TRUE; + $ProviderObject | Add-Member -MemberType NoteProperty -Name 'Metadata' -Value (New-Object PSCustomObject); + $ProviderObject | Add-Member -MemberType NoteProperty -Name 'Metrics' -Value (New-Object PSCustomObject); + $ProviderObject | Add-Member -MemberType NoteProperty -Name 'MetricsOverTime' -Value (New-Object PSCustomObject); + $ProviderObject.MetricsOverTime | Add-Member -MemberType NoteProperty -Name 'MetricContainer' -Value (New-Object PSCustomObject); + $ProviderObject.MetricsOverTime | Add-Member -MemberType NoteProperty -Name 'Cache' -Value (New-Object PSCustomObject); + $ProviderObject.MetricsOverTime | Add-Member -MemberType NoteProperty -Name 'Compiled' -Value (New-Object PSCustomObject); return $ProviderObject; }