From 80ff188c903a5d147296612a75145f2f807b5f77 Mon Sep 17 00:00:00 2001 From: Crited Date: Fri, 12 Jul 2019 13:59:02 +0200 Subject: [PATCH 001/259] Added bios.psm1 (Library) and a provider/enums.psm1 --- icinga-module-windows.psm1 | 2 + lib/provider/bios.psm1 | 91 ++++++++++++++++++++++++++++++++++++++ lib/provider/enums.psm1 | 72 ++++++++++++++++++++++++++++++ 3 files changed, 165 insertions(+) create mode 100644 lib/provider/bios.psm1 create mode 100644 lib/provider/enums.psm1 diff --git a/icinga-module-windows.psm1 b/icinga-module-windows.psm1 index 3d84e5e..70c3552 100644 --- a/icinga-module-windows.psm1 +++ b/icinga-module-windows.psm1 @@ -9,6 +9,8 @@ #> +$global:IncludeDir = "$PSScriptRoot\lib"; + function Install-Icinga() { [string]$command = Get-Icinga-Command('setup'); diff --git a/lib/provider/bios.psm1 b/lib/provider/bios.psm1 new file mode 100644 index 0000000..ba9655f --- /dev/null +++ b/lib/provider/bios.psm1 @@ -0,0 +1,91 @@ +Import-Module $IncludeDir\provider\enums; + +function Show-IcingaBiosData() +{ + # Lets load some bios informations + $BIOSInformation = Get-CimInstance Win32_BIOS; + [hashtable]$BIOSData = @{}; + + foreach ($bios_properties in $BIOSInformation) { + foreach($bios in $bios_properties.CimInstanceProperties) { + $BIOSData.Add($bios.Name, $bios.Value); + } + } + + return $BIOSData; +} + +function Get-IcingaBiosSerialNumber() +{ + $bios = Get-CimInstance Win32_BIOS; + return @{'value' = $bios.SerialNumber; 'name' = 'SerialNumber'}; +} + +function Get-IcingaBiosVersion() +{ + $bios = Get-CimInstance Win32_BIOS; + return @{'value' = $bios.Version; 'name' = 'Version'}; +} + +function Get-IcingaBiosManufacturer() +{ + $bios = Get-CimInstance Win32_BIOS; + return @{'value' = $bios.Manufacturer; 'name' = 'Manufacturer'}; +} + +# Primary Bios seems to be relevant in dual-bios context +function Get-IcingaBiosPrimaryBios() +{ + $bios = Get-CimInstance Win32_BIOS; + return @{'value' = $bios.PrimaryBIOS; 'name' = 'PrimaryBIOS'}; +} + +function Get-IcingaBiosName() +{ + $bios = Get-CimInstance Win32_BIOS; + return @{'value' = $bios.Name; 'name' = 'Name'}; +} + +function Get-IcingaBiosStatus() +{ + $bios = Get-CimInstance Win32_BIOS; + return @{'value' = $bios.Status; 'name' = 'Status'}; +} + +function Get-IcingaBiosCaption() +{ + $bios = Get-CimInstance Win32_BIOS; + return @{'value' = $bios.Caption; 'name' = 'Caption'}; +} + +function Get-IcingaBiosSMBIOSBIOSVersion() +{ + $bios = Get-CimInstance Win32_BIOS; + return @{'value' = $bios.SMBIOSBIOSVersion; 'name' = 'SMBIOSBIOSVersion'}; +} + +function Get-IcingaBiosSoftwareElementID() +{ + $bios = Get-CimInstance Win32_BIOS; + return @{'value' = $bios.SoftwareElementID; 'name' = 'SoftwareElementID'}; +} + +function Get-IcingaBiosCharacteristics() +{ + param([switch]$Sorted); + + $bios = Get-CimInstance WIN32_BIOS; + [hashtable]$BIOSCharacteristics = @{}; + + foreach ($id in $bios.BiosCharacteristics) { + $BIOSCharacteristics.Add([int]$id, $ProviderEnums.BiosCharacteristics.([int]$id)); + } + + $output = $BIOSCharacteristics; + + if ($sorted) { + $output = $BIOSCharacteristics.GetEnumerator() | Sort-Object name; + } + + return @{'value' = $output; 'name' = 'BiosCharacteristics'}; +} diff --git a/lib/provider/enums.psm1 b/lib/provider/enums.psm1 new file mode 100644 index 0000000..a5425fd --- /dev/null +++ b/lib/provider/enums.psm1 @@ -0,0 +1,72 @@ +[hashtable]$BiosCharacteristics = @{ + 0 = 'Reserved'; + 1 = 'Reserved'; + 2 = 'Unknown'; + 3 = 'BIOS Characteristics Not Supported'; + 4 = 'ISA is supported'; + 5 = 'MCA is supported'; + 6 = 'EISA is supported'; + 7 = 'PCI is supported'; + 8 = 'PC Card (PCMCIA) is supported'; + 9 = 'Plug and Play is supported'; + 10 = 'APM is supported'; + 11 = 'BIOS is Upgradeable (Flash)'; + 12 = 'BIOS shadowing is allowed'; + 13 = 'VL-VESA is supported'; + 14 = 'ESCD support is available'; + 15 = 'Boot from CD is supported'; + 16 = 'Selectable Boot is supported'; + 17 = 'BIOS ROM is socketed'; + 18 = 'Boot From PC Card (PCMCIA) is supported'; + 19 = 'EDD (Enhanced Disk Drive) Specification is supported'; + 20 = 'Int 13h - Japanese Floppy for NEC 9800 1.2mb (3.5, 1k Bytes/Sector, 360 RPM) is supported'; + 21 = 'Int 13h - Japanese Floppy for Toshiba 1.2mb (3.5, 360 RPM) is supported'; + 22 = 'Int 13h - 5.25 / 360 KB Floppy Services are supported'; + 23 = 'Int 13h - 5.25 /1.2MB Floppy Services are supported'; + 24 = 'Int 13h - 3.5 / 720 KB Floppy Services are supported'; + 25 = 'Int 13h - 3.5 / 2.88 MB Floppy Services are supported'; + 26 = 'Int 5h, Print Screen Service is supported'; + 27 = 'Int 9h, 8042 Keyboard services are supported'; + 28 = 'Int 14h, Serial Services are supported'; + 29 = 'Int 17h, printer services are supported'; + 30 = 'Int 10h, CGA/Mono Video Services are supported'; + 31 = 'NEC PC-98'; + 32 = 'ACPI is supported'; + 33 = 'USB Legacy is supported'; + 34 = 'AGP is supported'; + 35 = 'I2O boot is supported'; + 36 = 'LS-120 boot is supported'; + 37 = 'ATAPI ZIP Drive boot is supported'; + 38 = '1394 boot is supported'; + 39 = 'Smart Battery is supported'; + 40 = 'Reserved for BIOS vendor'; + 41 = 'Reserved for BIOS vendor'; + 42 = 'Reserved for BIOS vendor'; + 43 = 'Reserved for BIOS vendor'; + 44 = 'Reserved for BIOS vendor'; + 45 = 'Reserved for BIOS vendor'; + 46 = 'Reserved for BIOS vendor'; + 47 = 'Reserved for BIOS vendor'; + 48 = 'Reserved for system vendor'; + 49 = 'Reserved for system vendor'; + 50 = 'Reserved for system vendor'; + 51 = 'Reserved for system vendor'; + 52 = 'Reserved for system vendor'; + 53 = 'Reserved for system vendor'; + 54 = 'Reserved for system vendor'; + 55 = 'Reserved for system vendor'; + 56 = 'Reserved for system vendor'; + 57 = 'Reserved for system vendor'; + 58 = 'Reserved for system vendor'; + 59 = 'Reserved for system vendor'; + 60 = 'Reserved for system vendor'; + 61 = 'Reserved for system vendor'; + 62 = 'Reserved for system vendor'; + 63 = 'Reserved for system vendor' +} + +[hashtable]$ProviderEnums = @{ + BiosCharacteristics = $BiosCharacteristics +} + +Export-ModuleMember -Variable @('ProviderEnums'); \ No newline at end of file From df8ef6665e7720716466c9ace5cbc004c8baf21a Mon Sep 17 00:00:00 2001 From: Crited Date: Tue, 16 Jul 2019 14:47:21 +0200 Subject: [PATCH 002/259] Added disk-module; extended enums to fit disk-modules --- lib/provider/disks.psm1 | 220 ++++++++++++++++++++++++++++++++++++++++ lib/provider/enums.psm1 | 19 +++- 2 files changed, 238 insertions(+), 1 deletion(-) create mode 100644 lib/provider/disks.psm1 diff --git a/lib/provider/disks.psm1 b/lib/provider/disks.psm1 new file mode 100644 index 0000000..8035065 --- /dev/null +++ b/lib/provider/disks.psm1 @@ -0,0 +1,220 @@ +function Show-IcingaDiskFullData { + + $DisksInformations = Get-CimInstance Win32_DiskDrive; + + [hashtable]$PhysicalDiskData = @{}; + + foreach ($disk_properties in $DisksInformations) { + $disk_datails = @{}; + foreach($disk in $disk_properties.CimInstanceProperties) { + $disk_datails.Add($disk.Name, $disk.Value); + } + $disk_datails.Add('DriveReference', @()); + $PhysicalDiskData.Add($disk_datails.DeviceID, $disk_datails); + } + + $DiskPartitionInfo = Get-WmiObject Win32_DiskDriveToDiskPartition; + + [hashtable]$MapDiskPartitionToLogicalDisk = @{}; + + foreach ($item in $DiskPartitionInfo) { + [string]$diskPartition = $item.Dependent.SubString( + $item.Dependent.LastIndexOf('=') + 1, + $item.Dependent.Length - $item.Dependent.LastIndexOf('=') - 1 + ); + $diskPartition = $diskPartition.Replace('"', ''); + + [string]$physicalDrive = $item.Antecedent.SubString( + $item.Antecedent.LastIndexOf('\') + 1, + $item.Antecedent.Length - $item.Antecedent.LastIndexOf('\') - 1 + ) + $physicalDrive = $physicalDrive.Replace('"', ''); + + $MapDiskPartitionToLogicalDisk.Add($diskPartition, $physicalDrive); + } + + $LogicalDiskInfo = Get-WmiObject Win32_LogicalDiskToPartition; + + foreach ($item in $LogicalDiskInfo) { + [string]$driveLetter = $item.Dependent.SubString( + $item.Dependent.LastIndexOf('=') + 1, + $item.Dependent.Length - $item.Dependent.LastIndexOf('=') - 1 + ); + $driveLetter = $driveLetter.Replace('"', ''); + + [string]$diskPartition = $item.Antecedent.SubString( + $item.Antecedent.LastIndexOf('=') + 1, + $item.Antecedent.Length - $item.Antecedent.LastIndexOf('=') - 1 + ) + $diskPartition = $diskPartition.Replace('"', ''); + + if ($MapDiskPartitionToLogicalDisk.ContainsKey($diskPartition)) { + foreach ($disk in $PhysicalDiskData.Keys) { + [string]$DiskId = $disk.SubString( + $disk.LastIndexOf('\') + 1, + $disk.Length - $disk.LastIndexOf('\') - 1 + ); + + if ($DiskId.ToLower() -eq $MapDiskPartitionToLogicalDisk[$diskPartition].ToLower()) { + $PhysicalDiskData[$disk]['DriveReference'] += $driveLetter; + } + } + } + } + + return $PhysicalDiskData; + +} + +function Show-IcingaDiskPhysical() +{ + $DisksInformations = Get-CimInstance Win32_DiskDrive; + + [hashtable]$PhysicalDiskData = @{}; + + foreach ($disk_properties in $DisksInformations) { + $disk_datails = @{}; + foreach($disk in $disk_properties.CimInstanceProperties) { + $disk_datails.Add($disk.Name, $disk.Value); + } + $disk_datails.Add('DriveReference', @()); + $PhysicalDiskData.Add($disk_datails.DeviceID, $disk_datails); + } + + return $PhysicalDiskData; +} + +function Get-IcingaDiskInformation() +{ + param( + # The value to fetch from Win32_DiskDrive + [string]$Parameter + ); + $DiskInformation = Get-CimInstance Win32_DiskDrive; + [hashtable]$DiskData = @{}; + + foreach ($id in $DiskInformation.DeviceID) { + $id = $id.trimstart(".\PHYSICALDRVE"); + $DiskData.Add($id.trim(), $DiskInformation.$Parameter); + } + + return $DiskData; +} +function Get-IcingaDiskPartitions() +{ + $LogicalDiskInfo = Get-WmiObject Win32_LogicalDiskToPartition; + [hashtable]$PartitionDiskByDriveLetter = @{}; + + foreach ($item in $LogicalDiskInfo) { + [string]$driveLetter = $item.Dependent.SubString( + $item.Dependent.LastIndexOf('=') + 1, + $item.Dependent.Length - $item.Dependent.LastIndexOf('=') - 1 + ); + $driveLetter = $driveLetter.Replace('"', '').trim(':'); + + [string]$diskPartition = $item.Antecedent.SubString( + $item.Antecedent.LastIndexOf('=') + 1, + $item.Antecedent.Length - $item.Antecedent.LastIndexOf('=') - 1 + ) + $diskPartition = $diskPartition.Replace('"', ''); + $diskDisk,$diskPartition = $diskPartition.split(','); + + $diskPartition = $diskPartition.trim("Partition #"); + $diskDisk = $diskDisk.trim("Disk #"); + $diskPartitionSize = Get-Partition -DriveLetter $driveLetter; + $PartitionDiskByDriveLetter.Add( + $driveLetter, + @{ + 'Disk' = $diskDisk; + 'Partition' = $diskPartition; + 'Size' = $diskPartitionSize.Size; + } + ); + } + return $PartitionDiskByDriveLetter; +} + +#Code-Snippen that still exists for LordHepipud's amusement +function Get-IcingaDiskPartitionSize() +{ + param([switch]$sorted); + + [hashtable]$PartitionSizeByDriveLetter = @{}; + + # Should be dependent on the driveLetters returned in: "Show-IcingaDiskFullData" + for ($test = 0; $test -lt 26; $test++) + { + $DiskDriveLetter = ([char](65 + $test)) + $PartitionSize = (Get-Partition -DriveLetter $DiskDriveLetter -ErrorAction 'silentlycontinue').Size; + if ($null -eq $PartitionSize) + { + $PartitionSize = "0"; + } + $PartitionSizeByDriveLetter.Add("$DiskDriveLetter", $PartitionSize); + } + + $output = $PartitionSizeByDriveLetter; + + if ($sorted) { + $output = $PartitionSizeByDriveLetter.GetEnumerator() | Sort-Object name; + } + + return @{'value' = $output; 'name' = 'Size'}; +} +function Get-IcingaDiskCapabilities +{ + $DiskInformation = Get-CimInstance Win32_DiskDrive; + [hashtable]$DiskCapabilities = @{}; + + foreach ($id in $DiskInformation.Capabilities) { + $DiskCapabilities.Add([int]$id, $ProviderEnums.Capabilities.([int]$id)); + } + return @{'value' = $DiskCapabilities; 'name' = 'Capabilities'}; + +} +function Get-IcingaDiskSize +{ + $DiskSize = Get-IcingaDiskInformation -Parameter Size; + + return @{'value' = $DiskSize; 'name' = 'Size'}; +} + +function Get-IcingaDiskCaption +{ + $DiskCaption = Get-IcingaDiskInformation -Parameter Caption; + + return @{'value' = $DiskCaption; 'name' = 'Caption'}; +} + +function Get-IcingaDiskModel +{ + $DiskModel = Get-IcingaDiskInformation -Parameter Model; + return @{'value' = $DiskModel; 'name' = 'Model'}; +} + +function Get-IcingaDisk { + + $DiskInformation = Get-CimInstance Win32_DiskDrive; + $diskPartitionInformation = Get-IcingaDiskPartitions; + [hashtable]$DiskData = @{}; + + foreach ($id in $DiskInformation.DeviceID) { + [int]$id = $id.trimstart(".\PHYSICALDRVE"); + + $DiskData.Add( + $id, @{ + 'metadata' = @{ + 'Size' = $DiskInformation.Size; + 'Model' = $DiskInformation.Model; + 'Name' = $DiskInformation.Name.trim('.\'); + 'Manufacturer' = $DiskInformation.Manufacturer; + 'Cylinder' = $DiskInformation.TotalCylinders; + 'Sectors' = $DiskInformation.TotalSectors + }; + 'partitions' = $diskPartitionInformation + } + ); + } + + return $DiskData; +} \ No newline at end of file diff --git a/lib/provider/enums.psm1 b/lib/provider/enums.psm1 index a5425fd..b175397 100644 --- a/lib/provider/enums.psm1 +++ b/lib/provider/enums.psm1 @@ -65,8 +65,25 @@ 63 = 'Reserved for system vendor' } +[hashtable]$Capabilities = @{ + 0 = 'Unknown'; + 1 = 'Other'; + 2 = 'Sequential Access'; + 3 = 'Random Access'; + 4 = 'Supports Writing'; + 5 = 'Encryption'; + 6 = 'Compression'; + 7 = 'Supports Removeable Media'; + 8 = 'Manual Cleaning'; + 9 = 'Automatic Cleaning'; + 10 = 'SMART Notification'; + 11 = 'Supports Dual Sided Media'; + 12 = 'Predismount Eject Not Required' +} + [hashtable]$ProviderEnums = @{ - BiosCharacteristics = $BiosCharacteristics + BiosCharacteristics = $BiosCharacteristics; + Capabilities = $Capabilities; } Export-ModuleMember -Variable @('ProviderEnums'); \ No newline at end of file From dfd7d249eb37c9173c6595eb43630173c6a40172 Mon Sep 17 00:00:00 2001 From: Crited Date: Wed, 17 Jul 2019 07:52:09 +0200 Subject: [PATCH 003/259] Minor disks edit; basic cpu setup --- lib/provider/cpu.psm1 | 15 +++++++++++++++ lib/provider/disks.psm1 | 20 +++++++++++++++++++- 2 files changed, 34 insertions(+), 1 deletion(-) create mode 100644 lib/provider/cpu.psm1 diff --git a/lib/provider/cpu.psm1 b/lib/provider/cpu.psm1 new file mode 100644 index 0000000..0988bdb --- /dev/null +++ b/lib/provider/cpu.psm1 @@ -0,0 +1,15 @@ +function Show-IcingaCPUData(){ + +$CPUInformations = Get-CimInstance Win32_Processor; +[hashtable]$PhysicalCPUData = @{}; + +foreach ($cpu_properties in $CPUInformations) { + $cpu_datails = @{}; + foreach($cpu_core in $cpu_properties.CimInstanceProperties) { + $cpu_datails.Add($cpu_core.Name, $cpu_core.Value); + } + $PhysicalCPUData.Add($cpu_datails.DeviceID, $cpu_datails); +} + +return $PhysicalCPUData; +} \ No newline at end of file diff --git a/lib/provider/disks.psm1 b/lib/provider/disks.psm1 index 8035065..d17c051 100644 --- a/lib/provider/disks.psm1 +++ b/lib/provider/disks.psm1 @@ -192,7 +192,25 @@ function Get-IcingaDiskModel return @{'value' = $DiskModel; 'name' = 'Model'}; } -function Get-IcingaDisk { +function Get-IcingaDiskManufacturer +{ + $DiskManufacturer = Get-IcingaDiskInformation -Parameter Manufacturer; + return @{'value' = $DiskManufacturer; 'name' = 'Manufacturer'}; +} + +function Get-IcingaDiskTotalCylinders +{ + $DiskTotalCylinders = Get-IcingaDiskInformation -Parameter TotalCylinders; + return @{'value' = $DiskTotalCylinders; 'name' = 'TotalCylinders'}; +} + +function Get-IcingaDiskTotalSectors +{ + $DiskTotalSectors = Get-IcingaDiskInformation -Parameter TotalSectors; + return @{'value' = $DiskTotalSectors; 'name' = 'TotalSectors'}; +} + +function Get-IcingaDisks { $DiskInformation = Get-CimInstance Win32_DiskDrive; $diskPartitionInformation = Get-IcingaDiskPartitions; From 504c18ef005e70f0f7111c036482d394c65b5884 Mon Sep 17 00:00:00 2001 From: Crited Date: Wed, 17 Jul 2019 11:28:22 +0200 Subject: [PATCH 004/259] cpu first draft --- lib/provider/cpu.psm1 | 124 +++++++++++++++++++++++- lib/provider/disks.psm1 | 2 +- lib/provider/enums.psm1 | 206 +++++++++++++++++++++++++++++++++++++++- 3 files changed, 326 insertions(+), 6 deletions(-) diff --git a/lib/provider/cpu.psm1 b/lib/provider/cpu.psm1 index 0988bdb..b34767d 100644 --- a/lib/provider/cpu.psm1 +++ b/lib/provider/cpu.psm1 @@ -1,9 +1,10 @@ -function Show-IcingaCPUData(){ +function Show-IcingaCPUData() +{ -$CPUInformations = Get-CimInstance Win32_Processor; +$CPUInformation = Get-CimInstance Win32_Processor; [hashtable]$PhysicalCPUData = @{}; -foreach ($cpu_properties in $CPUInformations) { +foreach ($cpu_properties in $CPUInformation) { $cpu_datails = @{}; foreach($cpu_core in $cpu_properties.CimInstanceProperties) { $cpu_datails.Add($cpu_core.Name, $cpu_core.Value); @@ -12,4 +13,121 @@ foreach ($cpu_properties in $CPUInformations) { } return $PhysicalCPUData; +} + +function Get-IcingaCPUs() +{ + $CPUInformation = Get-CimInstance Win32_Processor; + [hashtable]$CPUData = @{}; + + foreach ($id in $CPUInformation.DeviceID) { + $CPUData.Add( + $id, @{ + 'metadata' = @{ + 'Name' = $CPUInformation.Name; + 'DeviceID' = $CPUInformation.DeviceID; + 'ProcessorID' = $CPUInformation.ProcessorId; + 'UniqueID' = $CPUInformation.UniqueId; + 'Description' = $CPUInformation.Description; + 'OtherFamilyDescription' = $CPUInformation.OtherFamilyDescription; + 'Caption' = $CPUInformation.Caption; + 'Version' = $CPUInformation.Version; + 'SerialNumber' = $CPUInformation.SerialNumber; + 'Manufacturer' = $CPUInformation.Manufacturer; + 'Number of Cores' = $CPUInformation.NumberOfCores; + 'Family' = $CPUFamily.Family; + 'Architecture' = $CPUArchitecture.Architecture; + 'ProcessorType' = $CPUProcessorType.ProcessorType; + 'StatusInfo' = $CPUStatusInfo.StatusInfo; + 'Status' = $CPUInformation.Status; + 'CPUStatus' = $CPUInformation.CpuStatus; + 'NumberOfLogicalProcessors' = $CPUStatusInfo.NumberOfLogicalProcessors; + 'Level'= $CPUInformation.Level; + 'Availability' = $CPUAvailability.Availability; + + }; + 'errors' = @{ + 'LastErrorCode' = $CPUInformation.LastErrorCode; + 'ErrorCleared' = $CPUInformation.ErrorCleared; + 'ErrorDescription' = $CPUInformation.ErrorDescription; + 'ConfigManagerErrorCode' = $CPUConfigManagerErrorCode.ConfigManagerErrorCode; + }; + 'perfdata' = @{ + 'LoadPercentage' = $CPUInformation.LoadPercentage; + 'CurrentVoltage' = $CPUInformation.CurrentVoltage; + 'ThreadCount' = $CPUInformation.ThreadCount; + } + } + ); + } + return $CPUData; +} + + +function Get-IcingaCPUArchitecture() +{ + + $CPUInformation = Get-CimInstance Win32_Processor; + [hashtable]$CPUArchitecture = @{}; + + foreach ($id in $CPUInformation.Architecture) { + $CPUArchitecture.Add([int]$id, $ProviderEnums.CPUArchitecture.([int]$id)); + } + return @{'value' = $CPUArchitecture; 'name' = 'Architecture'}; +} + +function Get-IcingaCPUProcessorType() +{ + $CPUInformation = Get-CimInstance Win32_Processor; + [hashtable]$CPUProcessorType = @{}; + + foreach ($id in $CPUInformation.ProcessorType) { + $CPUProcessorType.Add([int]$id, $ProviderEnums.CPUProcessorType.([int]$id)); + } + return @{'value' = $CPUProcessorType; 'name' = 'ProcessorType'}; +} + +function Get-IcingaCPUStatusInfo() +{ + $CPUInformation = Get-CimInstance Win32_Processor; + [hashtable]$CPUStatusInfo = @{}; + + foreach ($id in $CPUInformation.StatusInfo) { + $CPUStatusInfo.Add([int]$id, $ProviderEnums.CPUStatusInfo.([int]$id)); + } + return @{'value' = $CPUStatusInfo; 'name' = 'StatusInfo'}; +} + +function Get-IcingaCPUFamily() +{ + $CPUInformation = Get-CimInstance Win32_Processor; + [hashtable]$CPUFamily = @{}; + + foreach ($id in $CPUInformation.Family) { + $CPUFamily.Add([int]$id, $ProviderEnums.CPUFamily.([int]$id)); + } + return @{'value' = $CPUFamily; 'name' = 'Family'}; +} + +function Get-IcingaCPUConfigManagerErrorCode() +{ + $CPUInformation = Get-CimInstance Win32_Processor; + [hashtable]$CPUConfigManagerErrorCode = @{}; + + foreach ($id in $CPUInformation.ConfigManagerErrorCode) { + $CPUConfigManagerErrorCode.Add([int]$id, $ProviderEnums.CPUConfigManagerErrorCode.([int]$id)); + } + return @{'value' = $CPUConfigManagerErrorCode; 'name' = 'ConfigManagerErrorCode'}; +} + +function Get-IcingaCPUAvailability() +{ + $CPUInformation = Get-CimInstance Win32_Processor; + [hashtable]$CPUAvailability = @{}; + + foreach ($id in $CPUInformation.Availability) { + $CPUAvailability.Add([int]$id, $ProviderEnums.CPUAvailability.([int]$id)); + } + + return @{'value' = $CPUAvailability; 'name' = 'Availability'}; } \ No newline at end of file diff --git a/lib/provider/disks.psm1 b/lib/provider/disks.psm1 index d17c051..f8af26c 100644 --- a/lib/provider/disks.psm1 +++ b/lib/provider/disks.psm1 @@ -167,7 +167,7 @@ function Get-IcingaDiskCapabilities [hashtable]$DiskCapabilities = @{}; foreach ($id in $DiskInformation.Capabilities) { - $DiskCapabilities.Add([int]$id, $ProviderEnums.Capabilities.([int]$id)); + $DiskCapabilities.Add([int]$id, $ProviderEnums.DiskCapabilities.([int]$id)); } return @{'value' = $DiskCapabilities; 'name' = 'Capabilities'}; diff --git a/lib/provider/enums.psm1 b/lib/provider/enums.psm1 index b175397..938e236 100644 --- a/lib/provider/enums.psm1 +++ b/lib/provider/enums.psm1 @@ -65,7 +65,7 @@ 63 = 'Reserved for system vendor' } -[hashtable]$Capabilities = @{ +[hashtable]$DiskCapabilities = @{ 0 = 'Unknown'; 1 = 'Other'; 2 = 'Sequential Access'; @@ -81,9 +81,211 @@ 12 = 'Predismount Eject Not Required' } +[hashtable]$CPUArchitecture = @{ + 0='x86'; + 1='MIPS'; + 2='Alpha'; + 3='PowerPC'; + 6='ia64'; + 9='x64'; +} + +[hashtable]$CPUProcessorType = @{ + 1='Other'; + 2='Unknown'; + 3='Central Processor'; + 4='Math Processor'; + 5='DSP Processor'; + 6='Video Processor'; +} + +[hashtable]$CPUStatusInfo = @{ + 1='Other' + 2='Unknown' + 3='Enabled' + 4='Disabled' + 5='Not Applicable' +} + +[hashtable]$CPUFamily = @{ + 1='Other' + 2='Unknown' + 3='8086' + 4='80286' + 5='80386' + 6='80486' + 7='8087' + 8='80287' + 9='80387' + 10='80487' + 11='Pentium(R) brand' + 12='Pentium(R) Pro' + 13='Pentium(R) II' + 14='Pentium(R) processor with MMX(TM) technology' + 15='Celeron(TM)' + 16='Pentium(R) II Xeon(TM)' + 17='Pentium(R) III' + 18='M1 Family' + 19='M2 Family' + 24='K5 Family' + 25='K6 Family' + 26='K6-2' + 27='K6-3' + 28='AMD Athlon(TM) Processor Family' + 29='AMD(R) Duron(TM) Processor' + 30='AMD29000 Family' + 31='K6-2+' + 32='Power PC Family' + 33='Power PC 601' + 34='Power PC 603' + 35='Power PC 603+' + 36='Power PC 604' + 37='Power PC 620' + 38='Power PC X704' + 39='Power PC 750' + 48='Alpha Family' + 49='Alpha 21064' + 50='Alpha 21066' + 51='Alpha 21164' + 52='Alpha 21164PC' + 53='Alpha 21164a' + 54='Alpha 21264' + 55='Alpha 21364' + 64='MIPS Family' + 65='MIPS R4000' + 66='MIPS R4200' + 67='MIPS R4400' + 68='MIPS R4600' + 69='MIPS R10000' + 80='SPARC Family' + 81='SuperSPARC' + 82='microSPARC II' + 83='microSPARC IIep' + 84='UltraSPARC' + 85='UltraSPARC II' + 86='UltraSPARC IIi' + 87='UltraSPARC III' + 88='UltraSPARC IIIi' + 96='68040' + 97='68xxx Family' + 98='68000' + 99='68010' + 100='68020' + 101='68030' + 112='Hobbit Family' + 120='Crusoe(TM) TM5000 Family' + 121='Crusoe(TM) TM3000 Family' + 122='Efficeon(TM) TM8000 Family' + 128='Weitek' + 130='Itanium(TM) Processor' + 131='AMD Athlon(TM) 64 Processor Family' + 132='AMD Opteron(TM) Family' + 144='PA-RISC Family' + 145='PA-RISC 8500' + 146='PA-RISC 8000' + 147='PA-RISC 7300LC' + 148='PA-RISC 7200' + 149='PA-RISC 7100LC' + 150='PA-RISC 7100' + 160='V30 Family' + 176='Pentium(R) III Xeon(TM)' + 177='Pentium(R) III Processor with Intel(R) SpeedStep(TM) Technology' + 178='Pentium(R) 4' + 179='Intel(R) Xeon(TM)' + 180='AS400 Family' + 181='Intel(R) Xeon(TM) processor MP' + 182='AMD AthlonXP(TM) Family' + 183='AMD AthlonMP(TM) Family' + 184='Intel(R) Itanium(R) 2' + 185='Intel Pentium M Processor' + 190='K7' + 200='IBM390 Family' + 201='G4' + 202='G5' + 203='G6' + 204='z/Architecture base' + 250='i860' + 251='i960' + 260='SH-3' + 261='SH-4' + 280='ARM' + 281='StrongARM' + 300='6x86' + 301='MediaGX' + 302='MII' + 320='WinChip' + 350='DSP' + 500='Video Processor' +} + +[hashtable]$CPUConfigManagerErrorCode = @{ + 0='This device is working properly.'; + 1='This device is not configured correctly.'; + 2='Windows cannot load the driver for this device.'; + 3='The driver for this device might be corrupted, or your system may be running low on memory or other resources.'; + 4='This device is not working properly. One of its drivers or your registry might be corrupted.'; + 5='The driver for this device needs a resource that Windows cannot manage.'; + 6='The boot configuration for this device conflicts with other devices.'; + 7='Cannot filter.'; + 8='The driver loader for the device is missing.'; + 9='This device is not working properly because the controlling firmware is reporting the resources for the device incorrectly.'; + 10='This device cannot start.'; + 11=' This device failed.'; + 12='This device cannot find enough free resources that it can use.'; + 13="Windows cannot verify this device’s resources."; + 14='This device cannot work properly until you restart your computer.'; + 15='This device is not working properly because there is probably a re-enumeration problem.'; + 16='Windows cannot identify all the resources this device uses.'; + 17='This device is asking for an unknown resource type.'; + 18='Reinstall the drivers for this device.'; + 19='Your registry might be corrupted.'; + 20='Failure using the VxD loader.'; + 21='System failure: Try changing the driver for this device. If that does not work, see your hardware documentation. Windows is removing this device.'; + 22='This device is disabled.'; + 23="System failure: Try changing the driver for this device. If that doesn’t work, see your hardware documentation."; + 24="This device is not present, is not working properly, or does not have all its drivers installed."; + 25="Windows is still setting up this device."; + 26="Windows is still setting up this device."; + 27="This device does not have valid log configuration."; + 28="The drivers for this device are not installed."; + 29="This device is disabled because the firmware of the device did not give it the required resources."; + 30="This device is using an Interrupt Request (IRQ) resource that another device is using."; + 31='This device is not working properly because Windows cannot load the drivers required for this device.'; +} + +[hashtable]$CPUAvailability = @{ + 1='Other'; + 2='Unknown'; + 3='Running/Full Power'; + 4='Warning'; + 5='In Test'; + 6='Not Applicable'; + 7='Power Off'; + 8='Off Line'; + 9='Off Duty'; + 10='Degraded'; + 11='Not Installed'; + 12='Install Error'; + 13='Power Save - Unknown'; + 14='Power Save - Low Power Mode'; + 15='Power Save - Standby'; + 16='Power Cycle'; + 17='Power Save - Warning'; + 18='Paused'; + 19='Not Ready'; + 20='Not Configured'; + 21='Quiesced'; +} + [hashtable]$ProviderEnums = @{ BiosCharacteristics = $BiosCharacteristics; - Capabilities = $Capabilities; + DiskCapabilities = $DiskCapabilities; + CPUArchitecture = $CPUArchitecture; + CPUProcessorType = $CPUProcessorType; + CPUStatusInfo = $CPUStatusInfo; + CPUFamily = $CPUFamily; + CPUConfigManagerErrorCode = $CPUConfigManagerErrorCode; + CPUAvailability = $CPUAvailability; } Export-ModuleMember -Variable @('ProviderEnums'); \ No newline at end of file From 8bce5c6a4c5f0a7053c25932f2871a2be1be5213 Mon Sep 17 00:00:00 2001 From: Crited Date: Thu, 18 Jul 2019 14:20:23 +0200 Subject: [PATCH 005/259] Major fixes regarding all lib/providers, expanded upon memory.psm1, added some comments for future reference --- lib/provider/bios.psm1 | 42 ++++- lib/provider/cpu.psm1 | 251 ++++++++++++++++++++++------ lib/provider/disks.psm1 | 28 +++- lib/provider/enums.psm1 | 343 +++++++++++++++++++++++++-------------- lib/provider/memory.psm1 | 196 ++++++++++++++++++++++ 5 files changed, 685 insertions(+), 175 deletions(-) create mode 100644 lib/provider/memory.psm1 diff --git a/lib/provider/bios.psm1 b/lib/provider/bios.psm1 index ba9655f..e2acd7f 100644 --- a/lib/provider/bios.psm1 +++ b/lib/provider/bios.psm1 @@ -1,8 +1,10 @@ Import-Module $IncludeDir\provider\enums; +<################################################################################################## +################# Runspace "Show-Icinga{BIOS}" #################################################### +##################################################################################################> function Show-IcingaBiosData() { - # Lets load some bios informations $BIOSInformation = Get-CimInstance Win32_BIOS; [hashtable]$BIOSData = @{}; @@ -15,6 +17,40 @@ function Show-IcingaBiosData() return $BIOSData; } +<################################################################################################## +################# Runspace "Get-Icinga{BIOS}" ##################################################### +##################################################################################################> +function Get-IcingaBios() +{ + <# Collects the most important BIOS informations, + e.g. name, version, manufacturer#> + $BIOSInformation = Get-CimInstance Win32_BIOS; + [hashtable]$BIOSCharacteristics = @{}; + [hashtable]$BIOSData = @{}; + + foreach ($id in $BIOSInformation.BiosCharacteristics) { + $BIOSCharacteristics.Add([string]$id, $ProviderEnums.BiosCharacteristics.Item([int]$id)); + } + + $BIOSData.Add( + 'bios', @{ + 'metadata' = @{ + 'Name' = $BIOSInformation.Name; + 'Caption' = $BIOSInformation.Caption; + 'Manufacturer' = $BIOSInformation.Manufacturer; + 'PrimaryBIOS' = $BIOSInformation.PrimaryBIOS; + 'SerialNumber' = $BIOSInformation.SerialNumber; + 'SMBIOSBIOSVersion' = $BIOSInformation.SMBIOSBIOSVersion; + 'SoftwareElementID' = $BIOSInformation.SoftwareElementID; + 'Status' = $BIOSInformation.Status; + 'Version' = $BIOSInformation.Version; + 'BiosCharacteristics' = $BIOSCharacteristics; + } + } + ); + return $BIOSData; + } + function Get-IcingaBiosSerialNumber() { $bios = Get-CimInstance Win32_BIOS; @@ -33,7 +69,7 @@ function Get-IcingaBiosManufacturer() return @{'value' = $bios.Manufacturer; 'name' = 'Manufacturer'}; } -# Primary Bios seems to be relevant in dual-bios context +# Primary Bios might be more relevant in dual bios context function Get-IcingaBiosPrimaryBios() { $bios = Get-CimInstance Win32_BIOS; @@ -78,7 +114,7 @@ function Get-IcingaBiosCharacteristics() [hashtable]$BIOSCharacteristics = @{}; foreach ($id in $bios.BiosCharacteristics) { - $BIOSCharacteristics.Add([int]$id, $ProviderEnums.BiosCharacteristics.([int]$id)); + $BIOSCharacteristics.Add([string]$id, $ProviderEnums.BiosCharacteristics.Item([int]$id)); } $output = $BIOSCharacteristics; diff --git a/lib/provider/cpu.psm1 b/lib/provider/cpu.psm1 index b34767d..bdef95a 100644 --- a/lib/provider/cpu.psm1 +++ b/lib/provider/cpu.psm1 @@ -1,3 +1,8 @@ +Import-Module $IncludeDir\provider\enums; + +<################################################################################################## +################# Runspace "Show-Icinga{CPU}" ##################################################### +##################################################################################################> function Show-IcingaCPUData() { @@ -15,12 +20,19 @@ foreach ($cpu_properties in $CPUInformation) { return $PhysicalCPUData; } +<################################################################################################## +################# Runspace "Get-Icinga{Memory}" ################################################### +##################################################################################################> function Get-IcingaCPUs() { + <# Collects the most important CPU informations, + e.g. name, version, manufacturer#> $CPUInformation = Get-CimInstance Win32_Processor; [hashtable]$CPUData = @{}; foreach ($id in $CPUInformation.DeviceID) { + $id=$id.trim('CPU'); + $CPUData.Add( $id, @{ 'metadata' = @{ @@ -34,100 +46,241 @@ function Get-IcingaCPUs() 'Version' = $CPUInformation.Version; 'SerialNumber' = $CPUInformation.SerialNumber; 'Manufacturer' = $CPUInformation.Manufacturer; - 'Number of Cores' = $CPUInformation.NumberOfCores; - 'Family' = $CPUFamily.Family; - 'Architecture' = $CPUArchitecture.Architecture; - 'ProcessorType' = $CPUProcessorType.ProcessorType; - 'StatusInfo' = $CPUStatusInfo.StatusInfo; + 'NumberOfCores' = $CPUInformation.NumberOfCores; + 'PartNumber' = $CPUInformation.PartNumber; 'Status' = $CPUInformation.Status; 'CPUStatus' = $CPUInformation.CpuStatus; - 'NumberOfLogicalProcessors' = $CPUStatusInfo.NumberOfLogicalProcessors; + 'Revision' = $CPUInformation.Revision; + 'NumberOfLogicalProcessors' = $CPUInformation.NumberOfLogicalProcessors; 'Level'= $CPUInformation.Level; - 'Availability' = $CPUAvailability.Availability; - + 'AddressWidth' = $CPUInformation.AddressWidth; + 'Stepping' = $CPUInformation.Stepping; + 'SocketDesignation' = $CPUInformation.SocketDesignation; + 'Family' = @{ + 'raw' = $CPUInformation.Family; + 'value' = $ProviderEnums.CPUFamily[[int]$CPUInformation.Family]; + }; + 'Architecture' = @{ + 'raw' = $CPUInformation.Architecture; + 'value' = $ProviderEnums.CPUArchitecture[[int]$CPUInformation.Architecture]; + }; + 'ProcessorType' = @{ + 'raw' = $CPUInformation.ProcessorType; + 'value' = $ProviderEnums.CPUProcessorType[[int]$CPUInformation.ProcessorType]; + }; + 'StatusInfo' = @{ + 'raw' = $CPUInformation.StatusInfo; + 'value' = $ProviderEnums.CPUStatusInfo[[int]$CPUInformation.StatusInfo]; + }; + 'Availability' = @{ + 'raw' = $CPUInformation.Availability; + 'value' = $ProviderEnums.CPUAvailability[[int]$CPUInformation.Availability]; + }; + 'PowerManagementCapabilities' = @{ + 'raw' = $CPUInformation.PowerManagementCapabilities; + 'value' = $ProviderEnums.CPUPowerManagementCapabilities[[int]$CPUInformation.PowerManagementCapabilities]; + } }; 'errors' = @{ 'LastErrorCode' = $CPUInformation.LastErrorCode; 'ErrorCleared' = $CPUInformation.ErrorCleared; 'ErrorDescription' = $CPUInformation.ErrorDescription; - 'ConfigManagerErrorCode' = $CPUConfigManagerErrorCode.ConfigManagerErrorCode; + 'ConfigManagerErrorCode' = @{ + 'raw' = [int]$CPUInformation.ConfigManagerErrorCode; + 'value' = $ProviderEnums.CPUConfigManagerErrorCode.([int]$CPUInformation.ConfigManagerErrorCode); + } }; - 'perfdata' = @{ + 'specs' = @{ 'LoadPercentage' = $CPUInformation.LoadPercentage; 'CurrentVoltage' = $CPUInformation.CurrentVoltage; 'ThreadCount' = $CPUInformation.ThreadCount; + 'L3CacheSize' = $CPUInformation.L3CacheSize; + 'L2CacheSpeed' = $CPUInformation.L2CacheSpeed; + 'L2CacheSize' = $CPUInformation.L2CacheSize; + 'VoltageCaps' = $CPUInformation.VoltageCaps; + 'CurrentClockSpeed' = $CPUInformation.CurrentClockSpeed; } } - ); + ); } return $CPUData; } +function Get-IcingaCPUInformation() +{ + <# Fetches the information for other more specific Get-IcingaCPU-functions + e.g. Get-IcingaCPUThreadCount; Get-IcingaCPULoadPercentage. + Can be used to fetch information regarding a value of your choice. #> + param( + [string]$Parameter + ); + $CPUInformation = Get-CimInstance Win32_Processor; + [hashtable]$CPUData = @{}; + + foreach ($id in $CPUInformation.DeviceID) { + $CPUData.Add($id.trim('CPU'), $CPUInformation.$Parameter); + } + + return $CPUData; +} + +function Get-IcingaCPUInformationWithEnums() +{ <# Fetches the information of other more specific Get-IcingaCPU-functions, + which require a enums key-value pair to resolve their code + e.g Get-IcingaCPUFamily, e.g. Get-IcingaCPUArchitecture#> + param( + [string]$Parameter + ); + + $CPUInformation = Get-CimInstance Win32_Processor; + $Prefix = "CPU"; + + [hashtable]$CPUData = @{}; + + foreach ($id in $CPUInformation.DeviceID) { + $id=$id.trim('CPU'); + $CPUData.Add( + $id, @{ + 'raw' = $CPUInformation.$Parameter; + 'value' = $ProviderEnums."$Prefix$Parameter"[[int]$CPUInformation.$Parameter] + } + ); + } + return $CPUData; +} + +function Get-IcingaCPUErrors() +{ + $CPUInformation = Get-CimInstance Win32_Processor; + [hashtable]$CPUData = @{}; + + foreach ($id in $CPUInformation.DeviceID) { + $id=$id.trim('CPU'); + $CPUData.Add( + $id, @{ + 'errors' = @{ + 'LastErrorCode' = $CPUInformation.LastErrorCode; + 'ErrorCleared' = $CPUInformation.ErrorCleared; + 'ErrorDescription' = $CPUInformation.ErrorDescription; + 'ConfigManagerErrorCode' = @{ + 'raw' = [int]$CPUInformation.ConfigManagerErrorCode; + 'value' = $ProviderEnums.CPUConfigManagerErrorCode.([int]$CPUInformation.ConfigManagerErrorCode); + } + } + } + ); + } + return $CPUData; +} function Get-IcingaCPUArchitecture() { + $CPUArchitecture = Get-IcingaCPUInformationWithEnums -Parameter Architecture; - $CPUInformation = Get-CimInstance Win32_Processor; - [hashtable]$CPUArchitecture = @{}; - - foreach ($id in $CPUInformation.Architecture) { - $CPUArchitecture.Add([int]$id, $ProviderEnums.CPUArchitecture.([int]$id)); - } - return @{'value' = $CPUArchitecture; 'name' = 'Architecture'}; + return @{'value' = $CPUArchitecture; 'name' = 'Architecture'}; } function Get-IcingaCPUProcessorType() { - $CPUInformation = Get-CimInstance Win32_Processor; - [hashtable]$CPUProcessorType = @{}; + $CPUProcessorType = Get-IcingaCPUInformationWithEnums -Parameter ProcessorType; - foreach ($id in $CPUInformation.ProcessorType) { - $CPUProcessorType.Add([int]$id, $ProviderEnums.CPUProcessorType.([int]$id)); - } - return @{'value' = $CPUProcessorType; 'name' = 'ProcessorType'}; + return @{'value' = $CPUProcessorType; 'name' = 'ProcessorType'}; } function Get-IcingaCPUStatusInfo() { - $CPUInformation = Get-CimInstance Win32_Processor; - [hashtable]$CPUStatusInfo = @{}; + $CPUStatusInfo = Get-IcingaCPUInformationWithEnums -Parameter StatusInfo; - foreach ($id in $CPUInformation.StatusInfo) { - $CPUStatusInfo.Add([int]$id, $ProviderEnums.CPUStatusInfo.([int]$id)); - } - return @{'value' = $CPUStatusInfo; 'name' = 'StatusInfo'}; + return @{'value' = $CPUStatusInfo; 'name' = 'StatusInfo'}; } function Get-IcingaCPUFamily() { - $CPUInformation = Get-CimInstance Win32_Processor; - [hashtable]$CPUFamily = @{}; + $CPUFamily = Get-IcingaCPUInformationWithEnums -Parameter Family; - foreach ($id in $CPUInformation.Family) { - $CPUFamily.Add([int]$id, $ProviderEnums.CPUFamily.([int]$id)); - } - return @{'value' = $CPUFamily; 'name' = 'Family'}; + return @{'value' = $CPUFamily; 'name' = 'Family'}; } function Get-IcingaCPUConfigManagerErrorCode() { - $CPUInformation = Get-CimInstance Win32_Processor; - [hashtable]$CPUConfigManagerErrorCode = @{}; + $CPUConfigManagerErrorCode = Get-IcingaCPUInformationWithEnums -Parameter ConfigManagerErrorCode; - foreach ($id in $CPUInformation.ConfigManagerErrorCode) { - $CPUConfigManagerErrorCode.Add([int]$id, $ProviderEnums.CPUConfigManagerErrorCode.([int]$id)); - } - return @{'value' = $CPUConfigManagerErrorCode; 'name' = 'ConfigManagerErrorCode'}; + return @{'value' = $CPUConfigManagerErrorCode; 'name' = 'ConfigManagerErrorCode'}; } function Get-IcingaCPUAvailability() { - $CPUInformation = Get-CimInstance Win32_Processor; - [hashtable]$CPUAvailability = @{}; - - foreach ($id in $CPUInformation.Availability) { - $CPUAvailability.Add([int]$id, $ProviderEnums.CPUAvailability.([int]$id)); - } + $CPUAvailability = Get-IcingaCPUInformationWithEnums -Parameter Availability; - return @{'value' = $CPUAvailability; 'name' = 'Availability'}; + return @{'value' = $CPUAvailability; 'name' = 'Availability'}; +} + +function Get-IcingaCPUPowerManagementCapabilities() +{ + $CPUPowerManagementCapabilities = Get-IcingaCPUInformationWithEnums -Parameter PowerManagementCapabilities; + + return @{'value' = $CPUPowerManagementCapabilities; 'name' = 'PowerManagementCapabilities'}; +} + +function Get-IcingaCPULoadPercentage() +{ + $CPULoadPercentage = Get-IcingaCPUInformation -Parameter LoadPercentage; + + return @{'value' = $CPULoadPercentage; 'name' = 'LoadPercentage'}; +} + +function Get-IcingaCPUCurrentVoltage() +{ + $CPUCurrentVoltage = Get-IcingaCPUInformation -Parameter CurrentVoltage; + + return @{'value' = $CPUCurrentVoltage; 'name' = 'CurrentVoltage'}; +} + +function Get-IcingaCPUThreadCount() +{ + $CPUThreadCount = Get-IcingaCPUInformation -Parameter ThreadCount; + + return @{'value' = $CPUThreadCount; 'name' = 'ThreadCount'}; +} + +function Get-IcingaCPUL3CacheSize() +{ + $CPUL3CacheSize = Get-IcingaCPUInformation -Parameter L3CacheSize; + + return @{'value' = $CPUL3CacheSize; 'name' = 'L3CacheSize'}; +} + +function Get-IcingaCPUL2CacheSize() +{ + $CPUL2CacheSize = Get-IcingaCPUInformation -Parameter L2CacheSize; + + return @{'value' = $CPUL2CacheSize; 'name' = 'L2CacheSize'}; +} + +function Get-IcingaCPUL2CacheSpeed() +{ + $CPUL2CacheSpeed = Get-IcingaCPUInformation -Parameter L2CacheSpeed; + + return @{'value' = $CPUL2CacheSpeed; 'name' = 'L2CacheSpeed'}; +} + +function Get-IcingaCPUVoltageCaps() +{ + $CPUVoltageCaps = Get-IcingaCPUInformation -Parameter VoltageCaps; + + return @{'value' = $CPUVoltageCaps; 'name' = 'VoltageCaps'}; +} + +function Get-IcingaCPUCurrentClockSpeed() +{ + $CPUCurrentClockSpeed = Get-IcingaCPUInformation -Parameter CurrentClockSpeed; + + return @{'value' = $CPUCurrentClockSpeed; 'name' = 'CurrentClockSpeed'}; +} + +function Get-IcingaCPUNumberOfLogicalProcessors() +{ + $CPUNumberOfLogicalProcessors = Get-IcingaCPUInformation -Parameter NumberOfLogicalProcessors; + + return @{'value' = $CPUNumberOfLogicalProcessors; 'name' = 'NumberOfLogicalProcessors'}; } \ No newline at end of file diff --git a/lib/provider/disks.psm1 b/lib/provider/disks.psm1 index f8af26c..d689a33 100644 --- a/lib/provider/disks.psm1 +++ b/lib/provider/disks.psm1 @@ -1,4 +1,10 @@ -function Show-IcingaDiskFullData { +Import-Module $IncludeDir\provider\enums; + +<################################################################################################## +################# Runspace "Show-Icinga{Disk}" #################################################### +##################################################################################################> + +function Show-IcingaDiskData { $DisksInformations = Get-CimInstance Win32_DiskDrive; @@ -84,8 +90,15 @@ function Show-IcingaDiskPhysical() return $PhysicalDiskData; } +<################################################################################################## +################# Runspace "Get-Icinga{Disk}" #################################################### +##################################################################################################> + function Get-IcingaDiskInformation() { + <# Fetches the information for other more specific Get-IcingaDisk-functions + e.g. Get-IcingaDiskModel; Get-IcingaDiskManufacturer. + Can be used to fetch information regarding a value of your choice. #> param( # The value to fetch from Win32_DiskDrive [string]$Parameter @@ -93,7 +106,7 @@ function Get-IcingaDiskInformation() $DiskInformation = Get-CimInstance Win32_DiskDrive; [hashtable]$DiskData = @{}; - foreach ($id in $DiskInformation.DeviceID) { + foreach ($id in $DiskInformation.DeviceID) { $id = $id.trimstart(".\PHYSICALDRVE"); $DiskData.Add($id.trim(), $DiskInformation.$Parameter); } @@ -102,6 +115,9 @@ function Get-IcingaDiskInformation() } function Get-IcingaDiskPartitions() { + <# Fetches all the most important informations regarding partitions + e.g. physical disk; partition, size + , also collects partition information for Get-IcingaDisks #> $LogicalDiskInfo = Get-WmiObject Win32_LogicalDiskToPartition; [hashtable]$PartitionDiskByDriveLetter = @{}; @@ -141,7 +157,7 @@ function Get-IcingaDiskPartitionSize() [hashtable]$PartitionSizeByDriveLetter = @{}; - # Should be dependent on the driveLetters returned in: "Show-IcingaDiskFullData" + # Should be dependent on the driveLetters returned in: "Show-IcingaDiskData" for ($test = 0; $test -lt 26; $test++) { $DiskDriveLetter = ([char](65 + $test)) @@ -211,12 +227,14 @@ function Get-IcingaDiskTotalSectors } function Get-IcingaDisks { - + <# Collects all the most important Disk-Informations, + e.g. size, model, sectors, cylinders + Is dependent on Get-IcingaDiskPartitions#> $DiskInformation = Get-CimInstance Win32_DiskDrive; $diskPartitionInformation = Get-IcingaDiskPartitions; [hashtable]$DiskData = @{}; - foreach ($id in $DiskInformation.DeviceID) { + foreach ($id in $DiskInformation.DeviceID) { [int]$id = $id.trimstart(".\PHYSICALDRVE"); $DiskData.Add( diff --git a/lib/provider/enums.psm1 b/lib/provider/enums.psm1 index 938e236..6903ec0 100644 --- a/lib/provider/enums.psm1 +++ b/lib/provider/enums.psm1 @@ -1,8 +1,13 @@ -[hashtable]$BiosCharacteristics = @{ + +<################################################################################################## +################# /lib/provider/bios.psm1 ######################################################### +##################################################################################################> + +[hashtable]$BiosCharacteristics = @{ 0 = 'Reserved'; 1 = 'Reserved'; 2 = 'Unknown'; - 3 = 'BIOS Characteristics Not Supported'; + 3 = 'BIOS Characteristics Not Supported'; 4 = 'ISA is supported'; 5 = 'MCA is supported'; 6 = 'EISA is supported'; @@ -65,7 +70,11 @@ 63 = 'Reserved for system vendor' } -[hashtable]$DiskCapabilities = @{ +<################################################################################################## +################# /lib/provider/disks.psm1 ######################################################## +##################################################################################################> + +[hashtable]$DiskCapabilities = @{ 0 = 'Unknown'; 1 = 'Other'; 2 = 'Sequential Access'; @@ -78,9 +87,13 @@ 9 = 'Automatic Cleaning'; 10 = 'SMART Notification'; 11 = 'Supports Dual Sided Media'; - 12 = 'Predismount Eject Not Required' + 12 = 'Predismount Eject Not Required'; } +<################################################################################################## +################# /lib/provider/cpu.psm1 ########################################################## +##################################################################################################> + [hashtable]$CPUArchitecture = @{ 0='x86'; 1='MIPS'; @@ -100,122 +113,122 @@ } [hashtable]$CPUStatusInfo = @{ - 1='Other' - 2='Unknown' - 3='Enabled' - 4='Disabled' - 5='Not Applicable' + 1='Other'; + 2='Unknown'; + 3='Enabled'; + 4='Disabled'; + 5='Not Applicable'; } [hashtable]$CPUFamily = @{ - 1='Other' - 2='Unknown' - 3='8086' - 4='80286' - 5='80386' - 6='80486' - 7='8087' - 8='80287' - 9='80387' - 10='80487' - 11='Pentium(R) brand' - 12='Pentium(R) Pro' - 13='Pentium(R) II' - 14='Pentium(R) processor with MMX(TM) technology' - 15='Celeron(TM)' - 16='Pentium(R) II Xeon(TM)' - 17='Pentium(R) III' - 18='M1 Family' - 19='M2 Family' - 24='K5 Family' - 25='K6 Family' - 26='K6-2' - 27='K6-3' - 28='AMD Athlon(TM) Processor Family' - 29='AMD(R) Duron(TM) Processor' - 30='AMD29000 Family' - 31='K6-2+' - 32='Power PC Family' - 33='Power PC 601' - 34='Power PC 603' - 35='Power PC 603+' - 36='Power PC 604' - 37='Power PC 620' - 38='Power PC X704' - 39='Power PC 750' - 48='Alpha Family' - 49='Alpha 21064' - 50='Alpha 21066' - 51='Alpha 21164' - 52='Alpha 21164PC' - 53='Alpha 21164a' - 54='Alpha 21264' - 55='Alpha 21364' - 64='MIPS Family' - 65='MIPS R4000' - 66='MIPS R4200' - 67='MIPS R4400' - 68='MIPS R4600' - 69='MIPS R10000' - 80='SPARC Family' - 81='SuperSPARC' - 82='microSPARC II' - 83='microSPARC IIep' - 84='UltraSPARC' - 85='UltraSPARC II' - 86='UltraSPARC IIi' - 87='UltraSPARC III' - 88='UltraSPARC IIIi' - 96='68040' - 97='68xxx Family' - 98='68000' - 99='68010' - 100='68020' - 101='68030' - 112='Hobbit Family' - 120='Crusoe(TM) TM5000 Family' - 121='Crusoe(TM) TM3000 Family' - 122='Efficeon(TM) TM8000 Family' - 128='Weitek' - 130='Itanium(TM) Processor' - 131='AMD Athlon(TM) 64 Processor Family' - 132='AMD Opteron(TM) Family' - 144='PA-RISC Family' - 145='PA-RISC 8500' - 146='PA-RISC 8000' - 147='PA-RISC 7300LC' - 148='PA-RISC 7200' - 149='PA-RISC 7100LC' - 150='PA-RISC 7100' - 160='V30 Family' - 176='Pentium(R) III Xeon(TM)' - 177='Pentium(R) III Processor with Intel(R) SpeedStep(TM) Technology' - 178='Pentium(R) 4' - 179='Intel(R) Xeon(TM)' - 180='AS400 Family' - 181='Intel(R) Xeon(TM) processor MP' - 182='AMD AthlonXP(TM) Family' - 183='AMD AthlonMP(TM) Family' - 184='Intel(R) Itanium(R) 2' - 185='Intel Pentium M Processor' - 190='K7' - 200='IBM390 Family' - 201='G4' - 202='G5' - 203='G6' - 204='z/Architecture base' - 250='i860' - 251='i960' - 260='SH-3' - 261='SH-4' - 280='ARM' - 281='StrongARM' - 300='6x86' - 301='MediaGX' - 302='MII' - 320='WinChip' - 350='DSP' - 500='Video Processor' + 1='Other'; + 2='Unknown'; + 3='8086'; + 4='80286'; + 5='80386'; + 6='80486'; + 7='8087'; + 8='80287'; + 9='80387'; + 10='80487'; + 11='Pentium(R) brand'; + 12='Pentium(R) Pro'; + 13='Pentium(R) II'; + 14='Pentium(R) processor with MMX(TM) technology'; + 15='Celeron(TM)'; + 16='Pentium(R) II Xeon(TM)'; + 17='Pentium(R) III'; + 18='M1 Family'; + 19='M2 Family'; + 24='K5 Family'; + 25='K6 Family'; + 26='K6-2'; + 27='K6-3'; + 28='AMD Athlon(TM) Processor Family'; + 29='AMD(R) Duron(TM) Processor'; + 30='AMD29000 Family'; + 31='K6-2+'; + 32='Power PC Family'; + 33='Power PC 601'; + 34='Power PC 603'; + 35='Power PC 603+'; + 36='Power PC 604'; + 37='Power PC 620'; + 38='Power PC X704'; + 39='Power PC 750'; + 48='Alpha Family'; + 49='Alpha 21064'; + 50='Alpha 21066'; + 51='Alpha 21164'; + 52='Alpha 21164PC'; + 53='Alpha 21164a'; + 54='Alpha 21264'; + 55='Alpha 21364'; + 64='MIPS Family'; + 65='MIPS R4000'; + 66='MIPS R4200'; + 67='MIPS R4400'; + 68='MIPS R4600'; + 69='MIPS R10000'; + 80='SPARC Family'; + 81='SuperSPARC'; + 82='microSPARC II'; + 83='microSPARC IIep'; + 84='UltraSPARC'; + 85='UltraSPARC II'; + 86='UltraSPARC IIi'; + 87='UltraSPARC III'; + 88='UltraSPARC IIIi'; + 96='68040'; + 97='68xxx Family'; + 98='68000'; + 99='68010'; + 100='68020'; + 101='68030'; + 112='Hobbit Family'; + 120='Crusoe(TM) TM5000 Family'; + 121='Crusoe(TM) TM3000 Family'; + 122='Efficeon(TM) TM8000 Family'; + 128='Weitek'; + 130='Itanium(TM) Processor'; + 131='AMD Athlon(TM) 64 Processor Family'; + 132='AMD Opteron(TM) Family'; + 144='PA-RISC Family'; + 145='PA-RISC 8500'; + 146='PA-RISC 8000'; + 147='PA-RISC 7300LC'; + 148='PA-RISC 7200'; + 149='PA-RISC 7100LC'; + 150='PA-RISC 7100'; + 160='V30 Family'; + 176='Pentium(R) III Xeon(TM)'; + 177='Pentium(R) III Processor with Intel(R) SpeedStep(TM) Technology'; + 178='Pentium(R) 4'; + 179='Intel(R) Xeon(TM)'; + 180='AS400 Family'; + 181='Intel(R) Xeon(TM) processor MP'; + 182='AMD AthlonXP(TM) Family'; + 183='AMD AthlonMP(TM) Family'; + 184='Intel(R) Itanium(R) 2'; + 185='Intel Pentium M Processor'; + 190='K7'; + 200='IBM390 Family'; + 201='G4'; + 202='G5'; + 203='G6'; + 204='z/Architecture base'; + 250='i860'; + 251='i960'; + 260='SH-3'; + 261='SH-4'; + 280='ARM'; + 281='StrongARM'; + 300='6x86'; + 301='MediaGX'; + 302='MII'; + 320='WinChip'; + 350='DSP'; + 500='Video Processor'; } [hashtable]$CPUConfigManagerErrorCode = @{ @@ -277,15 +290,109 @@ 21='Quiesced'; } -[hashtable]$ProviderEnums = @{ +[hashtable]$CPUPowerManagementCapabilities = @{ + 0='Unknown'; + 1='Not Supported'; + 2='Disabled'; + 3='Enabled'; +} + +[hashtable]$MemoryFormFactor = @{ + 0='Unknown'; + 1= 'Other'; + 2= 'SIP'; + 3= 'DIP'; + 4= 'ZIP'; + 5= 'SOJ'; + 6= 'Proprietary'; + 7= 'SIMM'; + 8= 'DIMM'; + 9= 'TSOP'; + 10= 'PGA'; + 11= 'RIMM'; + 12= 'SODIMM'; + 13= 'SRIMM'; + 14= 'SMD'; + 15= 'SSMP'; + 16= 'QFP'; + 17= 'TQFP'; + 18= 'SOIC'; + 19= 'LCC'; + 20= 'PLCC'; + 21= 'BGA'; + 22= 'FPBGA'; + 23= 'LGA'; +} + +[hashtable]$MemoryInterleavePosition = @{ + 0= 'Noninterleaved'; + 1= 'First position'; + 2= 'Second position'; +} + +[hashtable]$MemoryMemoryType = @{ + 0= 'Unknown'; + 1= 'Other'; + 2= 'DRAM'; + 3= 'Synchronous DRAM'; + 4= 'Cache DRAM'; + 5= 'EDO'; + 6= 'EDRAM'; + 7= 'VRAM'; + 8= 'SRAM'; + 9= 'RAM'; + 10= 'ROM'; + 11= 'Flash'; + 12='EEPROM'; + 13= 'FEPROM'; + 14= 'EPROM'; + 15= 'CDRAM'; + 16= '3DRAM'; + 17= 'SDRAM'; + 18= 'SGRAM'; + 19= 'RDRAM'; + 20= 'DDR'; + 21= 'DDR2'; + 22= 'DDR2 FB-DIMM'; + 23= 'DDR2—FB-DIMM,May not be available; see note above.'; + 24= 'DDR3—May not be available; see note above.'; + 25= 'FBD2'; +} + +[hashtable]$MemoryTypeDetail = @{ + 1= 'Reserved'; + 2= 'Other'; + 4= 'Unknown'; + 8= 'Fast-paged'; + 16= 'Static column'; + 32= 'Pseudo-static'; + 64= 'RAMBUS'; + 128= 'Synchronous'; + 256= 'CMOS'; + 512= 'EDO'; + 1024= 'Window DRAM'; + 2048= 'Cache DRAM'; + 4096= 'Non-volatile'; +} + +[hashtable]$ProviderEnums = @{ + #/lib/provider/bios.psm1 BiosCharacteristics = $BiosCharacteristics; + #/lib/provider/disks.psm1 DiskCapabilities = $DiskCapabilities; + #/lib/provider/cpu.psm1 CPUArchitecture = $CPUArchitecture; CPUProcessorType = $CPUProcessorType; CPUStatusInfo = $CPUStatusInfo; CPUFamily = $CPUFamily; CPUConfigManagerErrorCode = $CPUConfigManagerErrorCode; CPUAvailability = $CPUAvailability; + CPUPowerManagementCapabilities = $CPUPowerManagementCapabilities; + #/lib/provider/memory.psm1 + MemoryFormFactor = $MemoryFormFactor; + MemoryInterleavePosition = $MemoryInterleavePosition; + MemoryMemoryType = $MemoryMemoryType; + MemoryTypeDetail = $MemoryTypeDetail; } Export-ModuleMember -Variable @('ProviderEnums'); \ No newline at end of file diff --git a/lib/provider/memory.psm1 b/lib/provider/memory.psm1 new file mode 100644 index 0000000..da6edd0 --- /dev/null +++ b/lib/provider/memory.psm1 @@ -0,0 +1,196 @@ +Import-Module $IncludeDir\provider\enums; + +<################################################################################################## +################# Runspace "Show-Icinga{Memory}" ################################################## +##################################################################################################> +function Show-IcingaMemoryData () +{ + + $MEMInformation = Get-CimInstance Win32_PhysicalMemory; + + [hashtable]$MEMData = @{}; + + foreach($id in $MEMInformation) { + $MEMData.Add( + $id.tag.trim("Physical Memory"), @{ + 'Caption' = $id.Name; + 'Description' = $id.Description; + 'Name' = $id.Name; + 'InstallDate' = $id.InstallDate; + 'Status' = $id.Status + 'CreationClassName'= $id.CreationClassName + 'Manufacturer'= $id.Manufacturer + 'Model'= $id.Model + 'OtherIdentifyingInfo'= $id.OtherIdentifyingInfo + 'PartNumber'= $id.PartNumber + 'PoweredOn'= $id.PoweredOn + 'SerialNumber'= $id.SerialNumber + 'SKU'= $id.SKU + 'Tag'= $id.Tag + 'Version'= $id.Version + 'HotSwappable'= $id.HotSwappable + 'Removable'= $id.Removable + 'Replaceable'= $id.Replaceable + 'FormFactor'= $id.FormFactor + 'BankLabel'= $id.BankLabel + 'Capacity'= $id.Capacity + 'DataWidth'= $id.DataWidth + 'InterleavePosition'= $id.InterleavePosition + 'MemoryType'= $id.MemoryType + 'PositionInRow'= $id.PositionInRow + 'Speed'= $id.Speed + 'TotalWidth'= $id.TotalWidth + 'Attributes'= $id.Attributes + 'ConfiguredClockSpeed'= $id.ConfiguredClockSpeed + 'ConfiguredVoltage'= $id.ConfiguredVoltage + 'DeviceLocator'= $id.DeviceLocator + 'InterleaveDataDepth'= $id.InterleaveDataDepth + 'MaxVoltage'= $id.MaxVoltage + 'MinVoltage'= $id.MinVoltage + 'SMBIOSMemoryType'= $id.SMBIOSMemoryType + 'TypeDetail'= $id.TypeDetail + 'PSComputerName'= $id.PSComputerName + } + ); + } + return $MEMData; +} +<################################################################################################## +################# Runspace "Get-Icinga{Memory}" ################################################### +##################################################################################################> +function Get-IcingaMemory () +{ + <# Collects the most important Memory informations, + e.g. name, version, manufacturer#> + $MEMInformation = Get-CimInstance Win32_PhysicalMemory; + + [hashtable]$MEMData = @{}; + + foreach($id in $MEMInformation) { + $MEMData.Add( + $id.tag.trim("Physical Memory"), @{ + 'metadata' = @{ + 'Caption' = $id.Name; + 'Description'= $id.Description; + 'Manufacturer'= $id.Manufacturer; + 'Model'= $id.Model; + 'OtherIdentifyingInfo'= $id.OtherIdentifyingInfo; + 'PartNumber'= $id.PartNumber; + 'SerialNumber'= $id.SerialNumber; + 'Tag'= $id.Tag; + 'SMBIOSMemoryType'= $id.SMBIOSMemoryType; + 'DeviceLocator' = $id.DeviceLocator; + 'PositionInRow' = $id.PositionInRow; + 'Version' = $id.Version; + 'PoweredOn' = $id.PoweredOn; + 'Status' = $id.Status; + 'InstallDate' = $id.InstallDate; + 'BankLabel' = $id.BankLabel; + 'InterleaveDataDepth' = $id.InterleaveDataDepth; + 'Attributes' = $id.Attributes; + 'Replaceable' = $id.Replaceable; + 'Removable' = $id.Removable; + 'HotSwappable' = $id.HotSwappable; + 'FormFactor' = @{ + 'raw' = $id.FormFactor; + 'value' = $ProviderEnums.MemoryFormFactor[[int]$id.FormFactor]; + }; + 'InterleavePosition' = @{ + 'raw' = $id.InterleavePosition; + 'value' = $ProviderEnums.MemoryInterleavePosition[[int]$id.InterleavePosition]; + }; + 'MemoryType' = @{ + 'raw' = $id.MemoryType; + 'value' = $ProviderEnums.MemoryMemoryType[[int]$id.MemoryType]; + }; + 'TypeDetail' = @{ + 'raw' = $id.TypeDetail; + 'value' = $ProviderEnums.MemoryTypeDetail[[int]$id.TypeDetail]; + }; + }; + 'specs' = @{ + 'MaxVoltage' = $id.MaxVoltage; + 'MinVoltage' = $id.MinVoltage; + 'ConfiguredVoltage' = $id.ConfiguredVoltage; + 'ConfiguredClockSpeed' = $id.ConfiguredClockSpeed; + 'TotalWidth' = $id.TotalWidth; + 'DataWidth' = $id.DataWidth; + 'Speed' = $id.Speed; + 'Capacity' = $id.Capacity; + } + } + ); + } + + return $MEMData; +} + +function Get-IcingaMemoryInformation() +{ + param( + [string]$Parameter + ); + $MEMInformation = Get-CimInstance Win32_PhysicalMemory; + [hashtable]$MEMData = @{}; + + foreach ($id in $MEMInformation) { + $MEMData.Add($id.tag.trim("Physical Memory"), $id.$Parameter); + } + + return $MEMData; +} +function Get-IcingaMemoryMaxVoltage() +{ + $MemoryMaxVoltage = Get-IcingaMemoryInformation -Parameter MaxVoltage; + + return @{'value' = $MemoryMaxVoltage; 'name' = 'MaxVoltage'}; +} + +function Get-IcingaMemoryMinVoltage() +{ + $MemoryMinVoltage = Get-IcingaMemoryInformation -Parameter MinVoltage; + + return @{'value' = $MemoryMinVoltage; 'name' = 'MinVoltage'}; +} + +function Get-IcingaMemoryConfiguredVoltage() +{ + $MemoryConfiguredVoltage = Get-IcingaMemoryInformation -Parameter ConfiguredVoltage; + + return @{'value' = $MemoryConfiguredVoltage; 'name' = 'ConfiguredVoltage'}; +} + +function Get-IcingaMemoryConfiguredClockSpeed() +{ + $MemoryConfiguredClockSpeed = Get-IcingaMemoryInformation -Parameter ConfiguredClockSpeed; + + return @{'value' = $MemoryConfiguredClockSpeed; 'name' = 'ConfiguredClockSpeed'}; +} + +function Get-IcingaMemoryTotalWidth() +{ + $MemoryTotalWidth = Get-IcingaMemoryInformation -Parameter TotalWidth; + + return @{'value' = $MemoryTotalWidth; 'name' = 'TotalWidth'}; +} + +function Get-IcingaMemoryDataWidth() +{ + $MemoryDataWidth = Get-IcingaMemoryInformation -Parameter DataWidth; + + return @{'value' = $MemoryDataWidth; 'name' = 'DataWidth'}; +} + +function Get-IcingaMemorySpeed() +{ + $MemorySpeed = Get-IcingaMemoryInformation -Parameter Speed; + + return @{'value' = $MemorySpeed; 'name' = 'Speed'}; +} + +function Get-IcingaMemoryCapacity() +{ + $MemoryCapacity = Get-IcingaMemoryInformation -Parameter Capacity; + + return @{'value' = $MemoryCapacity; 'name' = 'Capacity'}; +} \ No newline at end of file From 97ee39486a681d750e4f00ffd2d4a1da00f68352 Mon Sep 17 00:00:00 2001 From: Crited Date: Mon, 22 Jul 2019 07:32:52 +0200 Subject: [PATCH 006/259] Added Process.psm1, Added Services.psm1; Fixed previous concept errors --- lib/provider/cpu.psm1 | 143 ++++++++++++++++++--------------- lib/provider/disks.psm1 | 42 ++++++---- lib/provider/enums.psm1 | 4 + lib/provider/memory.psm1 | 160 ++++++++++++++++++------------------- lib/provider/process.psm1 | 124 ++++++++++++++++++++++++++++ lib/provider/services.psm1 | 61 ++++++++++++++ 6 files changed, 374 insertions(+), 160 deletions(-) create mode 100644 lib/provider/process.psm1 create mode 100644 lib/provider/services.psm1 diff --git a/lib/provider/cpu.psm1 b/lib/provider/cpu.psm1 index bdef95a..986a9f9 100644 --- a/lib/provider/cpu.psm1 +++ b/lib/provider/cpu.psm1 @@ -30,75 +30,74 @@ function Get-IcingaCPUs() $CPUInformation = Get-CimInstance Win32_Processor; [hashtable]$CPUData = @{}; - foreach ($id in $CPUInformation.DeviceID) { - $id=$id.trim('CPU'); + foreach ($cpu in $CPUInformation) { $CPUData.Add( - $id, @{ + $cpu.DeviceID.trim('CPU'), @{ 'metadata' = @{ - 'Name' = $CPUInformation.Name; - 'DeviceID' = $CPUInformation.DeviceID; - 'ProcessorID' = $CPUInformation.ProcessorId; - 'UniqueID' = $CPUInformation.UniqueId; - 'Description' = $CPUInformation.Description; - 'OtherFamilyDescription' = $CPUInformation.OtherFamilyDescription; - 'Caption' = $CPUInformation.Caption; - 'Version' = $CPUInformation.Version; - 'SerialNumber' = $CPUInformation.SerialNumber; - 'Manufacturer' = $CPUInformation.Manufacturer; - 'NumberOfCores' = $CPUInformation.NumberOfCores; - 'PartNumber' = $CPUInformation.PartNumber; - 'Status' = $CPUInformation.Status; - 'CPUStatus' = $CPUInformation.CpuStatus; - 'Revision' = $CPUInformation.Revision; - 'NumberOfLogicalProcessors' = $CPUInformation.NumberOfLogicalProcessors; - 'Level'= $CPUInformation.Level; - 'AddressWidth' = $CPUInformation.AddressWidth; - 'Stepping' = $CPUInformation.Stepping; - 'SocketDesignation' = $CPUInformation.SocketDesignation; + 'Name' = $cpu.Name; + 'DeviceID' = $cpu.DeviceID; + 'ProcessorID' = $cpu.ProcessorId; + 'UniqueID' = $cpu.UniqueId; + 'Description' = $cpu.Description; + 'OtherFamilyDescription' = $cpu.OtherFamilyDescription; + 'Caption' = $cpu.Caption; + 'Version' = $cpu.Version; + 'SerialNumber' = $cpu.SerialNumber; + 'Manufacturer' = $cpu.Manufacturer; + 'NumberOfCores' = $cpu.NumberOfCores; + 'PartNumber' = $cpu.PartNumber; + 'Status' = $cpu.Status; + 'CPUStatus' = $cpu.CpuStatus; + 'Revision' = $cpu.Revision; + 'NumberOfLogicalProcessors' = $cpu.NumberOfLogicalProcessors; + 'Level'= $cpu.Level; + 'AddressWidth' = $cpu.AddressWidth; + 'Stepping' = $cpu.Stepping; + 'SocketDesignation' = $cpu.SocketDesignation; 'Family' = @{ - 'raw' = $CPUInformation.Family; - 'value' = $ProviderEnums.CPUFamily[[int]$CPUInformation.Family]; + 'raw' = $cpu.Family; + 'value' = $ProviderEnums.CPUFamily[[int]$cpu.Family]; }; 'Architecture' = @{ - 'raw' = $CPUInformation.Architecture; - 'value' = $ProviderEnums.CPUArchitecture[[int]$CPUInformation.Architecture]; + 'raw' = $cpu.Architecture; + 'value' = $ProviderEnums.CPUArchitecture[[int]$cpu.Architecture]; }; 'ProcessorType' = @{ - 'raw' = $CPUInformation.ProcessorType; - 'value' = $ProviderEnums.CPUProcessorType[[int]$CPUInformation.ProcessorType]; + 'raw' = $cpu.ProcessorType; + 'value' = $ProviderEnums.CPUProcessorType[[int]$cpu.ProcessorType]; }; 'StatusInfo' = @{ - 'raw' = $CPUInformation.StatusInfo; - 'value' = $ProviderEnums.CPUStatusInfo[[int]$CPUInformation.StatusInfo]; + 'raw' = $cpu.StatusInfo; + 'value' = $ProviderEnums.CPUStatusInfo[[int]$cpu.StatusInfo]; }; 'Availability' = @{ - 'raw' = $CPUInformation.Availability; - 'value' = $ProviderEnums.CPUAvailability[[int]$CPUInformation.Availability]; + 'raw' = $cpu.Availability; + 'value' = $ProviderEnums.CPUAvailability[[int]$cpu.Availability]; }; 'PowerManagementCapabilities' = @{ - 'raw' = $CPUInformation.PowerManagementCapabilities; - 'value' = $ProviderEnums.CPUPowerManagementCapabilities[[int]$CPUInformation.PowerManagementCapabilities]; + 'raw' = $cpu.PowerManagementCapabilities; + 'value' = $ProviderEnums.CPUPowerManagementCapabilities[[int]$cpu.PowerManagementCapabilities]; } }; 'errors' = @{ - 'LastErrorCode' = $CPUInformation.LastErrorCode; - 'ErrorCleared' = $CPUInformation.ErrorCleared; - 'ErrorDescription' = $CPUInformation.ErrorDescription; + 'LastErrorCode' = $cpu.LastErrorCode; + 'ErrorCleared' = $cpu.ErrorCleared; + 'ErrorDescription' = $cpu.ErrorDescription; 'ConfigManagerErrorCode' = @{ - 'raw' = [int]$CPUInformation.ConfigManagerErrorCode; - 'value' = $ProviderEnums.CPUConfigManagerErrorCode.([int]$CPUInformation.ConfigManagerErrorCode); + 'raw' = [int]$cpu.ConfigManagerErrorCode; + 'value' = $ProviderEnums.CPUConfigManagerErrorCode.([int]$cpu.ConfigManagerErrorCode); } }; 'specs' = @{ - 'LoadPercentage' = $CPUInformation.LoadPercentage; - 'CurrentVoltage' = $CPUInformation.CurrentVoltage; - 'ThreadCount' = $CPUInformation.ThreadCount; - 'L3CacheSize' = $CPUInformation.L3CacheSize; - 'L2CacheSpeed' = $CPUInformation.L2CacheSpeed; - 'L2CacheSize' = $CPUInformation.L2CacheSize; - 'VoltageCaps' = $CPUInformation.VoltageCaps; - 'CurrentClockSpeed' = $CPUInformation.CurrentClockSpeed; + 'LoadPercentage' = $cpu.LoadPercentage; + 'CurrentVoltage' = $cpu.CurrentVoltage; + 'ThreadCount' = $cpu.ThreadCount; + 'L3CacheSize' = $cpu.L3CacheSize; + 'L2CacheSpeed' = $cpu.L2CacheSpeed; + 'L2CacheSize' = $cpu.L2CacheSize; + 'VoltageCaps' = $cpu.VoltageCaps; + 'CurrentClockSpeed' = $cpu.CurrentClockSpeed; } } ); @@ -117,8 +116,8 @@ function Get-IcingaCPUInformation() $CPUInformation = Get-CimInstance Win32_Processor; [hashtable]$CPUData = @{}; - foreach ($id in $CPUInformation.DeviceID) { - $CPUData.Add($id.trim('CPU'), $CPUInformation.$Parameter); + foreach ($cpu in $CPUInformation) { + $CPUData.Add($cpu.DeviceID.trim('CPU'), $cpu.$Parameter); } return $CPUData; @@ -137,12 +136,11 @@ function Get-IcingaCPUInformationWithEnums() [hashtable]$CPUData = @{}; - foreach ($id in $CPUInformation.DeviceID) { - $id=$id.trim('CPU'); + foreach ($cpu in $CPUInformation) { $CPUData.Add( - $id, @{ - 'raw' = $CPUInformation.$Parameter; - 'value' = $ProviderEnums."$Prefix$Parameter"[[int]$CPUInformation.$Parameter] + $cpu.DeviceID.trim('CPU'), @{ + 'raw' = $cpu.$Parameter; + 'value' = $ProviderEnums."$Prefix$Parameter"[[int]$cpu.$Parameter] } ); } @@ -154,17 +152,16 @@ function Get-IcingaCPUErrors() $CPUInformation = Get-CimInstance Win32_Processor; [hashtable]$CPUData = @{}; - foreach ($id in $CPUInformation.DeviceID) { - $id=$id.trim('CPU'); + foreach ($cpu in $CPUInformation) { $CPUData.Add( - $id, @{ + $cpu.trim('CPU'), @{ 'errors' = @{ - 'LastErrorCode' = $CPUInformation.LastErrorCode; - 'ErrorCleared' = $CPUInformation.ErrorCleared; - 'ErrorDescription' = $CPUInformation.ErrorDescription; + 'LastErrorCode' = $cpu.LastErrorCode; + 'ErrorCleared' = $cpu.ErrorCleared; + 'ErrorDescription' = $cpu.ErrorDescription; 'ConfigManagerErrorCode' = @{ - 'raw' = [int]$CPUInformation.ConfigManagerErrorCode; - 'value' = $ProviderEnums.CPUConfigManagerErrorCode.([int]$CPUInformation.ConfigManagerErrorCode); + 'raw' = [int]$cpu.ConfigManagerErrorCode; + 'value' = $ProviderEnums.CPUConfigManagerErrorCode.([int]$cpu.ConfigManagerErrorCode); } } } @@ -283,4 +280,24 @@ function Get-IcingaCPUNumberOfLogicalProcessors() $CPUNumberOfLogicalProcessors = Get-IcingaCPUInformation -Parameter NumberOfLogicalProcessors; return @{'value' = $CPUNumberOfLogicalProcessors; 'name' = 'NumberOfLogicalProcessors'}; +} + +function Get-IcingaCPUCount() +{ + <# Collects the most important CPU informations, + e.g. name, version, manufacturer#> + $CPUInformation = Get-CimInstance Win32_Processor; + + foreach ($cpu in $CPUInformation) { + $NumberOfCoresValue += $cpu.NumberOfCores; + $NumberOfLogicalProcessorsValue += $cpu.NumberOfLogicalProcessors; + $ThreadCountValue += $cpu.ThreadCount; + } + + If (($NumberOfCoresValue -ge $NumberOfLogicalProcessorsValue) -and ($NumberOfCoresValue -ge $ThreadCountValue)) { + return $NumberOfCoresValue; + } elseif ($NumberOfLogicalProcessorsValue -ge $ThreadCountValue) { + return $NumberOfLogicalProcessorsValue; + } + return $ThreadCountValue; } \ No newline at end of file diff --git a/lib/provider/disks.psm1 b/lib/provider/disks.psm1 index d689a33..eed30ec 100644 --- a/lib/provider/disks.psm1 +++ b/lib/provider/disks.psm1 @@ -106,15 +106,17 @@ function Get-IcingaDiskInformation() $DiskInformation = Get-CimInstance Win32_DiskDrive; [hashtable]$DiskData = @{}; - foreach ($id in $DiskInformation.DeviceID) { - $id = $id.trimstart(".\PHYSICALDRVE"); - $DiskData.Add($id.trim(), $DiskInformation.$Parameter); + foreach ($disk in $DiskInformation) { + $DiskData.Add($disk.DeviceID.trimstart(".\PHYSICALDRVE"), $disk.$Parameter); } return $DiskData; } function Get-IcingaDiskPartitions() { + param( + $Disk + ); <# Fetches all the most important informations regarding partitions e.g. physical disk; partition, size , also collects partition information for Get-IcingaDisks #> @@ -137,7 +139,15 @@ function Get-IcingaDiskPartitions() $diskPartition = $diskPartition.trim("Partition #"); $diskDisk = $diskDisk.trim("Disk #"); + + If ([string]::IsNullOrEmpty($Disk) -eq $FALSE) { + If ([int]$Disk -ne [int]$diskDisk) { + continue; + } + } + $diskPartitionSize = Get-Partition -DriveLetter $driveLetter; + $PartitionDiskByDriveLetter.Add( $driveLetter, @{ @@ -182,8 +192,8 @@ function Get-IcingaDiskCapabilities $DiskInformation = Get-CimInstance Win32_DiskDrive; [hashtable]$DiskCapabilities = @{}; - foreach ($id in $DiskInformation.Capabilities) { - $DiskCapabilities.Add([int]$id, $ProviderEnums.DiskCapabilities.([int]$id)); + foreach ($capabilities in $DiskInformation.Capabilities) { + $DiskCapabilities.Add([int]$capabilities, $ProviderEnums.DiskCapabilities.([int]$capabilities)); } return @{'value' = $DiskCapabilities; 'name' = 'Capabilities'}; @@ -231,23 +241,21 @@ function Get-IcingaDisks { e.g. size, model, sectors, cylinders Is dependent on Get-IcingaDiskPartitions#> $DiskInformation = Get-CimInstance Win32_DiskDrive; - $diskPartitionInformation = Get-IcingaDiskPartitions; [hashtable]$DiskData = @{}; - foreach ($id in $DiskInformation.DeviceID) { - [int]$id = $id.trimstart(".\PHYSICALDRVE"); - + foreach ($disk in $DiskInformation) { + $diskID = $disk.DeviceID.trimstart(".\PHYSICALDRVE"); $DiskData.Add( - $id, @{ + $diskID, @{ 'metadata' = @{ - 'Size' = $DiskInformation.Size; - 'Model' = $DiskInformation.Model; - 'Name' = $DiskInformation.Name.trim('.\'); - 'Manufacturer' = $DiskInformation.Manufacturer; - 'Cylinder' = $DiskInformation.TotalCylinders; - 'Sectors' = $DiskInformation.TotalSectors + 'Size' = $disk.Size; + 'Model' = $disk.Model; + 'Name' = $disk.Name.trim('.\'); + 'Manufacturer' = $disk.Manufacturer; + 'Cylinder' = $disk.TotalCylinders; + 'Sectors' = $disk.TotalSectors }; - 'partitions' = $diskPartitionInformation + 'partitions' = (Get-IcingaDiskPartitions -Disk $diskID); } ); } diff --git a/lib/provider/enums.psm1 b/lib/provider/enums.psm1 index 6903ec0..52faa73 100644 --- a/lib/provider/enums.psm1 +++ b/lib/provider/enums.psm1 @@ -297,6 +297,10 @@ 3='Enabled'; } +<################################################################################################## +################# /lib/provider/memory.psm1 ####################################################### +##################################################################################################> + [hashtable]$MemoryFormFactor = @{ 0='Unknown'; 1= 'Other'; diff --git a/lib/provider/memory.psm1 b/lib/provider/memory.psm1 index da6edd0..6e17fc0 100644 --- a/lib/provider/memory.psm1 +++ b/lib/provider/memory.psm1 @@ -10,46 +10,46 @@ function Show-IcingaMemoryData () [hashtable]$MEMData = @{}; - foreach($id in $MEMInformation) { + foreach($memory in $MEMInformation) { $MEMData.Add( - $id.tag.trim("Physical Memory"), @{ - 'Caption' = $id.Name; - 'Description' = $id.Description; - 'Name' = $id.Name; - 'InstallDate' = $id.InstallDate; - 'Status' = $id.Status - 'CreationClassName'= $id.CreationClassName - 'Manufacturer'= $id.Manufacturer - 'Model'= $id.Model - 'OtherIdentifyingInfo'= $id.OtherIdentifyingInfo - 'PartNumber'= $id.PartNumber - 'PoweredOn'= $id.PoweredOn - 'SerialNumber'= $id.SerialNumber - 'SKU'= $id.SKU - 'Tag'= $id.Tag - 'Version'= $id.Version - 'HotSwappable'= $id.HotSwappable - 'Removable'= $id.Removable - 'Replaceable'= $id.Replaceable - 'FormFactor'= $id.FormFactor - 'BankLabel'= $id.BankLabel - 'Capacity'= $id.Capacity - 'DataWidth'= $id.DataWidth - 'InterleavePosition'= $id.InterleavePosition - 'MemoryType'= $id.MemoryType - 'PositionInRow'= $id.PositionInRow - 'Speed'= $id.Speed - 'TotalWidth'= $id.TotalWidth - 'Attributes'= $id.Attributes - 'ConfiguredClockSpeed'= $id.ConfiguredClockSpeed - 'ConfiguredVoltage'= $id.ConfiguredVoltage - 'DeviceLocator'= $id.DeviceLocator - 'InterleaveDataDepth'= $id.InterleaveDataDepth - 'MaxVoltage'= $id.MaxVoltage - 'MinVoltage'= $id.MinVoltage - 'SMBIOSMemoryType'= $id.SMBIOSMemoryType - 'TypeDetail'= $id.TypeDetail - 'PSComputerName'= $id.PSComputerName + $memory.tag.trim("Physical Memory"), @{ + 'Caption' = $memory.Name; + 'Description' = $memory.Description; + 'Name' = $memory.Name; + 'InstallDate' = $memory.InstallDate; + 'Status' = $memory.Status + 'CreationClassName'= $memory.CreationClassName + 'Manufacturer'= $memory.Manufacturer + 'Model'= $memory.Model + 'OtherIdentifyingInfo'= $memory.OtherIdentifyingInfo + 'PartNumber'= $memory.PartNumber + 'PoweredOn'= $memory.PoweredOn + 'SerialNumber'= $memory.SerialNumber + 'SKU'= $memory.SKU + 'Tag'= $memory.Tag + 'Version'= $memory.Version + 'HotSwappable'= $memory.HotSwappable + 'Removable'= $memory.Removable + 'Replaceable'= $memory.Replaceable + 'FormFactor'= $memory.FormFactor + 'BankLabel'= $memory.BankLabel + 'Capacity'= $memory.Capacity + 'DataWidth'= $memory.DataWidth + 'InterleavePosition'= $memory.InterleavePosition + 'MemoryType'= $memory.MemoryType + 'PositionInRow'= $memory.PositionInRow + 'Speed'= $memory.Speed + 'TotalWidth'= $memory.TotalWidth + 'Attributes'= $memory.Attributes + 'ConfiguredClockSpeed'= $memory.ConfiguredClockSpeed + 'ConfiguredVoltage'= $memory.ConfiguredVoltage + 'DeviceLocator'= $memory.DeviceLocator + 'InterleaveDataDepth'= $memory.InterleaveDataDepth + 'MaxVoltage'= $memory.MaxVoltage + 'MinVoltage'= $memory.MinVoltage + 'SMBIOSMemoryType'= $memory.SMBIOSMemoryType + 'TypeDetail'= $memory.TypeDetail + 'PSComputerName'= $memory.PSComputerName } ); } @@ -66,57 +66,57 @@ function Get-IcingaMemory () [hashtable]$MEMData = @{}; - foreach($id in $MEMInformation) { + foreach($memory in $MEMInformation) { $MEMData.Add( - $id.tag.trim("Physical Memory"), @{ + $memory.tag.trim("Physical Memory"), @{ 'metadata' = @{ - 'Caption' = $id.Name; - 'Description'= $id.Description; - 'Manufacturer'= $id.Manufacturer; - 'Model'= $id.Model; - 'OtherIdentifyingInfo'= $id.OtherIdentifyingInfo; - 'PartNumber'= $id.PartNumber; - 'SerialNumber'= $id.SerialNumber; - 'Tag'= $id.Tag; - 'SMBIOSMemoryType'= $id.SMBIOSMemoryType; - 'DeviceLocator' = $id.DeviceLocator; - 'PositionInRow' = $id.PositionInRow; - 'Version' = $id.Version; - 'PoweredOn' = $id.PoweredOn; - 'Status' = $id.Status; - 'InstallDate' = $id.InstallDate; - 'BankLabel' = $id.BankLabel; - 'InterleaveDataDepth' = $id.InterleaveDataDepth; - 'Attributes' = $id.Attributes; - 'Replaceable' = $id.Replaceable; - 'Removable' = $id.Removable; - 'HotSwappable' = $id.HotSwappable; + 'Caption' = $memory.Name; + 'Description'= $memory.Description; + 'Manufacturer'= $memory.Manufacturer; + 'Model'= $memory.Model; + 'OtherIdentifyingInfo'= $memory.OtherIdentifyingInfo; + 'PartNumber'= $memory.PartNumber; + 'SerialNumber'= $memory.SerialNumber; + 'Tag'= $memory.Tag; + 'SMBIOSMemoryType'= $memory.SMBIOSMemoryType; + 'DeviceLocator' = $memory.DeviceLocator; + 'PositionInRow' = $memory.PositionInRow; + 'Version' = $memory.Version; + 'PoweredOn' = $memory.PoweredOn; + 'Status' = $memory.Status; + 'InstallDate' = $memory.InstallDate; + 'BankLabel' = $memory.BankLabel; + 'InterleaveDataDepth' = $memory.InterleaveDataDepth; + 'Attributes' = $memory.Attributes; + 'Replaceable' = $memory.Replaceable; + 'Removable' = $memory.Removable; + 'HotSwappable' = $memory.HotSwappable; 'FormFactor' = @{ - 'raw' = $id.FormFactor; - 'value' = $ProviderEnums.MemoryFormFactor[[int]$id.FormFactor]; + 'raw' = $memory.FormFactor; + 'value' = $ProviderEnums.MemoryFormFactor[[int]$memory.FormFactor]; }; 'InterleavePosition' = @{ - 'raw' = $id.InterleavePosition; - 'value' = $ProviderEnums.MemoryInterleavePosition[[int]$id.InterleavePosition]; + 'raw' = $memory.InterleavePosition; + 'value' = $ProviderEnums.MemoryInterleavePosition[[int]$memory.InterleavePosition]; }; 'MemoryType' = @{ - 'raw' = $id.MemoryType; - 'value' = $ProviderEnums.MemoryMemoryType[[int]$id.MemoryType]; + 'raw' = $memory.MemoryType; + 'value' = $ProviderEnums.MemoryMemoryType[[int]$memory.MemoryType]; }; 'TypeDetail' = @{ - 'raw' = $id.TypeDetail; - 'value' = $ProviderEnums.MemoryTypeDetail[[int]$id.TypeDetail]; + 'raw' = $memory.TypeDetail; + 'value' = $ProviderEnums.MemoryTypeDetail[[int]$memory.TypeDetail]; }; }; 'specs' = @{ - 'MaxVoltage' = $id.MaxVoltage; - 'MinVoltage' = $id.MinVoltage; - 'ConfiguredVoltage' = $id.ConfiguredVoltage; - 'ConfiguredClockSpeed' = $id.ConfiguredClockSpeed; - 'TotalWidth' = $id.TotalWidth; - 'DataWidth' = $id.DataWidth; - 'Speed' = $id.Speed; - 'Capacity' = $id.Capacity; + 'MaxVoltage' = $memory.MaxVoltage; + 'MinVoltage' = $memory.MinVoltage; + 'ConfiguredVoltage' = $memory.ConfiguredVoltage; + 'ConfiguredClockSpeed' = $memory.ConfiguredClockSpeed; + 'TotalWidth' = $memory.TotalWidth; + 'DataWidth' = $memory.DataWidth; + 'Speed' = $memory.Speed; + 'Capacity' = $memory.Capacity; } } ); @@ -133,8 +133,8 @@ function Get-IcingaMemoryInformation() $MEMInformation = Get-CimInstance Win32_PhysicalMemory; [hashtable]$MEMData = @{}; - foreach ($id in $MEMInformation) { - $MEMData.Add($id.tag.trim("Physical Memory"), $id.$Parameter); + foreach ($memory in $MEMInformation) { + $MEMData.Add($memory.tag.trim("Physical Memory"), $memory.$Parameter); } return $MEMData; diff --git a/lib/provider/process.psm1 b/lib/provider/process.psm1 new file mode 100644 index 0000000..26e639f --- /dev/null +++ b/lib/provider/process.psm1 @@ -0,0 +1,124 @@ +Import-Module $IncludeDir\provider\cpu; + +function Add-IcingaProcessPerfData() +{ + param($ProcessList, $ProcessKey, $Process); + + if ($ProcessList.ContainsKey($ProcessKey) -eq $FALSE) { + $ProcessList.Add($ProcessKey, $Process.$ProcessKey); + } else { + $ProcessList[$ProcessKey] += $Process.$ProcessKey; + } +} + +function Get-IcingaProcessData { + + $ProcessInformation = Get-WmiObject Win32_Process; + $ProcessPerfDataList = Get-WmiObject Win32_PerfFormattedData_PerfProc_Process; + $ProcessUniqueList = Get-WmiObject Win32_Process | Select-Object name -unique; + $CPUCoreCount = Get-IcingaCPUCount; + + + [hashtable]$ProcessData = @{}; + [hashtable]$ProcessList = @{}; + [hashtable]$ProcessNamesUnique = @{}; + [hashtable]$ProcessIDsByName = @{}; + #$NumberOfCPUThreads = $Icinga2.System.NumberOfCPUThreads; + + foreach ($process in $ProcessInformation) { + [string]$processName = $process.Name.Replace('.exe', ''); + + if ($ProcessList.ContainsKey($processName) -eq $FALSE) { + $ProcessList.Add($processName, @{ + 'ProcessList' = @{}; + 'PerformanceData' = @{} + }); + } + + $ProcessList[$processName]['ProcessList'].Add( + [string]$process.ProcessID, @{ + 'Name' = $process.Name; + 'ProcessId' = $process.ProcessId; + 'Priority' = $process.Priority; + 'PageFileUsage' = $process.PageFileUsage; + 'ThreadCount' = $process.ThreadCount; + 'KernelModeTime' = $process.KernelModeTime; + 'UserModeTime' = $process.UserModeTime; + 'WorkingSetSize' = $process.WorkingSetSize; + 'CommandLine' = $process.CommandLine; + } + ); + + Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'ThreadCount' -Process $process; + Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'PageFileUsage' -Process $process; + Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'KernelModeTime' -Process $process; + Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'UserModeTime' -Process $process; + Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'WorkingSetSize' -Process $process; + } + + foreach ($process in $ProcessPerfDataList) { + if ($process.Name -eq '_Total' -Or $process.Name -eq 'Idle') { + continue; + } + + [string]$processName = $process.Name.Split('#')[0]; + [string]$ProcessId = $process.IDProcess; + + if ($ProcessList.ContainsKey($processName) -eq $FALSE) { + Write-Host 'Unknown Process Name: ' $processName; + continue; + } + + if ($ProcessList[$processName]['ProcessList'].ContainsKey($ProcessId) -eq $FALSE) { + Write-Host 'Unknown Process ID: ' $ProcessId; + continue; + } + + $ProcessList[$processName]['ProcessList'][$ProcessId].Add( + 'WorkingSetPrivate', $process.WorkingSetPrivate + ); + $ProcessList[$processName]['ProcessList'][$ProcessId].Add( + 'PercentProcessorTime', ($process.PercentProcessorTime / $CPUCoreCount) + ); + + Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'WorkingSetPrivate' -Process $process; + if ($ProcessList[$processName]['PerformanceData'].ContainsKey('PercentProcessorTime') -eq $FALSE) { + $ProcessList[$processName]['PerformanceData'].Add('PercentProcessorTime', ($process.PercentProcessorTime / $CPUCoreCount)); + } else { + $ProcessList[$processName]['PerformanceData']['PercentProcessorTime'] += ($process.PercentProcessorTime / $CPUCoreCount); + } + } + + $ProcessData.Add('Process Count', $ProcessInformation.Count); + $ProcessData.add('Processes', $ProcessList); + + return $ProcessData; + # Code Stolli below + + foreach ($NameID in $ProcessUniqueList.Name) { + $ProcessIDsBasedOnName = (Get-WmiObject Win32_Process -Filter name="'${NameID}'").ProcessID; + $ProcessIDsByName.Add($NameID,$ProcessIDsBasedOnName); + } + + foreach ($id in $ProcessUniqueList) { + $nameid = $id.name; + $ProcessNamesUnique.Add( + $id.Name.trim(".exe"), @{ + 'processlist' = @{ + $ProcessIDsByName.Item("$nameid") = "metadata"; + }; + 'perfdata' = @{ + 'lawl' = 'lol'; + 'lel' = 'lel'; + 'lol' = 'eyooo'; + } + } + ); + } + + + $ProcessData.Add('Process Count', $ProcessInformation.Count); + $ProcessData.add('Processes', $ProcessNamesUnique); + + return $ProcessData; +} \ No newline at end of file diff --git a/lib/provider/services.psm1 b/lib/provider/services.psm1 new file mode 100644 index 0000000..54724bc --- /dev/null +++ b/lib/provider/services.psm1 @@ -0,0 +1,61 @@ +function Get-IcingaServices() +{ + param ( + [array]$Service + ) + + $ServiceInformation = Get-Service -Name $Service; + + [hashtable]$ServiceData = @{}; + + foreach ($service in $ServiceInformation) { + + [array]$DependentServices = $null; + [array]$DependingServices = $null; + + #Dependent / Child + foreach ($dependency in $service.DependentServices) { + if ($null -eq $DependentServices) { $DependentServices = @(); } + $DependentServices += $dependency.Name; + } + + #Depends / Parent + foreach ($dependency in $service.ServicesDependedOn) { + if ($null -eq $DependingServices) { $DependingServices = @(); } + $DependingServices += $dependency.Name; + } + + $ServiceData.Add( + $service.Name, @{ + 'metadata' = @{ + 'DisplayName' = $service.DisplayName; + 'ServiceName' = $service.ServiceName; + 'Site' = $service.Site; + 'Container' = $service.Container; + 'ServiceHandle' = $service.ServiceHandle; + 'Dependent' = $DependentServices; + 'Depends' = $DependingServices; + }; + 'configuration' = @{ + 'CanPauseAndContinue' = $service.CanPauseAndContinue; + 'CanShutdown' = $service.CanShutdown; + 'CanStop' = $service.CanStop; + 'Status' = @{ + 'raw' = [int]$service.Status; + 'value' = $service.Status; + }; + 'ServiceType' = @{ + 'raw' = [int]$service.ServiceType; + 'value' = $service.ServiceType; + }; + 'ServiceHandle' = $service.ServiceHandle; + 'StartType' = @{ + 'raw' = [int]$service.StartType; + 'value' = $service.StartType; + }; + } + } + ); + } + return $ServiceData; +} \ No newline at end of file From a89c85215b0c7324419dece48082a9947d955fea Mon Sep 17 00:00:00 2001 From: Crited Date: Mon, 22 Jul 2019 10:01:11 +0200 Subject: [PATCH 007/259] Structure Change; Added Updates -> hotfix, pending, installing --- .../Icinga_ProviderBios.psm1} | 82 ++++++------ lib/provider/bios/Show-IcingaBiosData.psm1 | 13 ++ .../{cpu.psm1 => cpu/Icinga_ProviderCpu.psm1} | 28 +--- lib/provider/cpu/Show-IcingaCPUData.psm1 | 16 +++ .../Icinga_ProviderDisks.psm1} | 121 ------------------ lib/provider/disks/Show-IcingaDiskData.psm1 | 67 ++++++++++ .../Icinga_ProviderEnums.psm1} | 0 .../Icinga_ProviderMemory.psm1} | 62 +-------- .../memory/Show-IcingaMemoryData.psm1 | 52 ++++++++ .../Icinga_ProviderProcess.psm1} | 29 ----- .../Icinga_ProviderServices.psm1} | 0 .../updates/Get-IcingaUpdatesHotfix.psm1 | 29 +++++ .../updates/Get-IcingaUpdatesInstalled.psm1 | 75 +++++++++++ .../updates/Get-IcingaUpdatesPending.psm1 | 78 +++++++++++ .../windows/Icinga_ProviderWindows.psm1 | 11 ++ 15 files changed, 386 insertions(+), 277 deletions(-) rename lib/provider/{bios.psm1 => bios/Icinga_ProviderBios.psm1} (77%) create mode 100644 lib/provider/bios/Show-IcingaBiosData.psm1 rename lib/provider/{cpu.psm1 => cpu/Icinga_ProviderCpu.psm1} (89%) create mode 100644 lib/provider/cpu/Show-IcingaCPUData.psm1 rename lib/provider/{disks.psm1 => disks/Icinga_ProviderDisks.psm1} (50%) create mode 100644 lib/provider/disks/Show-IcingaDiskData.psm1 rename lib/provider/{enums.psm1 => enums/Icinga_ProviderEnums.psm1} (100%) rename lib/provider/{memory.psm1 => memory/Icinga_ProviderMemory.psm1} (63%) create mode 100644 lib/provider/memory/Show-IcingaMemoryData.psm1 rename lib/provider/{process.psm1 => process/Icinga_ProviderProcess.psm1} (81%) rename lib/provider/{services.psm1 => services/Icinga_ProviderServices.psm1} (100%) create mode 100644 lib/provider/updates/Get-IcingaUpdatesHotfix.psm1 create mode 100644 lib/provider/updates/Get-IcingaUpdatesInstalled.psm1 create mode 100644 lib/provider/updates/Get-IcingaUpdatesPending.psm1 create mode 100644 lib/provider/windows/Icinga_ProviderWindows.psm1 diff --git a/lib/provider/bios.psm1 b/lib/provider/bios/Icinga_ProviderBios.psm1 similarity index 77% rename from lib/provider/bios.psm1 rename to lib/provider/bios/Icinga_ProviderBios.psm1 index e2acd7f..41eeb87 100644 --- a/lib/provider/bios.psm1 +++ b/lib/provider/bios/Icinga_ProviderBios.psm1 @@ -1,25 +1,4 @@ Import-Module $IncludeDir\provider\enums; - -<################################################################################################## -################# Runspace "Show-Icinga{BIOS}" #################################################### -##################################################################################################> -function Show-IcingaBiosData() -{ - $BIOSInformation = Get-CimInstance Win32_BIOS; - [hashtable]$BIOSData = @{}; - - foreach ($bios_properties in $BIOSInformation) { - foreach($bios in $bios_properties.CimInstanceProperties) { - $BIOSData.Add($bios.Name, $bios.Value); - } - } - - return $BIOSData; -} - -<################################################################################################## -################# Runspace "Get-Icinga{BIOS}" ##################################################### -##################################################################################################> function Get-IcingaBios() { <# Collects the most important BIOS informations, @@ -51,6 +30,45 @@ function Get-IcingaBios() return $BIOSData; } + +function Get-IcingaBiosCharacteristics() +{ + param([switch]$Sorted); + + $bios = Get-CimInstance WIN32_BIOS; + [hashtable]$BIOSCharacteristics = @{}; + + foreach ($id in $bios.BiosCharacteristics) { + $BIOSCharacteristics.Add([string]$id, $ProviderEnums.BiosCharacteristics.Item([int]$id)); + } + + $output = $BIOSCharacteristics; + + if ($sorted) { + $output = $BIOSCharacteristics.GetEnumerator() | Sort-Object name; + } + + return @{'value' = $output; 'name' = 'BiosCharacteristics'}; +} +function Get-IcingaBiosCharacteristics() +{ + param([switch]$Sorted); + + $bios = Get-CimInstance WIN32_BIOS; + [hashtable]$BIOSCharacteristics = @{}; + + foreach ($id in $bios.BiosCharacteristics) { + $BIOSCharacteristics.Add([string]$id, $ProviderEnums.BiosCharacteristics.Item([int]$id)); + } + + $output = $BIOSCharacteristics; + + if ($sorted) { + $output = $BIOSCharacteristics.GetEnumerator() | Sort-Object name; + } + + return @{'value' = $output; 'name' = 'BiosCharacteristics'}; +} function Get-IcingaBiosSerialNumber() { $bios = Get-CimInstance Win32_BIOS; @@ -104,24 +122,4 @@ function Get-IcingaBiosSoftwareElementID() { $bios = Get-CimInstance Win32_BIOS; return @{'value' = $bios.SoftwareElementID; 'name' = 'SoftwareElementID'}; -} - -function Get-IcingaBiosCharacteristics() -{ - param([switch]$Sorted); - - $bios = Get-CimInstance WIN32_BIOS; - [hashtable]$BIOSCharacteristics = @{}; - - foreach ($id in $bios.BiosCharacteristics) { - $BIOSCharacteristics.Add([string]$id, $ProviderEnums.BiosCharacteristics.Item([int]$id)); - } - - $output = $BIOSCharacteristics; - - if ($sorted) { - $output = $BIOSCharacteristics.GetEnumerator() | Sort-Object name; - } - - return @{'value' = $output; 'name' = 'BiosCharacteristics'}; -} +} \ No newline at end of file diff --git a/lib/provider/bios/Show-IcingaBiosData.psm1 b/lib/provider/bios/Show-IcingaBiosData.psm1 new file mode 100644 index 0000000..087c461 --- /dev/null +++ b/lib/provider/bios/Show-IcingaBiosData.psm1 @@ -0,0 +1,13 @@ +function Show-IcingaBiosData() +{ + $BIOSInformation = Get-CimInstance Win32_BIOS; + [hashtable]$BIOSData = @{}; + + foreach ($bios_properties in $BIOSInformation) { + foreach($bios in $bios_properties.CimInstanceProperties) { + $BIOSData.Add($bios.Name, $bios.Value); + } + } + + return $BIOSData; +} \ No newline at end of file diff --git a/lib/provider/cpu.psm1 b/lib/provider/cpu/Icinga_ProviderCpu.psm1 similarity index 89% rename from lib/provider/cpu.psm1 rename to lib/provider/cpu/Icinga_ProviderCpu.psm1 index 986a9f9..9324ba8 100644 --- a/lib/provider/cpu.psm1 +++ b/lib/provider/cpu/Icinga_ProviderCpu.psm1 @@ -1,28 +1,4 @@ Import-Module $IncludeDir\provider\enums; - -<################################################################################################## -################# Runspace "Show-Icinga{CPU}" ##################################################### -##################################################################################################> -function Show-IcingaCPUData() -{ - -$CPUInformation = Get-CimInstance Win32_Processor; -[hashtable]$PhysicalCPUData = @{}; - -foreach ($cpu_properties in $CPUInformation) { - $cpu_datails = @{}; - foreach($cpu_core in $cpu_properties.CimInstanceProperties) { - $cpu_datails.Add($cpu_core.Name, $cpu_core.Value); - } - $PhysicalCPUData.Add($cpu_datails.DeviceID, $cpu_datails); -} - -return $PhysicalCPUData; -} - -<################################################################################################## -################# Runspace "Get-Icinga{Memory}" ################################################### -##################################################################################################> function Get-IcingaCPUs() { <# Collects the most important CPU informations, @@ -284,8 +260,8 @@ function Get-IcingaCPUNumberOfLogicalProcessors() function Get-IcingaCPUCount() { - <# Collects the most important CPU informations, - e.g. name, version, manufacturer#> + <# Compares whether NumberofLogicalCores, NumberofCores or Threadcount across all CPUs is the highest, + this function is used in provider/memory/Icinga_ProviderMemory.psm1#> $CPUInformation = Get-CimInstance Win32_Processor; foreach ($cpu in $CPUInformation) { diff --git a/lib/provider/cpu/Show-IcingaCPUData.psm1 b/lib/provider/cpu/Show-IcingaCPUData.psm1 new file mode 100644 index 0000000..651a595 --- /dev/null +++ b/lib/provider/cpu/Show-IcingaCPUData.psm1 @@ -0,0 +1,16 @@ +function Show-IcingaCPUData() +{ + +$CPUInformation = Get-CimInstance Win32_Processor; +[hashtable]$PhysicalCPUData = @{}; + +foreach ($cpu_properties in $CPUInformation) { + $cpu_datails = @{}; + foreach($cpu_core in $cpu_properties.CimInstanceProperties) { + $cpu_datails.Add($cpu_core.Name, $cpu_core.Value); + } + $PhysicalCPUData.Add($cpu_datails.DeviceID, $cpu_datails); +} + +return $PhysicalCPUData; +} \ No newline at end of file diff --git a/lib/provider/disks.psm1 b/lib/provider/disks/Icinga_ProviderDisks.psm1 similarity index 50% rename from lib/provider/disks.psm1 rename to lib/provider/disks/Icinga_ProviderDisks.psm1 index eed30ec..74dab9e 100644 --- a/lib/provider/disks.psm1 +++ b/lib/provider/disks/Icinga_ProviderDisks.psm1 @@ -1,99 +1,5 @@ Import-Module $IncludeDir\provider\enums; -<################################################################################################## -################# Runspace "Show-Icinga{Disk}" #################################################### -##################################################################################################> - -function Show-IcingaDiskData { - - $DisksInformations = Get-CimInstance Win32_DiskDrive; - - [hashtable]$PhysicalDiskData = @{}; - - foreach ($disk_properties in $DisksInformations) { - $disk_datails = @{}; - foreach($disk in $disk_properties.CimInstanceProperties) { - $disk_datails.Add($disk.Name, $disk.Value); - } - $disk_datails.Add('DriveReference', @()); - $PhysicalDiskData.Add($disk_datails.DeviceID, $disk_datails); - } - - $DiskPartitionInfo = Get-WmiObject Win32_DiskDriveToDiskPartition; - - [hashtable]$MapDiskPartitionToLogicalDisk = @{}; - - foreach ($item in $DiskPartitionInfo) { - [string]$diskPartition = $item.Dependent.SubString( - $item.Dependent.LastIndexOf('=') + 1, - $item.Dependent.Length - $item.Dependent.LastIndexOf('=') - 1 - ); - $diskPartition = $diskPartition.Replace('"', ''); - - [string]$physicalDrive = $item.Antecedent.SubString( - $item.Antecedent.LastIndexOf('\') + 1, - $item.Antecedent.Length - $item.Antecedent.LastIndexOf('\') - 1 - ) - $physicalDrive = $physicalDrive.Replace('"', ''); - - $MapDiskPartitionToLogicalDisk.Add($diskPartition, $physicalDrive); - } - - $LogicalDiskInfo = Get-WmiObject Win32_LogicalDiskToPartition; - - foreach ($item in $LogicalDiskInfo) { - [string]$driveLetter = $item.Dependent.SubString( - $item.Dependent.LastIndexOf('=') + 1, - $item.Dependent.Length - $item.Dependent.LastIndexOf('=') - 1 - ); - $driveLetter = $driveLetter.Replace('"', ''); - - [string]$diskPartition = $item.Antecedent.SubString( - $item.Antecedent.LastIndexOf('=') + 1, - $item.Antecedent.Length - $item.Antecedent.LastIndexOf('=') - 1 - ) - $diskPartition = $diskPartition.Replace('"', ''); - - if ($MapDiskPartitionToLogicalDisk.ContainsKey($diskPartition)) { - foreach ($disk in $PhysicalDiskData.Keys) { - [string]$DiskId = $disk.SubString( - $disk.LastIndexOf('\') + 1, - $disk.Length - $disk.LastIndexOf('\') - 1 - ); - - if ($DiskId.ToLower() -eq $MapDiskPartitionToLogicalDisk[$diskPartition].ToLower()) { - $PhysicalDiskData[$disk]['DriveReference'] += $driveLetter; - } - } - } - } - - return $PhysicalDiskData; - -} - -function Show-IcingaDiskPhysical() -{ - $DisksInformations = Get-CimInstance Win32_DiskDrive; - - [hashtable]$PhysicalDiskData = @{}; - - foreach ($disk_properties in $DisksInformations) { - $disk_datails = @{}; - foreach($disk in $disk_properties.CimInstanceProperties) { - $disk_datails.Add($disk.Name, $disk.Value); - } - $disk_datails.Add('DriveReference', @()); - $PhysicalDiskData.Add($disk_datails.DeviceID, $disk_datails); - } - - return $PhysicalDiskData; -} - -<################################################################################################## -################# Runspace "Get-Icinga{Disk}" #################################################### -##################################################################################################> - function Get-IcingaDiskInformation() { <# Fetches the information for other more specific Get-IcingaDisk-functions @@ -160,33 +66,6 @@ function Get-IcingaDiskPartitions() return $PartitionDiskByDriveLetter; } -#Code-Snippen that still exists for LordHepipud's amusement -function Get-IcingaDiskPartitionSize() -{ - param([switch]$sorted); - - [hashtable]$PartitionSizeByDriveLetter = @{}; - - # Should be dependent on the driveLetters returned in: "Show-IcingaDiskData" - for ($test = 0; $test -lt 26; $test++) - { - $DiskDriveLetter = ([char](65 + $test)) - $PartitionSize = (Get-Partition -DriveLetter $DiskDriveLetter -ErrorAction 'silentlycontinue').Size; - if ($null -eq $PartitionSize) - { - $PartitionSize = "0"; - } - $PartitionSizeByDriveLetter.Add("$DiskDriveLetter", $PartitionSize); - } - - $output = $PartitionSizeByDriveLetter; - - if ($sorted) { - $output = $PartitionSizeByDriveLetter.GetEnumerator() | Sort-Object name; - } - - return @{'value' = $output; 'name' = 'Size'}; -} function Get-IcingaDiskCapabilities { $DiskInformation = Get-CimInstance Win32_DiskDrive; diff --git a/lib/provider/disks/Show-IcingaDiskData.psm1 b/lib/provider/disks/Show-IcingaDiskData.psm1 new file mode 100644 index 0000000..fab6e5b --- /dev/null +++ b/lib/provider/disks/Show-IcingaDiskData.psm1 @@ -0,0 +1,67 @@ +function Show-IcingaDiskData { + + $DisksInformations = Get-CimInstance Win32_DiskDrive; + + [hashtable]$PhysicalDiskData = @{}; + + foreach ($disk_properties in $DisksInformations) { + $disk_datails = @{}; + foreach($disk in $disk_properties.CimInstanceProperties) { + $disk_datails.Add($disk.Name, $disk.Value); + } + $disk_datails.Add('DriveReference', @()); + $PhysicalDiskData.Add($disk_datails.DeviceID, $disk_datails); + } + + $DiskPartitionInfo = Get-WmiObject Win32_DiskDriveToDiskPartition; + + [hashtable]$MapDiskPartitionToLogicalDisk = @{}; + + foreach ($item in $DiskPartitionInfo) { + [string]$diskPartition = $item.Dependent.SubString( + $item.Dependent.LastIndexOf('=') + 1, + $item.Dependent.Length - $item.Dependent.LastIndexOf('=') - 1 + ); + $diskPartition = $diskPartition.Replace('"', ''); + + [string]$physicalDrive = $item.Antecedent.SubString( + $item.Antecedent.LastIndexOf('\') + 1, + $item.Antecedent.Length - $item.Antecedent.LastIndexOf('\') - 1 + ) + $physicalDrive = $physicalDrive.Replace('"', ''); + + $MapDiskPartitionToLogicalDisk.Add($diskPartition, $physicalDrive); + } + + $LogicalDiskInfo = Get-WmiObject Win32_LogicalDiskToPartition; + + foreach ($item in $LogicalDiskInfo) { + [string]$driveLetter = $item.Dependent.SubString( + $item.Dependent.LastIndexOf('=') + 1, + $item.Dependent.Length - $item.Dependent.LastIndexOf('=') - 1 + ); + $driveLetter = $driveLetter.Replace('"', ''); + + [string]$diskPartition = $item.Antecedent.SubString( + $item.Antecedent.LastIndexOf('=') + 1, + $item.Antecedent.Length - $item.Antecedent.LastIndexOf('=') - 1 + ) + $diskPartition = $diskPartition.Replace('"', ''); + + if ($MapDiskPartitionToLogicalDisk.ContainsKey($diskPartition)) { + foreach ($disk in $PhysicalDiskData.Keys) { + [string]$DiskId = $disk.SubString( + $disk.LastIndexOf('\') + 1, + $disk.Length - $disk.LastIndexOf('\') - 1 + ); + + if ($DiskId.ToLower() -eq $MapDiskPartitionToLogicalDisk[$diskPartition].ToLower()) { + $PhysicalDiskData[$disk]['DriveReference'] += $driveLetter; + } + } + } + } + + return $PhysicalDiskData; + +} \ No newline at end of file diff --git a/lib/provider/enums.psm1 b/lib/provider/enums/Icinga_ProviderEnums.psm1 similarity index 100% rename from lib/provider/enums.psm1 rename to lib/provider/enums/Icinga_ProviderEnums.psm1 diff --git a/lib/provider/memory.psm1 b/lib/provider/memory/Icinga_ProviderMemory.psm1 similarity index 63% rename from lib/provider/memory.psm1 rename to lib/provider/memory/Icinga_ProviderMemory.psm1 index 6e17fc0..2631ae6 100644 --- a/lib/provider/memory.psm1 +++ b/lib/provider/memory/Icinga_ProviderMemory.psm1 @@ -1,63 +1,4 @@ Import-Module $IncludeDir\provider\enums; - -<################################################################################################## -################# Runspace "Show-Icinga{Memory}" ################################################## -##################################################################################################> -function Show-IcingaMemoryData () -{ - - $MEMInformation = Get-CimInstance Win32_PhysicalMemory; - - [hashtable]$MEMData = @{}; - - foreach($memory in $MEMInformation) { - $MEMData.Add( - $memory.tag.trim("Physical Memory"), @{ - 'Caption' = $memory.Name; - 'Description' = $memory.Description; - 'Name' = $memory.Name; - 'InstallDate' = $memory.InstallDate; - 'Status' = $memory.Status - 'CreationClassName'= $memory.CreationClassName - 'Manufacturer'= $memory.Manufacturer - 'Model'= $memory.Model - 'OtherIdentifyingInfo'= $memory.OtherIdentifyingInfo - 'PartNumber'= $memory.PartNumber - 'PoweredOn'= $memory.PoweredOn - 'SerialNumber'= $memory.SerialNumber - 'SKU'= $memory.SKU - 'Tag'= $memory.Tag - 'Version'= $memory.Version - 'HotSwappable'= $memory.HotSwappable - 'Removable'= $memory.Removable - 'Replaceable'= $memory.Replaceable - 'FormFactor'= $memory.FormFactor - 'BankLabel'= $memory.BankLabel - 'Capacity'= $memory.Capacity - 'DataWidth'= $memory.DataWidth - 'InterleavePosition'= $memory.InterleavePosition - 'MemoryType'= $memory.MemoryType - 'PositionInRow'= $memory.PositionInRow - 'Speed'= $memory.Speed - 'TotalWidth'= $memory.TotalWidth - 'Attributes'= $memory.Attributes - 'ConfiguredClockSpeed'= $memory.ConfiguredClockSpeed - 'ConfiguredVoltage'= $memory.ConfiguredVoltage - 'DeviceLocator'= $memory.DeviceLocator - 'InterleaveDataDepth'= $memory.InterleaveDataDepth - 'MaxVoltage'= $memory.MaxVoltage - 'MinVoltage'= $memory.MinVoltage - 'SMBIOSMemoryType'= $memory.SMBIOSMemoryType - 'TypeDetail'= $memory.TypeDetail - 'PSComputerName'= $memory.PSComputerName - } - ); - } - return $MEMData; -} -<################################################################################################## -################# Runspace "Get-Icinga{Memory}" ################################################### -##################################################################################################> function Get-IcingaMemory () { <# Collects the most important Memory informations, @@ -127,6 +68,9 @@ function Get-IcingaMemory () function Get-IcingaMemoryInformation() { + <# Fetches the information for other more specific Get-IcingaMemory-functions + e.g. Get-IcingaMemoryMaxVoltage; Get-IcingaMemoryTotalWidth. + Can be used to fetch information regarding a value of your choice. #> param( [string]$Parameter ); diff --git a/lib/provider/memory/Show-IcingaMemoryData.psm1 b/lib/provider/memory/Show-IcingaMemoryData.psm1 new file mode 100644 index 0000000..7bf8e5f --- /dev/null +++ b/lib/provider/memory/Show-IcingaMemoryData.psm1 @@ -0,0 +1,52 @@ +function Show-IcingaMemoryData () +{ + + $MEMInformation = Get-CimInstance Win32_PhysicalMemory; + + [hashtable]$MEMData = @{}; + + foreach($memory in $MEMInformation) { + $MEMData.Add( + $memory.tag.trim("Physical Memory"), @{ + 'Caption' = $memory.Name; + 'Description' = $memory.Description; + 'Name' = $memory.Name; + 'InstallDate' = $memory.InstallDate; + 'Status' = $memory.Status + 'CreationClassName'= $memory.CreationClassName + 'Manufacturer'= $memory.Manufacturer + 'Model'= $memory.Model + 'OtherIdentifyingInfo'= $memory.OtherIdentifyingInfo + 'PartNumber'= $memory.PartNumber + 'PoweredOn'= $memory.PoweredOn + 'SerialNumber'= $memory.SerialNumber + 'SKU'= $memory.SKU + 'Tag'= $memory.Tag + 'Version'= $memory.Version + 'HotSwappable'= $memory.HotSwappable + 'Removable'= $memory.Removable + 'Replaceable'= $memory.Replaceable + 'FormFactor'= $memory.FormFactor + 'BankLabel'= $memory.BankLabel + 'Capacity'= $memory.Capacity + 'DataWidth'= $memory.DataWidth + 'InterleavePosition'= $memory.InterleavePosition + 'MemoryType'= $memory.MemoryType + 'PositionInRow'= $memory.PositionInRow + 'Speed'= $memory.Speed + 'TotalWidth'= $memory.TotalWidth + 'Attributes'= $memory.Attributes + 'ConfiguredClockSpeed'= $memory.ConfiguredClockSpeed + 'ConfiguredVoltage'= $memory.ConfiguredVoltage + 'DeviceLocator'= $memory.DeviceLocator + 'InterleaveDataDepth'= $memory.InterleaveDataDepth + 'MaxVoltage'= $memory.MaxVoltage + 'MinVoltage'= $memory.MinVoltage + 'SMBIOSMemoryType'= $memory.SMBIOSMemoryType + 'TypeDetail'= $memory.TypeDetail + 'PSComputerName'= $memory.PSComputerName + } + ); + } + return $MEMData; +} \ No newline at end of file diff --git a/lib/provider/process.psm1 b/lib/provider/process/Icinga_ProviderProcess.psm1 similarity index 81% rename from lib/provider/process.psm1 rename to lib/provider/process/Icinga_ProviderProcess.psm1 index 26e639f..729138b 100644 --- a/lib/provider/process.psm1 +++ b/lib/provider/process/Icinga_ProviderProcess.psm1 @@ -23,7 +23,6 @@ function Get-IcingaProcessData { [hashtable]$ProcessList = @{}; [hashtable]$ProcessNamesUnique = @{}; [hashtable]$ProcessIDsByName = @{}; - #$NumberOfCPUThreads = $Icinga2.System.NumberOfCPUThreads; foreach ($process in $ProcessInformation) { [string]$processName = $process.Name.Replace('.exe', ''); @@ -92,33 +91,5 @@ function Get-IcingaProcessData { $ProcessData.Add('Process Count', $ProcessInformation.Count); $ProcessData.add('Processes', $ProcessList); - return $ProcessData; - # Code Stolli below - - foreach ($NameID in $ProcessUniqueList.Name) { - $ProcessIDsBasedOnName = (Get-WmiObject Win32_Process -Filter name="'${NameID}'").ProcessID; - $ProcessIDsByName.Add($NameID,$ProcessIDsBasedOnName); - } - - foreach ($id in $ProcessUniqueList) { - $nameid = $id.name; - $ProcessNamesUnique.Add( - $id.Name.trim(".exe"), @{ - 'processlist' = @{ - $ProcessIDsByName.Item("$nameid") = "metadata"; - }; - 'perfdata' = @{ - 'lawl' = 'lol'; - 'lel' = 'lel'; - 'lol' = 'eyooo'; - } - } - ); - } - - - $ProcessData.Add('Process Count', $ProcessInformation.Count); - $ProcessData.add('Processes', $ProcessNamesUnique); - return $ProcessData; } \ No newline at end of file diff --git a/lib/provider/services.psm1 b/lib/provider/services/Icinga_ProviderServices.psm1 similarity index 100% rename from lib/provider/services.psm1 rename to lib/provider/services/Icinga_ProviderServices.psm1 diff --git a/lib/provider/updates/Get-IcingaUpdatesHotfix.psm1 b/lib/provider/updates/Get-IcingaUpdatesHotfix.psm1 new file mode 100644 index 0000000..2f62185 --- /dev/null +++ b/lib/provider/updates/Get-IcingaUpdatesHotfix.psm1 @@ -0,0 +1,29 @@ +function Get-IcingaUpdatesHotfix (){ + +[hashtable]$HotfixInfo = @{}; +[hashtable]$HotfixNameCache = @{}; + +# First fetch all of our hotfixes +$Hotfixes = Get-Hotfix; + +foreach ($property in $Hotfixes) { + [hashtable]$HotfixData = @{}; + foreach ($hotfix in $property.Properties) { + $HotfixData.Add($hotfix.Name, $hotfix.Value); + } + + [string]$name = [string]::Format('{0} [{1}]', $HotfixData.HotFixID, $HotfixData.InstalledOn); + + if ($HotfixNameCache.ContainsKey($name) -eq $FALSE) { + $HotfixNameCache.Add($name, 1); + } else { + $HotfixNameCache[$name] += 1; + $name = [string]::Format('{0} ({1})', $name, $HotfixNameCache[$name]); + } + + $HotfixInfo.Add($name, $HotfixData); +} + +return $HotfixInfo; + +} \ No newline at end of file diff --git a/lib/provider/updates/Get-IcingaUpdatesInstalled.psm1 b/lib/provider/updates/Get-IcingaUpdatesInstalled.psm1 new file mode 100644 index 0000000..a294303 --- /dev/null +++ b/lib/provider/updates/Get-IcingaUpdatesInstalled.psm1 @@ -0,0 +1,75 @@ +function Get-IcingaUpdatesInstalled () +{ + +# Fetch all informations about installed updates and add them +$WindowsUpdates = New-Object -ComObject "Microsoft.Update.Session"; +$SearchIndex = $WindowsUpdates.CreateUpdateSearcher(); +[hashtable]$UpdateList = @{}; +[hashtable]$UpdateInstalled = @{}; +[hashtable]$UpdateUninstalled = @{}; +[hashtable]$UpdateOther = @{}; + +# Operation ID's +# 1: Installed +# 2: Uninstalled +# 3: Other + +# At first get a list of our Windows Update history +$Updates = $SearchIndex.QueryHistory(0, $SearchIndex.GetTotalHistoryCount()) | + Select-Object Operation, ResultCode, HResult, Date, Title, Description, ServiceID, SupportUrl; + +foreach ($update in $Updates) { + [string]$UpdateKey = [string]::Format('{0} [{1}|{2}]', $update.Title, $update.Date, $update.HResult); + switch ($update.Operation) { + 1 { + if ($UpdateInstalled.ContainsKey($UpdateKey) -eq $FALSE) { + $UpdateInstalled.Add($UpdateKey, $update); + } else { + $Icinga2.Log.Write( + $Icinga2.Enums.LogState.Warning, + [string]::Format( + 'Unable to add update "{0}" to update list. The key with content "{1}" is already present', + $UpdateKey, + $update + ) + ); + } + }; + 2 { + if ($UpdateUninstalled.ContainsKey($UpdateKey) -eq $FALSE) { + $UpdateUninstalled.Add($UpdateKey, $update); + } else { + $Icinga2.Log.Write( + $Icinga2.Enums.LogState.Warning, + [string]::Format( + 'Unable to add update "{0}" to update list. The key with content "{1}" is already present', + $UpdateKey, + $update + ) + ); + } + }; + default { + if ($UpdateOther.ContainsKey($UpdateKey) -eq $FALSE) { + $UpdateOther.Add($UpdateKey, $update); + } else { + $Icinga2.Log.Write( + $Icinga2.Enums.LogState.Warning, + [string]::Format( + 'Unable to add update "{0}" to update list. The key with content "{1}" is already present', + $UpdateKey, + $update + ) + ); + } + }; + } +} + +$UpdateList.Add('installed', $UpdateInstalled); +$UpdateList.Add('uninstalled', $UpdateUninstalled); +$UpdateList.Add('other', $UpdateOther); + +return $UpdateList; + +} \ No newline at end of file diff --git a/lib/provider/updates/Get-IcingaUpdatesPending.psm1 b/lib/provider/updates/Get-IcingaUpdatesPending.psm1 new file mode 100644 index 0000000..2caa728 --- /dev/null +++ b/lib/provider/updates/Get-IcingaUpdatesPending.psm1 @@ -0,0 +1,78 @@ +function Get-IcingaUpdatesPending () +{ + + [hashtable]$PendingUpdates = @{}; + [hashtable]$PendingUpdateNameCache = @{}; + # Fetch all informations about installed updates and add them + $WindowsUpdates = New-Object -ComObject "Microsoft.Update.Session"; + $SearchIndex = $WindowsUpdates.CreateUpdateSearcher(); + + try { + # Get a list of current pending updates which are not yet installed on the system + $Pending = $SearchIndex.Search("IsInstalled=0"); + $PendingUpdates.Add('count', $Pending.Updates.Count); + + foreach ($update in $Pending.Updates) { + [hashtable]$PendingUpdateDetails = @{}; + $PendingUpdateDetails.Add('Title', $update.Title); + $PendingUpdateDetails.Add('Deadline', $update.Deadline); + $PendingUpdateDetails.Add('Description', $update.Description); + $PendingUpdateDetails.Add('IsBeta', $update.IsBeta); + $PendingUpdateDetails.Add('IsDownloaded', $update.IsDownloaded); + $PendingUpdateDetails.Add('IsHidden', $update.IsHidden); + $PendingUpdateDetails.Add('IsInstalled', $update.IsInstalled); + $PendingUpdateDetails.Add('IsMandatory', $update.IsMandatory); + $PendingUpdateDetails.Add('IsUninstallable', $update.IsUninstallable); + $PendingUpdateDetails.Add('Languages', $update.Languages); + $PendingUpdateDetails.Add('LastDeploymentChangeTime', $update.LastDeploymentChangeTime); + $PendingUpdateDetails.Add('MaxDownloadSize', $update.MaxDownloadSize); + $PendingUpdateDetails.Add('MinDownloadSize', $update.MinDownloadSize); + $PendingUpdateDetails.Add('MoreInfoUrls', $update.MoreInfoUrls); + $PendingUpdateDetails.Add('MsrcSeverity', $update.MsrcSeverity); + $PendingUpdateDetails.Add('RecommendedCpuSpeed', $update.RecommendedCpuSpeed); + $PendingUpdateDetails.Add('RecommendedHardDiskSpace', $update.RecommendedHardDiskSpace); + $PendingUpdateDetails.Add('RecommendedMemory', $update.RecommendedMemory); + $PendingUpdateDetails.Add('ReleaseNotes', $update.ReleaseNotes); + $PendingUpdateDetails.Add('SecurityBulletinIDs', $update.SecurityBulletinIDs); + $PendingUpdateDetails.Add('SupersededUpdateIDs', $update.SupersededUpdateIDs); + $PendingUpdateDetails.Add('SupportUrl', $update.SupportUrl); + $PendingUpdateDetails.Add('Type', $update.Type); + $PendingUpdateDetails.Add('UninstallationNotes', $update.UninstallationNotes); + $PendingUpdateDetails.Add('UninstallationBehavior', $update.UninstallationBehavior); + $PendingUpdateDetails.Add('UninstallationSteps', $update.UninstallationSteps); + $PendingUpdateDetails.Add('KBArticleIDs', $update.KBArticleIDs); + $PendingUpdateDetails.Add('DeploymentAction', $update.DeploymentAction); + $PendingUpdateDetails.Add('DownloadPriority', $update.DownloadPriority); + $PendingUpdateDetails.Add('RebootRequired', $update.RebootRequired); + $PendingUpdateDetails.Add('IsPresent', $update.IsPresent); + $PendingUpdateDetails.Add('CveIDs', $update.CveIDs); + $PendingUpdateDetails.Add('BrowseOnly', $update.BrowseOnly); + $PendingUpdateDetails.Add('PerUser', $update.PerUser); + $PendingUpdateDetails.Add('AutoSelection', $update.AutoSelection); + $PendingUpdateDetails.Add('AutoDownload', $update.AutoDownload); + + [string]$name = [string]::Format('{0} [{1}]', $update.Title, $update.LastDeploymentChangeTime); + + if ($PendingUpdateNameCache.ContainsKey($name) -eq $FALSE) { + $PendingUpdateNameCache.Add($name, 1); + } else { + $PendingUpdateNameCache[$name] += 1; + $name = [string]::Format('{0} ({1})', $name, $PendingUpdateNameCache[$name]); + } + + $PendingUpdates.Add($name, $PendingUpdateDetails); + } + } catch { + if ($PendingUpdates.ContainsKey('Count') -eq $FALSE) { + $PendingUpdates.Add('count', 0); + } else { + $PendingUpdates['count'] = 0; + } + $PendingUpdates.Add('error', [string]::Format( + 'Failed to query Windows Update server: {0}', + $_.Exception.Message + )); + } + + return $PendingUpdates; +} \ No newline at end of file diff --git a/lib/provider/windows/Icinga_ProviderWindows.psm1 b/lib/provider/windows/Icinga_ProviderWindows.psm1 new file mode 100644 index 0000000..0d40c7d --- /dev/null +++ b/lib/provider/windows/Icinga_ProviderWindows.psm1 @@ -0,0 +1,11 @@ +function Show-IcingaWindowsData() +{ + $WindowsInformations = Get-CimInstance Win32_OperatingSystem; + + $windows_datails = @{}; + foreach($cpu_core in $WindowsInformations.CimInstanceProperties) { + $windows_datails.Add($cpu_core.Name, $cpu_core.Value); + } + + return $windows_datails; +} \ No newline at end of file From 7ca64c27c7e94a5ce41d59ea3e2d00a113fd517c Mon Sep 17 00:00:00 2001 From: Crited Date: Mon, 22 Jul 2019 15:23:21 +0200 Subject: [PATCH 008/259] Expanded upon Icinga_ProviderWindows.psm1; Minor Changes to other modules regarding structure and comments --- lib/provider/enums/Icinga_ProviderEnums.psm1 | 112 ++++++++++++++++-- .../memory/Icinga_ProviderMemory.psm1 | 2 +- .../windows/Icinga_ProviderWindows.psm1 | 39 +++++- .../windows/Show-IcingaWindowsData.psm1 | 11 ++ 4 files changed, 151 insertions(+), 13 deletions(-) create mode 100644 lib/provider/windows/Show-IcingaWindowsData.psm1 diff --git a/lib/provider/enums/Icinga_ProviderEnums.psm1 b/lib/provider/enums/Icinga_ProviderEnums.psm1 index 52faa73..3818cfc 100644 --- a/lib/provider/enums/Icinga_ProviderEnums.psm1 +++ b/lib/provider/enums/Icinga_ProviderEnums.psm1 @@ -1,6 +1,6 @@ <################################################################################################## -################# /lib/provider/bios.psm1 ######################################################### +################# /lib/provider/bios ############################################################## ##################################################################################################> [hashtable]$BiosCharacteristics = @{ @@ -71,7 +71,7 @@ } <################################################################################################## -################# /lib/provider/disks.psm1 ######################################################## +################# /lib/provider/disks ############################################################# ##################################################################################################> [hashtable]$DiskCapabilities = @{ @@ -91,7 +91,7 @@ } <################################################################################################## -################# /lib/provider/cpu.psm1 ########################################################## +################# /lib/provider/cpu ############################################################### ##################################################################################################> [hashtable]$CPUArchitecture = @{ @@ -298,7 +298,7 @@ } <################################################################################################## -################# /lib/provider/memory.psm1 ####################################################### +################# /lib/provider/memory ############################################################ ##################################################################################################> [hashtable]$MemoryFormFactor = @{ @@ -379,12 +379,104 @@ 4096= 'Non-volatile'; } +<################################################################################################## +################# /lib/provider/Windows ########################################################### +##################################################################################################> + +[hashtable]$WindowsOSProductSuite = @{ + 1= 'Microsoft Small Business Server was once installed, but may have been upgraded to another version of Windows.'; + 2= 'Windows Server 2008 Enterprise is installed.'; + 4= 'Windows BackOffice components are installed.'; + 8= 'Communication Server is installed.'; + 16= 'Terminal Services is installed.'; + 32= 'Microsoft Small Business Server is installed with the restrictive client license.'; + 64= 'Windows Embedded is installed.'; + 128= 'Datacenter edition is installed.'; + 256= 'Terminal Services is installed, but only one interactive session is supported.'; + 512= 'Windows Home Edition is installed.'; + 1024= 'Web Server Edition is installed.'; + 8192= 'Storage Server Edition is installed.'; + 16384= 'Compute Cluster Edition is installed.'; +} + +[hashtable]$WindowsProductType = @{ + 1= 'Work Station'; + 2= 'Domain Controller'; + 3= 'Server'; +} + +[hashtable]$WindowsOSType = @{ + 0= 'Unknown'; + 1= 'Other'; + 2= 'MACROS'; + 3= 'ATTUNIX'; + 4= 'DGUX'; + 5= 'DECNT'; + 6= 'Digital Unix'; + 7= 'OpenVMS' + 8= 'HPUX'; + 9= 'AIX'; + 10= 'MVS'; + 11= 'OS400'; + 12= 'OS/2'; + 13= 'JavaVM'; + 14= 'MSDOS'; + 15= 'WIN3x'; + 16= 'WIN95'; + 17= 'WIN98'; + 18= 'WINNT'; + 19= 'WINCE'; + 20= 'NCR3000'; + 21= 'NetWare'; + 22= 'OSF'; + 23= 'DC/OS'; + 24= 'Reliant UNIX'; + 25= 'SCO UnixWare'; + 26= 'SCO OpenServer'; + 27= 'Sequent'; + 28= 'IRIX'; + 29= 'Solaris'; + 30= 'SunOS'; + 31= 'U6000'; + 32= 'ASERIES'; + 33= 'TandemNSK'; + 34= 'TandemNT'; + 35= 'BS2000'; + 36= 'LINUX'; + 37= 'Lynx'; + 38= 'XENIX'; + 39= 'VM/ESA'; + 40= 'Interactive UNIX'; + 41= 'BSDUNIX'; + 42= 'FreeBSD'; + 43= 'NetBSD'; + 44= 'GNU Hurd'; + 45= 'OS9'; + 46= 'MACH Kernel'; + 47= 'Inferno'; + 48= 'QNX'; + 49= 'EPOC'; + 50= 'IxWorks'; + 51= 'VxWorks'; + 52= 'MiNT'; + 53= 'BeOS'; + 54= 'HP MPE'; + 55= 'NextStep'; + 56= 'PalmPilot'; + 57= 'Rhapsody'; + 58= 'Windows 2000'; + 59= 'Dedicated'; + 60= 'OS/390'; + 61= 'VSE'; + 62= 'TPF'; +} + [hashtable]$ProviderEnums = @{ - #/lib/provider/bios.psm1 + #/lib/provider/bios BiosCharacteristics = $BiosCharacteristics; - #/lib/provider/disks.psm1 + #/lib/provider/disks DiskCapabilities = $DiskCapabilities; - #/lib/provider/cpu.psm1 + #/lib/provider/cpu CPUArchitecture = $CPUArchitecture; CPUProcessorType = $CPUProcessorType; CPUStatusInfo = $CPUStatusInfo; @@ -392,11 +484,15 @@ CPUConfigManagerErrorCode = $CPUConfigManagerErrorCode; CPUAvailability = $CPUAvailability; CPUPowerManagementCapabilities = $CPUPowerManagementCapabilities; - #/lib/provider/memory.psm1 + #/lib/provider/memory MemoryFormFactor = $MemoryFormFactor; MemoryInterleavePosition = $MemoryInterleavePosition; MemoryMemoryType = $MemoryMemoryType; MemoryTypeDetail = $MemoryTypeDetail; + #/lib/provider/windows + WindowsOSProductSuite = $WindowsOSProductSuite; + WindowsProductType = $WindowsProductType; + WindowsOSType = $WindowsOSType; } Export-ModuleMember -Variable @('ProviderEnums'); \ No newline at end of file diff --git a/lib/provider/memory/Icinga_ProviderMemory.psm1 b/lib/provider/memory/Icinga_ProviderMemory.psm1 index 2631ae6..cbe0a9c 100644 --- a/lib/provider/memory/Icinga_ProviderMemory.psm1 +++ b/lib/provider/memory/Icinga_ProviderMemory.psm1 @@ -1,4 +1,4 @@ -Import-Module $IncludeDir\provider\enums; +Import-Module $IncludeDir\provider\enums\Icinga_ProviderEnums; function Get-IcingaMemory () { <# Collects the most important Memory informations, diff --git a/lib/provider/windows/Icinga_ProviderWindows.psm1 b/lib/provider/windows/Icinga_ProviderWindows.psm1 index 0d40c7d..068ce6d 100644 --- a/lib/provider/windows/Icinga_ProviderWindows.psm1 +++ b/lib/provider/windows/Icinga_ProviderWindows.psm1 @@ -1,11 +1,42 @@ -function Show-IcingaWindowsData() +Import-Module $IncludeDir\provider\enums\Icinga_ProviderEnums; + +function Get-IcingaWindows() { $WindowsInformations = Get-CimInstance Win32_OperatingSystem; $windows_datails = @{}; - foreach($cpu_core in $WindowsInformations.CimInstanceProperties) { - $windows_datails.Add($cpu_core.Name, $cpu_core.Value); - } + $windows_datails.Add( + 'windows', @{ + 'metadata' = @{ + 'Version' = $WindowsInformations.Version; + 'CurrentTimeZone' = $WindowsInformations.CurrentTimeZone; + 'InstallDate' = $WindowsInformations.InstallDate; + 'SystemDevice' = $WindowsInformations.SystemDevice; + 'SystemDirectory' = $WindowsInformations.SystemDirectory; + 'BuildType' = $WindowsInformations.BuildType; + 'BuildNumber' = $WindowsInformations.BuildNumber; + 'OSArchitecture' = $WindowsInformations.OSArchitecture; + 'NumberOfUsers' = $WindowsInformations.NumberOfUsers; + 'OSType' = @{ + 'raw' = $WindowsInformations.OSType; + 'value' = $ProviderEnums.WindowsOSType[[int]$WindowsInformations.OSType]; + }; + 'OSProductSuite' = @{ + 'raw' = $WindowsInformations.OSProductSuite; + 'value' = $ProviderEnums.WindowsOSProductSuite[[int]$WindowsInformations.OSProductSuite]; + }; + 'ProductType' = @{ + 'raw' = $WindowsInformations.ProductType; + 'value' = $ProviderEnums.WindowsProductType[[int]$WindowsInformations.ProductType]; + }; + }; + 'language' = @{ + 'CountryCode' = $WindowsInformations.CountryCode; + 'OSLanguage' = $WindowsInformations.OSLanguage; + 'Locale' = $WindowsInformations.Locale; + } + } + ); return $windows_datails; } \ No newline at end of file diff --git a/lib/provider/windows/Show-IcingaWindowsData.psm1 b/lib/provider/windows/Show-IcingaWindowsData.psm1 new file mode 100644 index 0000000..0d40c7d --- /dev/null +++ b/lib/provider/windows/Show-IcingaWindowsData.psm1 @@ -0,0 +1,11 @@ +function Show-IcingaWindowsData() +{ + $WindowsInformations = Get-CimInstance Win32_OperatingSystem; + + $windows_datails = @{}; + foreach($cpu_core in $WindowsInformations.CimInstanceProperties) { + $windows_datails.Add($cpu_core.Name, $cpu_core.Value); + } + + return $windows_datails; +} \ No newline at end of file From 1a5dbb392a7e51013a4d967c460fd827fb0b1834 Mon Sep 17 00:00:00 2001 From: Crited Date: Mon, 22 Jul 2019 15:53:07 +0200 Subject: [PATCH 009/259] Binary-Addition in relevant files for enums --- lib/provider/memory/Icinga_ProviderMemory.psm1 | 10 +++++++++- lib/provider/windows/Icinga_ProviderWindows.psm1 | 10 +++++++++- 2 files changed, 18 insertions(+), 2 deletions(-) diff --git a/lib/provider/memory/Icinga_ProviderMemory.psm1 b/lib/provider/memory/Icinga_ProviderMemory.psm1 index cbe0a9c..89e544d 100644 --- a/lib/provider/memory/Icinga_ProviderMemory.psm1 +++ b/lib/provider/memory/Icinga_ProviderMemory.psm1 @@ -8,6 +8,14 @@ function Get-IcingaMemory () [hashtable]$MEMData = @{}; foreach($memory in $MEMInformation) { + + $TypeDetail = @(); + $ProviderEnums.MemoryTypeDetail.Keys | Where-Object { + $_ -band $memory.TypeDetail + } | ForEach-Object { + $TypeDetail += $ProviderEnums.MemoryTypeDetail.Get_Item($_); + }; + $MEMData.Add( $memory.tag.trim("Physical Memory"), @{ 'metadata' = @{ @@ -46,7 +54,7 @@ function Get-IcingaMemory () }; 'TypeDetail' = @{ 'raw' = $memory.TypeDetail; - 'value' = $ProviderEnums.MemoryTypeDetail[[int]$memory.TypeDetail]; + 'value' = $TypeDetail; }; }; 'specs' = @{ diff --git a/lib/provider/windows/Icinga_ProviderWindows.psm1 b/lib/provider/windows/Icinga_ProviderWindows.psm1 index 068ce6d..57b1a88 100644 --- a/lib/provider/windows/Icinga_ProviderWindows.psm1 +++ b/lib/provider/windows/Icinga_ProviderWindows.psm1 @@ -1,9 +1,17 @@ Import-Module $IncludeDir\provider\enums\Icinga_ProviderEnums; + function Get-IcingaWindows() { $WindowsInformations = Get-CimInstance Win32_OperatingSystem; + $OSProductSuite = @(); + $ProviderEnums.WindowsOSProductSuite.Keys | Where-Object { + $_ -band $WindowsInformations.OSProductSuite + } | ForEach-Object { + $OSProductSuite += $ProviderEnums.WindowsOSProductSuite.Get_Item($_); + }; + $windows_datails = @{}; $windows_datails.Add( 'windows', @{ @@ -23,7 +31,7 @@ function Get-IcingaWindows() }; 'OSProductSuite' = @{ 'raw' = $WindowsInformations.OSProductSuite; - 'value' = $ProviderEnums.WindowsOSProductSuite[[int]$WindowsInformations.OSProductSuite]; + 'value' = $OSProductSuite; }; 'ProductType' = @{ 'raw' = $WindowsInformations.ProductType; From 34c001c761ecdc06e3ea34e150966e88dba653fe Mon Sep 17 00:00:00 2001 From: Crited Date: Mon, 22 Jul 2019 15:59:47 +0200 Subject: [PATCH 010/259] Changed Import-Module to fit with Import-ModuleLib Concept --- icinga-module-windows.psm1 | 2 -- lib/provider/bios/Icinga_ProviderBios.psm1 | 2 +- lib/provider/cpu/Icinga_ProviderCpu.psm1 | 2 +- lib/provider/disks/Icinga_ProviderDisks.psm1 | 2 +- lib/provider/memory/Icinga_ProviderMemory.psm1 | 2 +- lib/provider/process/Icinga_ProviderProcess.psm1 | 3 ++- lib/provider/windows/Icinga_ProviderWindows.psm1 | 3 +-- 7 files changed, 7 insertions(+), 9 deletions(-) diff --git a/icinga-module-windows.psm1 b/icinga-module-windows.psm1 index 70c3552..3d84e5e 100644 --- a/icinga-module-windows.psm1 +++ b/icinga-module-windows.psm1 @@ -9,8 +9,6 @@ #> -$global:IncludeDir = "$PSScriptRoot\lib"; - function Install-Icinga() { [string]$command = Get-Icinga-Command('setup'); diff --git a/lib/provider/bios/Icinga_ProviderBios.psm1 b/lib/provider/bios/Icinga_ProviderBios.psm1 index 41eeb87..76e6a73 100644 --- a/lib/provider/bios/Icinga_ProviderBios.psm1 +++ b/lib/provider/bios/Icinga_ProviderBios.psm1 @@ -1,4 +1,4 @@ -Import-Module $IncludeDir\provider\enums; +Import-IcingaLib provider\enums; function Get-IcingaBios() { <# Collects the most important BIOS informations, diff --git a/lib/provider/cpu/Icinga_ProviderCpu.psm1 b/lib/provider/cpu/Icinga_ProviderCpu.psm1 index 9324ba8..6dac6c8 100644 --- a/lib/provider/cpu/Icinga_ProviderCpu.psm1 +++ b/lib/provider/cpu/Icinga_ProviderCpu.psm1 @@ -1,4 +1,4 @@ -Import-Module $IncludeDir\provider\enums; +Import-IcingaLib provider\enums; function Get-IcingaCPUs() { <# Collects the most important CPU informations, diff --git a/lib/provider/disks/Icinga_ProviderDisks.psm1 b/lib/provider/disks/Icinga_ProviderDisks.psm1 index 74dab9e..b03a8b6 100644 --- a/lib/provider/disks/Icinga_ProviderDisks.psm1 +++ b/lib/provider/disks/Icinga_ProviderDisks.psm1 @@ -1,4 +1,4 @@ -Import-Module $IncludeDir\provider\enums; +Import-IcingaLib provider\enums; function Get-IcingaDiskInformation() { diff --git a/lib/provider/memory/Icinga_ProviderMemory.psm1 b/lib/provider/memory/Icinga_ProviderMemory.psm1 index 89e544d..f9abcd0 100644 --- a/lib/provider/memory/Icinga_ProviderMemory.psm1 +++ b/lib/provider/memory/Icinga_ProviderMemory.psm1 @@ -1,4 +1,4 @@ -Import-Module $IncludeDir\provider\enums\Icinga_ProviderEnums; +Import-IcingaLib provider\enums; function Get-IcingaMemory () { <# Collects the most important Memory informations, diff --git a/lib/provider/process/Icinga_ProviderProcess.psm1 b/lib/provider/process/Icinga_ProviderProcess.psm1 index 729138b..c86c6ee 100644 --- a/lib/provider/process/Icinga_ProviderProcess.psm1 +++ b/lib/provider/process/Icinga_ProviderProcess.psm1 @@ -1,4 +1,5 @@ -Import-Module $IncludeDir\provider\cpu; +Import-IcingaLib provider\enums; +Import-IcingaLib provider\cpu; function Add-IcingaProcessPerfData() { diff --git a/lib/provider/windows/Icinga_ProviderWindows.psm1 b/lib/provider/windows/Icinga_ProviderWindows.psm1 index 57b1a88..d0d5d6d 100644 --- a/lib/provider/windows/Icinga_ProviderWindows.psm1 +++ b/lib/provider/windows/Icinga_ProviderWindows.psm1 @@ -1,5 +1,4 @@ -Import-Module $IncludeDir\provider\enums\Icinga_ProviderEnums; - +Import-IcingaLib provider\enums; function Get-IcingaWindows() { From 6cbbf91049f3159aa51cec416553fb30e54877af Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 22 Jul 2019 18:01:12 +0200 Subject: [PATCH 011/259] Fixed output for Check Results with checks only --- lib/icinga/plugin/New-IcingaCheckResult.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/icinga/plugin/New-IcingaCheckResult.psm1 b/lib/icinga/plugin/New-IcingaCheckResult.psm1 index d205e53..c7126ff 100644 --- a/lib/icinga/plugin/New-IcingaCheckResult.psm1 +++ b/lib/icinga/plugin/New-IcingaCheckResult.psm1 @@ -18,7 +18,7 @@ function New-IcingaCheckresult() } # Compile the check / package if not already done - $this.check.Compile() | Out-Null; + $this.check.Compile($TRUE) | Out-Null; if ([int]$this.check.exitcode -ne [int]$IcingaEnums.IcingaExitCode.Unknown -And -Not $this.noperfdata) { Write-Host ([string]::Format('| {0}', $this.check.GetPerfData())); From b0bea9a6a4c27e74ff3a0da1267236eaedb20a6c Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 22 Jul 2019 18:03:19 +0200 Subject: [PATCH 012/259] Replaced Silent argument for verbose on check packages --- lib/icinga/plugin/New-IcingaCheckPackage.psm1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 index aa857f9..6d51045 100644 --- a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 +++ b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 @@ -51,7 +51,7 @@ function New-IcingaCheckPackage() } $Check | Add-Member -membertype ScriptMethod -name 'Compile' -value { - param([bool]$Silent); + param([bool]$Verbose); if ($this.compiled) { return; @@ -90,7 +90,7 @@ function New-IcingaCheckPackage() $this.exitcode = $IcingaEnums.IcingaExitCode.Ok; } - if ($Silent -eq $FALSE -And [int]$this.exitcode -ne $IcingaEnums.IcingaExitCode.Unknown) { + if ($Verbose -eq $TRUE -Or [int]$this.exitcode -ne $IcingaEnums.IcingaExitCode.Unknown) { $this.PrintOutputMessages(); } @@ -100,7 +100,7 @@ function New-IcingaCheckPackage() } $Check | Add-Member -membertype ScriptMethod -name 'SilentCompile' -value { - $this.Compile($TRUE) | Out-Null; + $this.Compile($FALSE) | Out-Null; } $Check | Add-Member -membertype ScriptMethod -name 'GetOkCount' -value { From 56ddd36cbb18805d8578680ebd660ee1b3e3f555 Mon Sep 17 00:00:00 2001 From: Niko Martini Date: Tue, 23 Jul 2019 08:03:32 +0200 Subject: [PATCH 013/259] Fixed Code Styling --- lib/core/tools/ConvertTo-ByteUnit.psm1 | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/core/tools/ConvertTo-ByteUnit.psm1 b/lib/core/tools/ConvertTo-ByteUnit.psm1 index f2d57b3..50cc3e4 100644 --- a/lib/core/tools/ConvertTo-ByteUnit.psm1 +++ b/lib/core/tools/ConvertTo-ByteUnit.psm1 @@ -1,5 +1,3 @@ -# - function ConvertTo-Byte() { param( From ec8bac7a833a8c1373dda2b9417ff1ef042f5952 Mon Sep 17 00:00:00 2001 From: Niko Martini Date: Tue, 23 Jul 2019 09:16:43 +0200 Subject: [PATCH 014/259] Fixed Code Styling --- lib/core/tools/ConvertTo-ByteUnit.psm1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/core/tools/ConvertTo-ByteUnit.psm1 b/lib/core/tools/ConvertTo-ByteUnit.psm1 index 50cc3e4..669c5fb 100644 --- a/lib/core/tools/ConvertTo-ByteUnit.psm1 +++ b/lib/core/tools/ConvertTo-ByteUnit.psm1 @@ -52,7 +52,7 @@ function ConvertTo-MegaByte() [string]$Unit ); - switch($Unit) { + switch ($Unit) { { 'B', 'Byte' -contains $_ } { $result = ($Value / [math]::Pow(10, 6)); $boolOption = $true; } { 'KB', 'KiloByte' -contains $_ } { $result = ($Value / [math]::Pow(10, 3)); $boolOption = $true; } { 'MB', 'MegaByte' -contains $_ } { $result = $Value; $boolOption = $true; } @@ -76,7 +76,7 @@ function ConvertTo-GigaByte() [string]$Unit ); - switch($Unit) { + switch ($Unit) { { 'B', 'Byte' -contains $_ } { $result = ($Value / [math]::Pow(10, 9)); $boolOption = $true; } { 'KB', 'KiloByte' -contains $_ } { $result = ($Value / [math]::Pow(10, 6)); $boolOption = $true; } { 'MB', 'MegaByte' -contains $_ } { $result = ($Value / [math]::Pow(10, 3)); $boolOption = $true; } @@ -100,7 +100,7 @@ function ConvertTo-TeraByte() [string]$Unit ); - switch($Unit) { + switch ($Unit) { { 'B', 'Byte' -contains $_ } { $result = ($Value / [math]::Pow(10, 12)); $boolOption = $true; } { 'KB', 'KiloByte' -contains $_ } { $result = ($Value / [math]::Pow(10, 9)); $boolOption = $true; } { 'MB', 'MegaByte' -contains $_ } { $result = ($Value / [math]::Pow(10, 6)); $boolOption = $true; } @@ -124,7 +124,7 @@ function ConvertTo-PetaByte() [string]$Unit ); - switch($Unit) { + switch ($Unit) { { 'B', 'Byte' -contains $_ } { $result = ($Value / [math]::Pow(10, 15)); $boolOption = $true; } { 'KB', 'KiloByte' -contains $_ } { $result = ($Value / [math]::Pow(10, 12)); $boolOption = $true; } { 'MB', 'MegaByte' -contains $_ } { $result = ($Value / [math]::Pow(10, 9)); $boolOption = $true; } From df7a1a1f6b7838d5c24939845c6b1a2b093b4e75 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 23 Jul 2019 09:16:54 +0200 Subject: [PATCH 015/259] Added support to automaticly load all modules on init --- icinga-module-windows.psm1 | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/icinga-module-windows.psm1 b/icinga-module-windows.psm1 index 50a685a..97aa99e 100644 --- a/icinga-module-windows.psm1 +++ b/icinga-module-windows.psm1 @@ -334,9 +334,8 @@ function Get-Icinga-Object() return $Icinga2; } -# Automaticly load the Help library including Plugins -Import-IcingaLib help\help; -Import-IcingaLib plugins; +# Automaticly load all library modules +Import-IcingaLib '\'; # Initialise base configuration for our module $Icinga2 = & (Join-Path -Path $PSScriptRoot -ChildPath '\core\init.ps1') ` From bc8f80ec1041c1fa6d71dc10e3577180ae44624d Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 23 Jul 2019 09:17:11 +0200 Subject: [PATCH 016/259] Improved Directory module loading --- icinga-module-windows.psm1 | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/icinga-module-windows.psm1 b/icinga-module-windows.psm1 index 97aa99e..b04b78f 100644 --- a/icinga-module-windows.psm1 +++ b/icinga-module-windows.psm1 @@ -43,13 +43,14 @@ function Import-IcingaLib() [string]$modulePath = $_.FullName; $moduleName = $_.Name.Replace('.psm1', ''); - if ($ForceReload) { - if ($ListOfLoadedModules -like "*$moduleName*") { + if ($ListOfLoadedModules -like "*$moduleName*") { + if ($ForceReload) { Remove-Module -Name $moduleName + Import-Module ([string]::Format('{0}', $modulePath)) -Global; } + } else { + Import-Module ([string]::Format('{0}', $modulePath)) -Global; } - - Import-Module ([string]::Format('{0}', $modulePath)) -Global; } } else { $module = $module.Replace('.psm1', ''); # Cut possible .psm1 ending From c298a1c6940fb39f9f2014da96fabf756124e75d Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 23 Jul 2019 09:18:02 +0200 Subject: [PATCH 017/259] Added first attempt for Bios Serial Number Check --- lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 | 8 ++++++++ 1 file changed, 8 insertions(+) create mode 100644 lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 diff --git a/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 b/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 new file mode 100644 index 0000000..0517022 --- /dev/null +++ b/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 @@ -0,0 +1,8 @@ +Import-IcingaLib provider\bios; + +function Invoke-IcingaCheckBiosSerial() +{ + $Bios = Get-IcingaBiosSerialNumber; + $BiosCheck = New-IcingaCheck -Name $Bios.Name -Value $Bios.Value -NoPerfData; + exit (New-IcingaCheckresult -Check $BiosCheck -NoPerfData $TRUE -Compile); +} From ecef0920b4ba0a30595b9c6a403759f0ba66a6c3 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 23 Jul 2019 09:34:15 +0200 Subject: [PATCH 018/259] Fixed code spacing --- lib/core/tools/ConvertTo-ByteUnit.psm1 | 39 +++++++++++++------------- 1 file changed, 20 insertions(+), 19 deletions(-) diff --git a/lib/core/tools/ConvertTo-ByteUnit.psm1 b/lib/core/tools/ConvertTo-ByteUnit.psm1 index 669c5fb..ee132a0 100644 --- a/lib/core/tools/ConvertTo-ByteUnit.psm1 +++ b/lib/core/tools/ConvertTo-ByteUnit.psm1 @@ -13,14 +13,15 @@ function ConvertTo-Byte() { 'TB', 'TeraByte' -contains $_ } { $result = ($Value * [math]::Pow(10, 12)); $boolOption = $true; } { 'PT', 'PetaByte' -contains $_ } { $result = ($Value * [math]::Pow(10, 15)); $boolOption = $true; } default { - if (-Not $boolOption) { - Throw 'Invalid input'; - } + if (-Not $boolOption) { + Throw 'Invalid input'; + } } } return $result; } + function ConvertTo-KiloByte() { param( @@ -36,9 +37,9 @@ function ConvertTo-KiloByte() { 'TB', 'TeraByte' -contains $_ } { $result = ($Value * [math]::Pow(10, 9)); $boolOption = $true; } { 'PT', 'PetaByte' -contains $_ } { $result = ($Value * [math]::Pow(10, 12)); $boolOption = $true; } default { - if (-Not $boolOption) { - Throw 'Invalid input'; - } + if (-Not $boolOption) { + Throw 'Invalid input'; + } } } @@ -60,9 +61,9 @@ function ConvertTo-MegaByte() { 'TB', 'TeraByte' -contains $_ } { $result = ($Value * [math]::Pow(10, 6)); $boolOption = $true; } { 'PT', 'PetaByte' -contains $_ } { $result = ($Value * [math]::Pow(10, 9)); $boolOption = $true; } default { - if (-Not $boolOption) { - Throw 'Invalid input'; - } + if (-Not $boolOption) { + Throw 'Invalid input'; + } } } @@ -84,9 +85,9 @@ function ConvertTo-GigaByte() { 'TB', 'TeraByte' -contains $_ } { $result = ($Value * [math]::Pow(10, 3)); $boolOption = $true; } { 'PT', 'PetaByte' -contains $_ } { $result = ($Value * [math]::Pow(10, 6)); $boolOption = $true; } default { - if (-Not $boolOption) { - Throw 'Invalid input'; - } + if (-Not $boolOption) { + Throw 'Invalid input'; + } } } @@ -108,9 +109,9 @@ function ConvertTo-TeraByte() { 'TB', 'TeraByte' -contains $_ } { $result = $Value; $boolOption = $true; } { 'PT', 'PetaByte' -contains $_ } { $result = ($Value * [math]::Pow(10, 3)); $boolOption = $true; } default { - if (-Not $boolOption) { - Throw 'Invalid input'; - } + if (-Not $boolOption) { + Throw 'Invalid input'; + } } } @@ -132,11 +133,11 @@ function ConvertTo-PetaByte() { 'TB', 'TeraByte' -contains $_ } { $result = ($Value / [math]::Pow(10, 3)); $boolOption = $true; } { 'PT', 'PetaByte' -contains $_ } { $result = $Value; $boolOption = $true; } default { - if (-Not $boolOption) { - Throw 'Invalid input'; - } + if (-Not $boolOption) { + Throw 'Invalid input'; + } } } return $result; -} \ No newline at end of file +} From 7100db383814e0e68a9f25e65f420674a0fd714c Mon Sep 17 00:00:00 2001 From: Crited Date: Tue, 23 Jul 2019 10:50:58 +0200 Subject: [PATCH 019/259] Added FreeDiskSpace to Disk Provider, via Performance Counters --- icinga-module-windows.psm1 | 4 +++- lib/provider/disks/Icinga_ProviderDisks.psm1 | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/icinga-module-windows.psm1 b/icinga-module-windows.psm1 index b04b78f..990a151 100644 --- a/icinga-module-windows.psm1 +++ b/icinga-module-windows.psm1 @@ -339,8 +339,10 @@ function Get-Icinga-Object() Import-IcingaLib '\'; # Initialise base configuration for our module +<# $Icinga2 = & (Join-Path -Path $PSScriptRoot -ChildPath '\core\init.ps1') ` -RootDirectory $PSScriptRoot ` -ModuleName $MyInvocation.MyCommand.Name; -Export-ModuleMember @Icinga2; \ No newline at end of file +Export-ModuleMember @Icinga2; +#> \ No newline at end of file diff --git a/lib/provider/disks/Icinga_ProviderDisks.psm1 b/lib/provider/disks/Icinga_ProviderDisks.psm1 index b03a8b6..c1fb3b1 100644 --- a/lib/provider/disks/Icinga_ProviderDisks.psm1 +++ b/lib/provider/disks/Icinga_ProviderDisks.psm1 @@ -51,6 +51,8 @@ function Get-IcingaDiskPartitions() continue; } } + + $DiskArray = New-IcingaPerformanceCounterStructure -CounterCategory 'LogicalDisk' -PerformanceCounterHash (New-IcingaPerformanceCounterArray @('\LogicalDisk(*)\% free space')); $diskPartitionSize = Get-Partition -DriveLetter $driveLetter; @@ -60,6 +62,7 @@ function Get-IcingaDiskPartitions() 'Disk' = $diskDisk; 'Partition' = $diskPartition; 'Size' = $diskPartitionSize.Size; + 'Free Space' = $DiskArray.Item([string]::Format('{0}:', $driveLetter))."% free space".value; } ); } From 63d9445d16240ca409c89d02f65aaf32e7c25910 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 23 Jul 2019 11:42:16 +0200 Subject: [PATCH 020/259] Fixed check initialising for AddCheck() on Check Packages --- lib/icinga/plugin/New-IcingaCheckPackage.psm1 | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 index 6d51045..bc57f08 100644 --- a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 +++ b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 @@ -30,12 +30,20 @@ function New-IcingaCheckPackage() $Check | Add-Member -membertype ScriptMethod -name 'Initialise' -value { foreach ($check in $this.checks) { - $check.verbose = $this.verbose; - $check.AddSpacing(); - $check.SilentCompile(); + $this.InitCheck($check); } } + $Check | Add-Member -membertype ScriptMethod -name 'InitCheck' -value { + if ($null -eq $check) { + return; + } + + $check.verbose = $this.verbose; + $check.AddSpacing(); + $check.SilentCompile(); + } + $Check | Add-Member -membertype ScriptMethod -name 'AddSpacing' -value { $this.spacing += 1; foreach ($check in $this.checks) { @@ -47,6 +55,11 @@ function New-IcingaCheckPackage() $Check | Add-Member -membertype ScriptMethod -name 'AddCheck' -value { param($check); + if ($null -eq $check) { + return; + } + + $this.InitCheck($check); $this.checks += $check; } From 075018d21a4ce8ea150286bf863b38db8bb09115 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 23 Jul 2019 12:21:45 +0200 Subject: [PATCH 021/259] Removed no longer required debug output --- lib/icinga/plugin/New-IcingaCheck.psm1 | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/icinga/plugin/New-IcingaCheck.psm1 b/lib/icinga/plugin/New-IcingaCheck.psm1 index 019b0d5..d65d78d 100644 --- a/lib/icinga/plugin/New-IcingaCheck.psm1 +++ b/lib/icinga/plugin/New-IcingaCheck.psm1 @@ -55,7 +55,6 @@ function New-IcingaCheck() if (-Not $negate -And (Test-Numeric $rangeMin) -And (Test-Numeric $rangeMax)) { $this.WarnIfLowerThan($rangeMin).WarnIfGreaterThan($rangeMax) | Out-Null; } elseif ((Test-Numeric $rangeMin) -And [string]::IsNullOrEmpty($rangeMax) -eq $TRUE) { - Write-Host 'lal' $this.WarnIfLowerThan($rangeMin) | Out-Null; } elseif ($rangeMin -eq '~' -And (Test-Numeric $rangeMax)) { $this.WarnIfGreaterThan($rangeMax) | Out-Null; From 728949c14ebef964f881c174adb33654e6b2fdb8 Mon Sep 17 00:00:00 2001 From: Crited Date: Tue, 23 Jul 2019 15:08:59 +0200 Subject: [PATCH 022/259] Added Invoke-IcingaCheckFreePartition.psm1 --- .../Invoke-IcingaCheckFreePartition.psm1 | 39 +++++++++++++++++++ 1 file changed, 39 insertions(+) create mode 100644 lib/plugins/Invoke-IcingaCheckFreePartition.psm1 diff --git a/lib/plugins/Invoke-IcingaCheckFreePartition.psm1 b/lib/plugins/Invoke-IcingaCheckFreePartition.psm1 new file mode 100644 index 0000000..36a14bc --- /dev/null +++ b/lib/plugins/Invoke-IcingaCheckFreePartition.psm1 @@ -0,0 +1,39 @@ +Import-IcingaLib core\perfcounter; +Import-IcingaLib icinga\plugin; + +function Invoke-IcingaCheckFreePartition() +{ + param( + $Warning, + $Critical, + [array]$Include = @(), + [array]$Exclude = @(), + [switch]$NoPerfData, + $Verbose + ); + + $DiskFree = Get-IcingaDiskPartitions + $DiskPackage = New-IcingaCheckPackage -Name 'Free Disk Space' -OperatorAnd -Verbos $Verbose; + + foreach ($Letter in $DiskFree.Keys) { + if ($Include.Count -ne 0) { + $Include = $Include.trim(' :/\'); + if (-Not ($Include.Contains($Letter))) { + continue; + } + } + + if ($Exclude.Count -ne 0) { + $Exclude = $Exclude.trim(' :/\'); + if ($Exclude.Contains($Letter)) { + continue; + } + } + + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Partition {0}', $Letter)) -Value $DiskFree.([string]::Format($Letter))."Free Space" -Unit '%'; + $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + $DiskPackage.AddCheck($IcingaCheck); + } + + exit (New-IcingaCheckResult -Name 'Free Disk Space' -Check $DiskPackage -NoPerfData $NoPerfData -Compile); +} From 9a2f2fd06abdc8c0e2e398320653e8f3356d8929 Mon Sep 17 00:00:00 2001 From: Crited Date: Wed, 24 Jul 2019 10:01:34 +0200 Subject: [PATCH 023/259] Added Icinga_ProviderServices, adjusted Invoke-IcingaCheckService accordingly --- .../Invoke-IcingaCheckFreePartition.psm1 | 5 +++- lib/plugins/Invoke-IcingaCheckService.psm1 | 23 +++++++++++++++++++ .../services/Icinga_ProviderServices.psm1 | 6 ++++- 3 files changed, 32 insertions(+), 2 deletions(-) create mode 100644 lib/plugins/Invoke-IcingaCheckService.psm1 diff --git a/lib/plugins/Invoke-IcingaCheckFreePartition.psm1 b/lib/plugins/Invoke-IcingaCheckFreePartition.psm1 index 36a14bc..bab94fa 100644 --- a/lib/plugins/Invoke-IcingaCheckFreePartition.psm1 +++ b/lib/plugins/Invoke-IcingaCheckFreePartition.psm1 @@ -12,8 +12,9 @@ function Invoke-IcingaCheckFreePartition() $Verbose ); - $DiskFree = Get-IcingaDiskPartitions + $DiskFree = Get-IcingaDiskPartitions; $DiskPackage = New-IcingaCheckPackage -Name 'Free Disk Space' -OperatorAnd -Verbos $Verbose; + [array]$CheckedPartitions; foreach ($Letter in $DiskFree.Keys) { if ($Include.Count -ne 0) { @@ -23,6 +24,8 @@ function Invoke-IcingaCheckFreePartition() } } + $CheckedPartitions+=$Letter + if ($Exclude.Count -ne 0) { $Exclude = $Exclude.trim(' :/\'); if ($Exclude.Contains($Letter)) { diff --git a/lib/plugins/Invoke-IcingaCheckService.psm1 b/lib/plugins/Invoke-IcingaCheckService.psm1 new file mode 100644 index 0000000..71f0a9e --- /dev/null +++ b/lib/plugins/Invoke-IcingaCheckService.psm1 @@ -0,0 +1,23 @@ +Import-IcingaLib provider\services; +Import-IcingaLib icinga\plugin; + +function Invoke-IcingaCheckService() +{ + param( + [string]$Status, + [string]$Service, + [switch]$NoPerfData, + $Verbose + ); + + $FoundService = Get-IcingaServices -Service $Service; + $ServiceName = $FoundService.Values.metadata.ServiceName; + $DisplayName = $FoundService.Values.metadata.DisplayName; + # $Status = Get-IcingaServicesStatusTranslation -Status $Status; + $StatusRaw = $FoundService.Values.configuration.Status.raw; + + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Service "{0} ({1})"', $DisplayName, $ServiceName)) -Value $StatusRaw -ObjectExists $FoundService -ValueTranslation $ProviderEnums.ServiceStatus; + $IcingaCheck.CritIfNotMatch($Status) | Out-Null; + + exit (New-IcingaCheckResult -Name "Service $Service" -Check $IcingaCheck -NoPerfData $TRUE -Compile); +} diff --git a/lib/provider/services/Icinga_ProviderServices.psm1 b/lib/provider/services/Icinga_ProviderServices.psm1 index 54724bc..9dfc1cb 100644 --- a/lib/provider/services/Icinga_ProviderServices.psm1 +++ b/lib/provider/services/Icinga_ProviderServices.psm1 @@ -4,7 +4,11 @@ function Get-IcingaServices() [array]$Service ) - $ServiceInformation = Get-Service -Name $Service; + $ServiceInformation = Get-Service -Name $Service -ErrorAction SilentlyContinue; + + if ($null -eq $ServiceInformation) { + return $null; + } [hashtable]$ServiceData = @{}; From 0e0cf88023c9ddfd8045424769cf7ecc92943200 Mon Sep 17 00:00:00 2001 From: Crited Date: Wed, 24 Jul 2019 10:26:39 +0200 Subject: [PATCH 024/259] Expanded upon lib/provider/services to support translated status values in Invoke-IcingaCheckService.psm1 --- lib/plugins/Invoke-IcingaCheckService.psm1 | 4 ++-- lib/provider/enums/Icinga_ProviderEnums.psm1 | 11 +++++++++++ .../services/Icinga_ProviderServices.psm1 | 15 +++++++++++++++ 3 files changed, 28 insertions(+), 2 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckService.psm1 b/lib/plugins/Invoke-IcingaCheckService.psm1 index 71f0a9e..0f62080 100644 --- a/lib/plugins/Invoke-IcingaCheckService.psm1 +++ b/lib/plugins/Invoke-IcingaCheckService.psm1 @@ -13,10 +13,10 @@ function Invoke-IcingaCheckService() $FoundService = Get-IcingaServices -Service $Service; $ServiceName = $FoundService.Values.metadata.ServiceName; $DisplayName = $FoundService.Values.metadata.DisplayName; - # $Status = Get-IcingaServicesStatusTranslation -Status $Status; + $Status = Get-IcingaServicesStatusTranslation -Status $Status; $StatusRaw = $FoundService.Values.configuration.Status.raw; - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Service "{0} ({1})"', $DisplayName, $ServiceName)) -Value $StatusRaw -ObjectExists $FoundService -ValueTranslation $ProviderEnums.ServiceStatus; + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Service "{0} ({1})"', $DisplayName, $ServiceName)) -Value $StatusRaw -ObjectExists $FoundService -ValueTranslation $ProviderEnums.ServicesStatus; $IcingaCheck.CritIfNotMatch($Status) | Out-Null; exit (New-IcingaCheckResult -Name "Service $Service" -Check $IcingaCheck -NoPerfData $TRUE -Compile); diff --git a/lib/provider/enums/Icinga_ProviderEnums.psm1 b/lib/provider/enums/Icinga_ProviderEnums.psm1 index 3818cfc..886290c 100644 --- a/lib/provider/enums/Icinga_ProviderEnums.psm1 +++ b/lib/provider/enums/Icinga_ProviderEnums.psm1 @@ -470,6 +470,15 @@ 61= 'VSE'; 62= 'TPF'; } + +<################################################################################################## +################# /lib/provider/Services ########################################################### +##################################################################################################> + +[hashtable]$ServiceStatus = @{ + 'Stopped' = 1; + 'Running' = 4; +} [hashtable]$ProviderEnums = @{ #/lib/provider/bios @@ -493,6 +502,8 @@ WindowsOSProductSuite = $WindowsOSProductSuite; WindowsProductType = $WindowsProductType; WindowsOSType = $WindowsOSType; + #/lib/provider/services + ServiceStatus = $ServiceStatus; } Export-ModuleMember -Variable @('ProviderEnums'); \ No newline at end of file diff --git a/lib/provider/services/Icinga_ProviderServices.psm1 b/lib/provider/services/Icinga_ProviderServices.psm1 index 9dfc1cb..a2f71ab 100644 --- a/lib/provider/services/Icinga_ProviderServices.psm1 +++ b/lib/provider/services/Icinga_ProviderServices.psm1 @@ -62,4 +62,19 @@ function Get-IcingaServices() ); } return $ServiceData; +} + +function Get-IcingaServicesStatusTranslation() +{ + param ( + $Status + ) + + if ($Status -match "^\d+$") { + return $Status + } else { + $Status = $ProviderEnums.ServiceStatus.($Status); + } + + return $Status; } \ No newline at end of file From 51414a75069db1ee3127fc2a763ea0f97c30e157 Mon Sep 17 00:00:00 2001 From: Crited Date: Wed, 24 Jul 2019 11:44:33 +0200 Subject: [PATCH 025/259] Splitt into ConvertTo-ServiceStatusCode, to fit project structure, changed Free Space to Used Space --- lib/plugins/Invoke-IcingaCheckService.psm1 | 2 +- ... => Invoke-IcingaCheckUsedPartitionSpace.psm1} | 4 ++-- .../services/ConvertTo-ServiceStatusCode.psm1 | 14 ++++++++++++++ .../services/Icinga_ProviderServices.psm1 | 15 --------------- 4 files changed, 17 insertions(+), 18 deletions(-) rename lib/plugins/{Invoke-IcingaCheckFreePartition.psm1 => Invoke-IcingaCheckUsedPartitionSpace.psm1} (88%) create mode 100644 lib/provider/services/ConvertTo-ServiceStatusCode.psm1 diff --git a/lib/plugins/Invoke-IcingaCheckService.psm1 b/lib/plugins/Invoke-IcingaCheckService.psm1 index 0f62080..2479f5c 100644 --- a/lib/plugins/Invoke-IcingaCheckService.psm1 +++ b/lib/plugins/Invoke-IcingaCheckService.psm1 @@ -13,7 +13,7 @@ function Invoke-IcingaCheckService() $FoundService = Get-IcingaServices -Service $Service; $ServiceName = $FoundService.Values.metadata.ServiceName; $DisplayName = $FoundService.Values.metadata.DisplayName; - $Status = Get-IcingaServicesStatusTranslation -Status $Status; + $Status = ConvertTo-ServiceStatusCode -Status $Status; $StatusRaw = $FoundService.Values.configuration.Status.raw; $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Service "{0} ({1})"', $DisplayName, $ServiceName)) -Value $StatusRaw -ObjectExists $FoundService -ValueTranslation $ProviderEnums.ServicesStatus; diff --git a/lib/plugins/Invoke-IcingaCheckFreePartition.psm1 b/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 similarity index 88% rename from lib/plugins/Invoke-IcingaCheckFreePartition.psm1 rename to lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 index bab94fa..6fa57f8 100644 --- a/lib/plugins/Invoke-IcingaCheckFreePartition.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 @@ -1,7 +1,7 @@ Import-IcingaLib core\perfcounter; Import-IcingaLib icinga\plugin; -function Invoke-IcingaCheckFreePartition() +function Invoke-IcingaCheckUsedPartitionSpace() { param( $Warning, @@ -33,7 +33,7 @@ function Invoke-IcingaCheckFreePartition() } } - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Partition {0}', $Letter)) -Value $DiskFree.([string]::Format($Letter))."Free Space" -Unit '%'; + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Partition {0}', $Letter)) -Value (100-($DiskFree.([string]::Format($Letter))."Free Space")) -Unit '%'; $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; $DiskPackage.AddCheck($IcingaCheck); } diff --git a/lib/provider/services/ConvertTo-ServiceStatusCode.psm1 b/lib/provider/services/ConvertTo-ServiceStatusCode.psm1 new file mode 100644 index 0000000..1e4772f --- /dev/null +++ b/lib/provider/services/ConvertTo-ServiceStatusCode.psm1 @@ -0,0 +1,14 @@ +function ConvertTo-ServiceStatusCode() +{ + param ( + $Status + ) + + if ($Status -match "^\d+$") { + return $Status + } else { + $Status = $ProviderEnums.ServiceStatus.($Status); + } + + return $Status; +} \ No newline at end of file diff --git a/lib/provider/services/Icinga_ProviderServices.psm1 b/lib/provider/services/Icinga_ProviderServices.psm1 index a2f71ab..8774868 100644 --- a/lib/provider/services/Icinga_ProviderServices.psm1 +++ b/lib/provider/services/Icinga_ProviderServices.psm1 @@ -63,18 +63,3 @@ function Get-IcingaServices() } return $ServiceData; } - -function Get-IcingaServicesStatusTranslation() -{ - param ( - $Status - ) - - if ($Status -match "^\d+$") { - return $Status - } else { - $Status = $ProviderEnums.ServiceStatus.($Status); - } - - return $Status; -} \ No newline at end of file From dc2c4eac0baecff68d632934fe5f6bffa20ac093 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 24 Jul 2019 12:44:02 +0200 Subject: [PATCH 026/259] Added Windows Uptime metadata to Windows provider --- lib/provider/windows/Icinga_ProviderWindows.psm1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/provider/windows/Icinga_ProviderWindows.psm1 b/lib/provider/windows/Icinga_ProviderWindows.psm1 index d0d5d6d..126d016 100644 --- a/lib/provider/windows/Icinga_ProviderWindows.psm1 +++ b/lib/provider/windows/Icinga_ProviderWindows.psm1 @@ -24,6 +24,10 @@ function Get-IcingaWindows() 'BuildNumber' = $WindowsInformations.BuildNumber; 'OSArchitecture' = $WindowsInformations.OSArchitecture; 'NumberOfUsers' = $WindowsInformations.NumberOfUsers; + 'Uptime' = @{ + 'raw' = $WindowsInformations.LastBootUpTime; + 'value' = ((Get-Date) - $WindowsInformations.LastBootUpTime).TotalSeconds; + }; 'OSType' = @{ 'raw' = $WindowsInformations.OSType; 'value' = $ProviderEnums.WindowsOSType[[int]$WindowsInformations.OSType]; From 7cd8d5c6663abb218df0636759ef499b1dfbae76 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 24 Jul 2019 12:44:49 +0200 Subject: [PATCH 027/259] Fixed spacing for CPU error code enum --- lib/provider/enums/Icinga_ProviderEnums.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/provider/enums/Icinga_ProviderEnums.psm1 b/lib/provider/enums/Icinga_ProviderEnums.psm1 index 3818cfc..d69c48d 100644 --- a/lib/provider/enums/Icinga_ProviderEnums.psm1 +++ b/lib/provider/enums/Icinga_ProviderEnums.psm1 @@ -243,7 +243,7 @@ 8='The driver loader for the device is missing.'; 9='This device is not working properly because the controlling firmware is reporting the resources for the device incorrectly.'; 10='This device cannot start.'; - 11=' This device failed.'; + 11='This device failed.'; 12='This device cannot find enough free resources that it can use.'; 13="Windows cannot verify this device’s resources."; 14='This device cannot work properly until you restart your computer.'; From 54ef544b8ad9dcdfa417ebc63477c94933071fe6 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 24 Jul 2019 13:01:50 +0200 Subject: [PATCH 028/259] Check Packages will now return Unknown if no check is assigned --- lib/icinga/plugin/New-IcingaCheckPackage.psm1 | 73 ++++++++++++------- 1 file changed, 47 insertions(+), 26 deletions(-) diff --git a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 index bc57f08..b01c6f1 100644 --- a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 +++ b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 @@ -70,33 +70,37 @@ function New-IcingaCheckPackage() return; } - if ($this.opand) { - if ($this.CheckAllOk() -eq $FALSE) { - $this.GetWorstExitCode(); - } - } elseif($this.opor) { - if ($this.CheckOneOk() -eq $FALSE) { - $this.GetWorstExitCode(); - } - } elseif($this.opnone) { - if ($this.CheckOneOk() -eq $TRUE) { - $this.GetWorstExitCode(); - $this.exitcode = $IcingaEnums.IcingaExitCode.Critical; - } else { - $this.exitcode = $IcingaEnums.IcingaExitCode.Ok; - } - } elseif([int]$this.opmin -ne -1) { - if ($this.CheckMinimumOk() -eq $FALSE) { - $this.GetWorstExitCode(); - } else { - $this.exitcode = $IcingaEnums.IcingaExitCode.Ok; - } - } elseif([int]$this.opmax -ne -1) { - if ($this.CheckMaximumOk() -eq $FALSE) { - $this.GetWorstExitCode(); - } else { - $this.exitcode = $IcingaEnums.IcingaExitCode.Ok; + if ($this.checks.Count -ne 0) { + if ($this.opand) { + if ($this.CheckAllOk() -eq $FALSE) { + $this.GetWorstExitCode(); + } + } elseif($this.opor) { + if ($this.CheckOneOk() -eq $FALSE) { + $this.GetWorstExitCode(); + } + } elseif($this.opnone) { + if ($this.CheckOneOk() -eq $TRUE) { + $this.GetWorstExitCode(); + $this.exitcode = $IcingaEnums.IcingaExitCode.Critical; + } else { + $this.exitcode = $IcingaEnums.IcingaExitCode.Ok; + } + } elseif([int]$this.opmin -ne -1) { + if ($this.CheckMinimumOk() -eq $FALSE) { + $this.GetWorstExitCode(); + } else { + $this.exitcode = $IcingaEnums.IcingaExitCode.Ok; + } + } elseif([int]$this.opmax -ne -1) { + if ($this.CheckMaximumOk() -eq $FALSE) { + $this.GetWorstExitCode(); + } else { + $this.exitcode = $IcingaEnums.IcingaExitCode.Ok; + } } + } else { + $this.exitcode = $IcingaEnums.IcingaExitCode.Unknown; } if ([int]$this.exitcode -eq -1) { @@ -219,6 +223,20 @@ function New-IcingaCheckPackage() } } + $Check | Add-Member -membertype ScriptMethod -name 'PrintNoChecksConfigured' -value { + if ($this.checks.Count -eq 0) { + Write-Host ( + [string]::Format( + '{0}{1}: No checks configured for package "{2}"', + (New-StringTree ($this.spacing + 1)), + $IcingaEnums.IcingaExitCodeText.($this.exitcode), + $this.name + ) + ) + return; + } + } + $Check | Add-Member -membertype ScriptMethod -name 'WritePackageOutputStatus' -value { [string]$outputMessage = '{0}{1}: Check package "{2}" is {1}'; if ($this.verbose -ne 0) { @@ -252,14 +270,17 @@ function New-IcingaCheckPackage() } } + $this.WritePackageOutputStatus(); if ($printAll) { $this.WriteAllOutput(); + $this.PrintNoChecksConfigured(); } elseif ($printDetails) { # Now print Non-Ok Check outputs in case our package is not Ok if ([int]$this.exitcode -ne $IcingaEnums.IcingaExitCode.Ok) { $this.WriteCheckErrors(); + $this.PrintNoChecksConfigured(); } } } From dafc256ec45682b917307db567171f9b58b384ed Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 24 Jul 2019 13:02:03 +0200 Subject: [PATCH 029/259] Removed no longer required variables from Check Package --- lib/icinga/plugin/New-IcingaCheckPackage.psm1 | 2 -- 1 file changed, 2 deletions(-) diff --git a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 index b01c6f1..8d8428e 100644 --- a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 +++ b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 @@ -289,11 +289,9 @@ function New-IcingaCheckPackage() if ([int]$this.exitcode -eq [int]$IcingaEnums.IcingaExitCode.Unknown) { return; } - $worstCheck = $null; foreach ($check in $this.checks) { if ([int]$this.exitcode -lt $check.exitcode) { $this.exitcode = $check.exitcode; - $worstCheck = $check; } } } From 93951cd607a89cc6d6ed46843947ee2d0d076ef8 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 24 Jul 2019 14:28:53 +0200 Subject: [PATCH 030/259] Updated Services Provider, Enums and Helper functions * Added new function to get Service Name for Check output * Added missing Service State enums * Updated Service Status Code function to use existing Test-Numeric * Update Service Check with new Cmdlets --- lib/plugins/Invoke-IcingaCheckService.psm1 | 6 ++--- lib/provider/enums/Icinga_ProviderEnums.psm1 | 24 +++++++++++++++---- .../services/ConvertTo-ServiceStatusCode.psm1 | 13 +++++----- .../services/Get-IcingaServiceCheckName.psm1 | 20 ++++++++++++++++ 4 files changed, 50 insertions(+), 13 deletions(-) create mode 100644 lib/provider/services/Get-IcingaServiceCheckName.psm1 diff --git a/lib/plugins/Invoke-IcingaCheckService.psm1 b/lib/plugins/Invoke-IcingaCheckService.psm1 index 2479f5c..61ffcf4 100644 --- a/lib/plugins/Invoke-IcingaCheckService.psm1 +++ b/lib/plugins/Invoke-IcingaCheckService.psm1 @@ -1,4 +1,5 @@ Import-IcingaLib provider\services; +Import-IcingaLib provider\enums; Import-IcingaLib icinga\plugin; function Invoke-IcingaCheckService() @@ -11,12 +12,11 @@ function Invoke-IcingaCheckService() ); $FoundService = Get-IcingaServices -Service $Service; - $ServiceName = $FoundService.Values.metadata.ServiceName; - $DisplayName = $FoundService.Values.metadata.DisplayName; + $ServiceName = Get-IcingaServiceCheckName -ServiceInput $Service -Service $FoundService; $Status = ConvertTo-ServiceStatusCode -Status $Status; $StatusRaw = $FoundService.Values.configuration.Status.raw; - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Service "{0} ({1})"', $DisplayName, $ServiceName)) -Value $StatusRaw -ObjectExists $FoundService -ValueTranslation $ProviderEnums.ServicesStatus; + $IcingaCheck = New-IcingaCheck -Name $ServiceName -Value $StatusRaw -ObjectExists $FoundService -Translation $ProviderEnums.ServiceStatusName; $IcingaCheck.CritIfNotMatch($Status) | Out-Null; exit (New-IcingaCheckResult -Name "Service $Service" -Check $IcingaCheck -NoPerfData $TRUE -Compile); diff --git a/lib/provider/enums/Icinga_ProviderEnums.psm1 b/lib/provider/enums/Icinga_ProviderEnums.psm1 index 19ccb80..a8850fa 100644 --- a/lib/provider/enums/Icinga_ProviderEnums.psm1 +++ b/lib/provider/enums/Icinga_ProviderEnums.psm1 @@ -475,11 +475,26 @@ ################# /lib/provider/Services ########################################################### ##################################################################################################> -[hashtable]$ServiceStatus = @{ - 'Stopped' = 1; - 'Running' = 4; +[hashtable]$ServiceStatusName = @{ + 1 = 'Stopped'; + 2 = 'StartPending'; + 3 = 'StopPending'; + 4 = 'Running'; + 5 = 'ContinuePending'; + 6 = 'PausePending'; + 7 = 'Paused'; } - + +[hashtable]$ServiceStatus = @{ + 'Stopped' = 1; + 'StartPending' = 2; + 'StopPending' = 3; + 'Running' = 4; + 'ContinuePending' = 5; + 'PausePending' = 6; + 'Paused' = 7; +} + [hashtable]$ProviderEnums = @{ #/lib/provider/bios BiosCharacteristics = $BiosCharacteristics; @@ -504,6 +519,7 @@ WindowsOSType = $WindowsOSType; #/lib/provider/services ServiceStatus = $ServiceStatus; + ServiceStatusName =$ServiceStatusName; } Export-ModuleMember -Variable @('ProviderEnums'); \ No newline at end of file diff --git a/lib/provider/services/ConvertTo-ServiceStatusCode.psm1 b/lib/provider/services/ConvertTo-ServiceStatusCode.psm1 index 1e4772f..ce04d84 100644 --- a/lib/provider/services/ConvertTo-ServiceStatusCode.psm1 +++ b/lib/provider/services/ConvertTo-ServiceStatusCode.psm1 @@ -1,14 +1,15 @@ +Import-IcingaLib core\tools; +Import-IcingaLib provider\enums; + function ConvertTo-ServiceStatusCode() { param ( $Status ) - if ($Status -match "^\d+$") { - return $Status - } else { - $Status = $ProviderEnums.ServiceStatus.($Status); + if (Test-Numeric $Status) { + return [int]$Status } - return $Status; -} \ No newline at end of file + return [int]($ProviderEnums.ServiceStatus.$Status); +} diff --git a/lib/provider/services/Get-IcingaServiceCheckName.psm1 b/lib/provider/services/Get-IcingaServiceCheckName.psm1 new file mode 100644 index 0000000..8d8b4b3 --- /dev/null +++ b/lib/provider/services/Get-IcingaServiceCheckName.psm1 @@ -0,0 +1,20 @@ +function Get-IcingaServiceCheckName() +{ + param ( + [string]$ServiceInput, + $Service + ); + + if ($null -eq $Service) { + return [string]::Format( + 'Service "{0}"', + $ServiceInput + ); + } + + return [string]::Format( + 'Service "{0} ({1})"', + $Service.Values.metadata.DisplayName, + $Service.Values.metadata.ServiceName + ); +} From c14efdcc9f37fbeee29046e2cba9c1ddf0cf6e18 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 24 Jul 2019 14:37:42 +0200 Subject: [PATCH 031/259] Removed not required arguments for Service check --- lib/plugins/Invoke-IcingaCheckService.psm1 | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckService.psm1 b/lib/plugins/Invoke-IcingaCheckService.psm1 index 61ffcf4..8d20e07 100644 --- a/lib/plugins/Invoke-IcingaCheckService.psm1 +++ b/lib/plugins/Invoke-IcingaCheckService.psm1 @@ -6,9 +6,7 @@ function Invoke-IcingaCheckService() { param( [string]$Status, - [string]$Service, - [switch]$NoPerfData, - $Verbose + [string]$Service ); $FoundService = Get-IcingaServices -Service $Service; From 82cb773290b344c020011dce73133c7e56b65c5b Mon Sep 17 00:00:00 2001 From: Crited Date: Wed, 24 Jul 2019 15:02:58 +0200 Subject: [PATCH 032/259] added IcingaCheckProcessCount.psm1, modified Process-Provider to fit related Checks, deleted useless parameter in Checks --- .../Invoke-IcingaCheckProcessCount.psm1 | 27 ++++++++ lib/plugins/Invoke-IcingaCheckService.psm1 | 2 +- .../Invoke-IcingaCheckUsedPartitionSpace.psm1 | 6 +- .../process/Icinga_ProviderProcess.psm1 | 69 +++++++++++-------- 4 files changed, 71 insertions(+), 33 deletions(-) create mode 100644 lib/plugins/Invoke-IcingaCheckProcessCount.psm1 diff --git a/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 b/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 new file mode 100644 index 0000000..5b5b5ab --- /dev/null +++ b/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 @@ -0,0 +1,27 @@ +Import-IcingaLib provider\process; +Import-IcingaLib icinga\plugin; + +function Invoke-IcingaCheckProcessCount() +{ + param( + $Warning, + $Critical, + [array]$Process, + [switch]$NoPerfData, + $Verbose + ); + + $ProcessInformation = (Get-IcingaProcessData -Name $Process) + + $ProcessPackage = New-icingaCheckPackage -Name "Process Check" -OperatorAnd -Verbose $Verbose -NoPerfData $NoPerfData; + + foreach ($proc in $process) { + $ProcessCount = $ProcessInformation."Processes".$proc.processlist.Count; + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Process Count "{0}"', $proc)) -Value $ProcessCount; + $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + $ProcessPackage.AddCheck($IcingaCheck); + } + + + exit (New-IcingaCheckResult -Check $ProcessPackage -NoPerfData $TRUE -Compile); +} diff --git a/lib/plugins/Invoke-IcingaCheckService.psm1 b/lib/plugins/Invoke-IcingaCheckService.psm1 index 8d20e07..86cc058 100644 --- a/lib/plugins/Invoke-IcingaCheckService.psm1 +++ b/lib/plugins/Invoke-IcingaCheckService.psm1 @@ -17,5 +17,5 @@ function Invoke-IcingaCheckService() $IcingaCheck = New-IcingaCheck -Name $ServiceName -Value $StatusRaw -ObjectExists $FoundService -Translation $ProviderEnums.ServiceStatusName; $IcingaCheck.CritIfNotMatch($Status) | Out-Null; - exit (New-IcingaCheckResult -Name "Service $Service" -Check $IcingaCheck -NoPerfData $TRUE -Compile); + exit (New-IcingaCheckResult -Check $IcingaCheck -NoPerfData $TRUE -Compile); } diff --git a/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 b/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 index 6fa57f8..5c05c86 100644 --- a/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 @@ -13,8 +13,7 @@ function Invoke-IcingaCheckUsedPartitionSpace() ); $DiskFree = Get-IcingaDiskPartitions; - $DiskPackage = New-IcingaCheckPackage -Name 'Free Disk Space' -OperatorAnd -Verbos $Verbose; - [array]$CheckedPartitions; + $DiskPackage = New-IcingaCheckPackage -Name 'Used Partition Space' -OperatorAnd -Verbos $Verbose; foreach ($Letter in $DiskFree.Keys) { if ($Include.Count -ne 0) { @@ -24,7 +23,6 @@ function Invoke-IcingaCheckUsedPartitionSpace() } } - $CheckedPartitions+=$Letter if ($Exclude.Count -ne 0) { $Exclude = $Exclude.trim(' :/\'); @@ -38,5 +36,5 @@ function Invoke-IcingaCheckUsedPartitionSpace() $DiskPackage.AddCheck($IcingaCheck); } - exit (New-IcingaCheckResult -Name 'Free Disk Space' -Check $DiskPackage -NoPerfData $NoPerfData -Compile); + exit (New-IcingaCheckResult -Check $DiskPackage -NoPerfData $NoPerfData -Compile); } diff --git a/lib/provider/process/Icinga_ProviderProcess.psm1 b/lib/provider/process/Icinga_ProviderProcess.psm1 index c86c6ee..5f81296 100644 --- a/lib/provider/process/Icinga_ProviderProcess.psm1 +++ b/lib/provider/process/Icinga_ProviderProcess.psm1 @@ -14,9 +14,12 @@ function Add-IcingaProcessPerfData() function Get-IcingaProcessData { + param( + [array]$Process + ); + $ProcessInformation = Get-WmiObject Win32_Process; $ProcessPerfDataList = Get-WmiObject Win32_PerfFormattedData_PerfProc_Process; - $ProcessUniqueList = Get-WmiObject Win32_Process | Select-Object name -unique; $CPUCoreCount = Get-IcingaCPUCount; @@ -25,8 +28,14 @@ function Get-IcingaProcessData { [hashtable]$ProcessNamesUnique = @{}; [hashtable]$ProcessIDsByName = @{}; - foreach ($process in $ProcessInformation) { - [string]$processName = $process.Name.Replace('.exe', ''); + foreach ($processinfo in $ProcessInformation) { + [string]$processName = $processinfo.Name.Replace('.exe', ''); + + If ($null -ne $Process) { + If (-Not ($Process.Contains($processName))) { + continue; + } + } if ($ProcessList.ContainsKey($processName) -eq $FALSE) { $ProcessList.Add($processName, @{ @@ -36,56 +45,60 @@ function Get-IcingaProcessData { } $ProcessList[$processName]['ProcessList'].Add( - [string]$process.ProcessID, @{ - 'Name' = $process.Name; - 'ProcessId' = $process.ProcessId; - 'Priority' = $process.Priority; - 'PageFileUsage' = $process.PageFileUsage; - 'ThreadCount' = $process.ThreadCount; - 'KernelModeTime' = $process.KernelModeTime; - 'UserModeTime' = $process.UserModeTime; - 'WorkingSetSize' = $process.WorkingSetSize; - 'CommandLine' = $process.CommandLine; + [string]$processinfo.ProcessID, @{ + 'Name' = $processinfo.Name; + 'ProcessId' = $processinfo.ProcessId; + 'Priority' = $processinfo.Priority; + 'PageFileUsage' = $processinfo.PageFileUsage; + 'ThreadCount' = $processinfo.ThreadCount; + 'KernelModeTime' = $processinfo.KernelModeTime; + 'UserModeTime' = $processinfo.UserModeTime; + 'WorkingSetSize' = $processinfo.WorkingSetSize; + 'CommandLine' = $processinfo.CommandLine; } ); - Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'ThreadCount' -Process $process; - Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'PageFileUsage' -Process $process; - Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'KernelModeTime' -Process $process; - Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'UserModeTime' -Process $process; - Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'WorkingSetSize' -Process $process; + Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'ThreadCount' -Process $processinfo; + Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'PageFileUsage' -Process $processinfo; + Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'KernelModeTime' -Process $processinfo; + Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'UserModeTime' -Process $processinfo; + Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'WorkingSetSize' -Process $processinfo; } - foreach ($process in $ProcessPerfDataList) { - if ($process.Name -eq '_Total' -Or $process.Name -eq 'Idle') { + foreach ($processinfo in $ProcessPerfDataList) { + if ($processinfo.Name -eq '_Total' -Or $processinfo.Name -eq 'Idle') { continue; } - [string]$processName = $process.Name.Split('#')[0]; - [string]$ProcessId = $process.IDProcess; + If ($null -ne $Process) { + If (-Not ($Process.Contains($processName))) { + continue; + } + } + + [string]$processName = $processinfo.Name.Split('#')[0]; + [string]$ProcessId = $processinfo.IDProcess; if ($ProcessList.ContainsKey($processName) -eq $FALSE) { - Write-Host 'Unknown Process Name: ' $processName; continue; } if ($ProcessList[$processName]['ProcessList'].ContainsKey($ProcessId) -eq $FALSE) { - Write-Host 'Unknown Process ID: ' $ProcessId; continue; } $ProcessList[$processName]['ProcessList'][$ProcessId].Add( - 'WorkingSetPrivate', $process.WorkingSetPrivate + 'WorkingSetPrivate', $processinfo.WorkingSetPrivate ); $ProcessList[$processName]['ProcessList'][$ProcessId].Add( - 'PercentProcessorTime', ($process.PercentProcessorTime / $CPUCoreCount) + 'PercentProcessorTime', ($processinfo.PercentProcessorTime / $CPUCoreCount) ); Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'WorkingSetPrivate' -Process $process; if ($ProcessList[$processName]['PerformanceData'].ContainsKey('PercentProcessorTime') -eq $FALSE) { - $ProcessList[$processName]['PerformanceData'].Add('PercentProcessorTime', ($process.PercentProcessorTime / $CPUCoreCount)); + $ProcessList[$processName]['PerformanceData'].Add('PercentProcessorTime', ($processinfo.PercentProcessorTime / $CPUCoreCount)); } else { - $ProcessList[$processName]['PerformanceData']['PercentProcessorTime'] += ($process.PercentProcessorTime / $CPUCoreCount); + $ProcessList[$processName]['PerformanceData']['PercentProcessorTime'] += ($processinfo.PercentProcessorTime / $CPUCoreCount); } } From 79fa198931bd89be1355e1e55f9572a5aa3a2fd0 Mon Sep 17 00:00:00 2001 From: Crited Date: Wed, 24 Jul 2019 15:34:49 +0200 Subject: [PATCH 033/259] Added further options in ProcessCount-Check --- lib/plugins/Invoke-IcingaCheckProcessCount.psm1 | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 b/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 index 5b5b5ab..0efd0f0 100644 --- a/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 +++ b/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 @@ -15,13 +15,20 @@ function Invoke-IcingaCheckProcessCount() $ProcessPackage = New-icingaCheckPackage -Name "Process Check" -OperatorAnd -Verbose $Verbose -NoPerfData $NoPerfData; - foreach ($proc in $process) { - $ProcessCount = $ProcessInformation."Processes".$proc.processlist.Count; - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Process Count "{0}"', $proc)) -Value $ProcessCount; + if ($Process.Count -eq 0) { + $ProcessCount = $ProcessInformation['Process Count']; + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Process Count')) -Value $ProcessCount; $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; $ProcessPackage.AddCheck($IcingaCheck); + } else { + foreach ($proc in $process) { + $ProcessCount = $ProcessInformation."Processes".$proc.processlist.Count; + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Process Count "{0}"', $proc)) -Value $ProcessCount; + $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + $ProcessPackage.AddCheck($IcingaCheck); + } } - exit (New-IcingaCheckResult -Check $ProcessPackage -NoPerfData $TRUE -Compile); + exit (New-IcingaCheckResult -Check $ProcessPackage -NoPerfData $NoPerfData -Compile); } From fca6e2e8738d5ac701d52e51874413e9304e3254 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 24 Jul 2019 17:10:16 +0200 Subject: [PATCH 034/259] Added support to check if objects exist on icinga checks --- lib/icinga/plugin/New-IcingaCheck.psm1 | 48 ++++++++++++++++---------- 1 file changed, 29 insertions(+), 19 deletions(-) diff --git a/lib/icinga/plugin/New-IcingaCheck.psm1 b/lib/icinga/plugin/New-IcingaCheck.psm1 index d65d78d..160f047 100644 --- a/lib/icinga/plugin/New-IcingaCheck.psm1 +++ b/lib/icinga/plugin/New-IcingaCheck.psm1 @@ -9,29 +9,31 @@ function New-IcingaCheck() $Unit = $null, [string]$Minimum = '', [string]$Maximum = '', + $ObjectExists = -1, [switch]$NoPerfData ); $Check = New-Object -TypeName PSObject; - $Check | Add-Member -membertype NoteProperty -name 'name' -value $Name; - $Check | Add-Member -membertype NoteProperty -name 'verbose' -value 0; - $Check | Add-Member -membertype NoteProperty -name 'messages' -value @(); - $Check | Add-Member -membertype NoteProperty -name 'oks' -value @(); - $Check | Add-Member -membertype NoteProperty -name 'warnings' -value @(); - $Check | Add-Member -membertype NoteProperty -name 'criticals' -value @(); - $Check | Add-Member -membertype NoteProperty -name 'unknowns' -value @(); - $Check | Add-Member -membertype NoteProperty -name 'value' -value $Value; - $Check | Add-Member -membertype NoteProperty -name 'exitcode' -value -1; - $Check | Add-Member -membertype NoteProperty -name 'unit' -value $Unit; - $Check | Add-Member -membertype NoteProperty -name 'spacing' -value 0; - $Check | Add-Member -membertype NoteProperty -name 'compiled' -value $FALSE; - $Check | Add-Member -membertype NoteProperty -name 'perfdata' -value (-Not $NoPerfData); - $Check | Add-Member -membertype NoteProperty -name 'warning' -value ''; - $Check | Add-Member -membertype NoteProperty -name 'critical' -value ''; - $Check | Add-Member -membertype NoteProperty -name 'minimum' -value $Minimum; - $Check | Add-Member -membertype NoteProperty -name 'maximum' -value $Maximum; - $Check | Add-Member -membertype NoteProperty -name 'checks' -value $null; - $Check | Add-Member -membertype NoteProperty -name 'completed' -value $FALSE; + $Check | Add-Member -membertype NoteProperty -name 'name' -value $Name; + $Check | Add-Member -membertype NoteProperty -name 'verbose' -value 0; + $Check | Add-Member -membertype NoteProperty -name 'messages' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'oks' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'warnings' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'criticals' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'unknowns' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'value' -value $Value; + $Check | Add-Member -membertype NoteProperty -name 'exitcode' -value -1; + $Check | Add-Member -membertype NoteProperty -name 'unit' -value $Unit; + $Check | Add-Member -membertype NoteProperty -name 'spacing' -value 0; + $Check | Add-Member -membertype NoteProperty -name 'compiled' -value $FALSE; + $Check | Add-Member -membertype NoteProperty -name 'perfdata' -value (-Not $NoPerfData); + $Check | Add-Member -membertype NoteProperty -name 'warning' -value ''; + $Check | Add-Member -membertype NoteProperty -name 'critical' -value ''; + $Check | Add-Member -membertype NoteProperty -name 'minimum' -value $Minimum; + $Check | Add-Member -membertype NoteProperty -name 'maximum' -value $Maximum; + $Check | Add-Member -membertype NoteProperty -name 'objectexists' -value $ObjectExists; + $Check | Add-Member -membertype NoteProperty -name 'checks' -value $null; + $Check | Add-Member -membertype NoteProperty -name 'completed' -value $FALSE; $Check | Add-Member -membertype ScriptMethod -name 'AddSpacing' -value { $this.spacing += 1; @@ -404,6 +406,14 @@ function New-IcingaCheck() $Check | Add-Member -membertype ScriptMethod -name 'AddInternalCheckMessage' -value { param($state, $value, $type); + if ($this.objectexists -ne -1 -And $null -eq $this.objectexists) { + $this.SetExitCode($IcingaEnums.IcingaExitCode.Unknown); + $this.AddMessage([string]::Format( + '{0} does not exist', $this.name + ), $IcingaEnums.IcingaExitCode.Unknown); + return; + } + $this.SetExitCode($state); $this.AddMessage([string]::Format( '{0} {1}{4} is {2} {3}{4}', $this.name, $this.value, $type, $value, $this.unit From c64fd63d978aeb368fe743a36f7fde36938c029e Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 24 Jul 2019 17:19:56 +0200 Subject: [PATCH 035/259] Added support to translate check values to speaking values on output --- lib/icinga/plugin/New-IcingaCheck.psm1 | 46 +++++++++++++++++++++++--- 1 file changed, 42 insertions(+), 4 deletions(-) diff --git a/lib/icinga/plugin/New-IcingaCheck.psm1 b/lib/icinga/plugin/New-IcingaCheck.psm1 index 160f047..09a1155 100644 --- a/lib/icinga/plugin/New-IcingaCheck.psm1 +++ b/lib/icinga/plugin/New-IcingaCheck.psm1 @@ -10,6 +10,7 @@ function New-IcingaCheck() [string]$Minimum = '', [string]$Maximum = '', $ObjectExists = -1, + $Translation = $null, [switch]$NoPerfData ); @@ -32,6 +33,7 @@ function New-IcingaCheck() $Check | Add-Member -membertype NoteProperty -name 'minimum' -value $Minimum; $Check | Add-Member -membertype NoteProperty -name 'maximum' -value $Maximum; $Check | Add-Member -membertype NoteProperty -name 'objectexists' -value $ObjectExists; + $Check | Add-Member -membertype NoteProperty -name 'translation' -value $Translation; $Check | Add-Member -membertype NoteProperty -name 'checks' -value $null; $Check | Add-Member -membertype NoteProperty -name 'completed' -value $FALSE; @@ -403,6 +405,26 @@ function New-IcingaCheck() return $this; } + $Check | Add-Member -membertype ScriptMethod -name 'TranslateValue' -value { + param($value); + + if ($null -eq $this.translation -Or $null -eq $value) { + return $value; + } + + $checkValue = $value; + + if ((Test-Numeric $checkValue)) { + $checkValue = [int]$checkValue; + } + + if ($this.translation.ContainsKey($checkValue)) { + return $this.translation[$checkValue]; + } + + return $value; + } + $Check | Add-Member -membertype ScriptMethod -name 'AddInternalCheckMessage' -value { param($state, $value, $type); @@ -415,9 +437,17 @@ function New-IcingaCheck() } $this.SetExitCode($state); - $this.AddMessage([string]::Format( - '{0} {1}{4} is {2} {3}{4}', $this.name, $this.value, $type, $value, $this.unit - ), $state); + $this.AddMessage( + [string]::Format( + '{0} {1}{4} is {2} {3}{4}', + $this.name, + $this.TranslateValue($this.value), + $type, + $this.TranslateValue($value), + $this.unit + ), + $state + ); switch ($state) { $IcingaEnums.IcingaExitCode.Warning { @@ -562,7 +592,15 @@ function New-IcingaCheck() $Check | Add-Member -membertype ScriptMethod -name 'AddOkOutput' -value { if ([int]$this.exitcode -eq -1) { $this.exitcode = $IcingaEnums.IcingaExitCode.Ok; - $this.AddMessage([string]::Format('{0} is {1}{2}', $this.name, $this.value, $this.unit), $IcingaEnums.IcingaExitCode.Ok); + $this.AddMessage( + [string]::Format( + '{0} is {1}{2}', + $this.name, + $this.TranslateValue($this.value), + $this.unit + ), + $IcingaEnums.IcingaExitCode.Ok + ); } } From e65d43a829519c8eb28d7cfe73ab35f6dff956cb Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 24 Jul 2019 17:21:10 +0200 Subject: [PATCH 036/259] Fixed $null code styling comparison --- lib/icinga/plugin/New-IcingaCheckResult.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/icinga/plugin/New-IcingaCheckResult.psm1 b/lib/icinga/plugin/New-IcingaCheckResult.psm1 index c7126ff..b7b07c6 100644 --- a/lib/icinga/plugin/New-IcingaCheckResult.psm1 +++ b/lib/icinga/plugin/New-IcingaCheckResult.psm1 @@ -13,7 +13,7 @@ function New-IcingaCheckresult() $CheckResult | Add-Member -membertype NoteProperty -name 'noperfdata' -value $NoPerfData; $CheckResult | Add-Member -membertype ScriptMethod -name 'Compile' -value { - if ($this.check -eq $null) { + if ($null -eq $this.check) { return $IcingaEnums.IcingaExitCode.Unknown; } From 41ea4e51b94a6e9539804312c6a136fe8d455095 Mon Sep 17 00:00:00 2001 From: Niko Martini Date: Thu, 25 Jul 2019 15:51:31 +0200 Subject: [PATCH 037/259] Fixed Code Styling --- lib/provider/memory/Icinga_ProviderMemory.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/provider/memory/Icinga_ProviderMemory.psm1 b/lib/provider/memory/Icinga_ProviderMemory.psm1 index f9abcd0..68ab0ed 100644 --- a/lib/provider/memory/Icinga_ProviderMemory.psm1 +++ b/lib/provider/memory/Icinga_ProviderMemory.psm1 @@ -1,5 +1,5 @@ Import-IcingaLib provider\enums; -function Get-IcingaMemory () +function Get-IcingaMemory() { <# Collects the most important Memory informations, e.g. name, version, manufacturer#> From c82c58b634a3638cf170053adff6705701fd5f88 Mon Sep 17 00:00:00 2001 From: Niko Martini Date: Thu, 25 Jul 2019 16:19:38 +0200 Subject: [PATCH 038/259] Fixed Code Styling --- lib/provider/memory/Show-IcingaMemoryData.psm1 | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/provider/memory/Show-IcingaMemoryData.psm1 b/lib/provider/memory/Show-IcingaMemoryData.psm1 index 7bf8e5f..bd2a28c 100644 --- a/lib/provider/memory/Show-IcingaMemoryData.psm1 +++ b/lib/provider/memory/Show-IcingaMemoryData.psm1 @@ -1,6 +1,5 @@ function Show-IcingaMemoryData () { - $MEMInformation = Get-CimInstance Win32_PhysicalMemory; [hashtable]$MEMData = @{}; From 4bccfb87fd03c79b817726996c0c2e66fa5b91b5 Mon Sep 17 00:00:00 2001 From: Niko Martini Date: Thu, 25 Jul 2019 17:48:19 +0200 Subject: [PATCH 039/259] Introduce new function for astoll --- lib/plugins/Invoke-IcingaCheckUsers.psm1 | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 lib/plugins/Invoke-IcingaCheckUsers.psm1 diff --git a/lib/plugins/Invoke-IcingaCheckUsers.psm1 b/lib/plugins/Invoke-IcingaCheckUsers.psm1 new file mode 100644 index 0000000..fd2a3e3 --- /dev/null +++ b/lib/plugins/Invoke-IcingaCheckUsers.psm1 @@ -0,0 +1,4 @@ +function Invoke-IcingaCheckUsers() +{ + +} \ No newline at end of file From df20e7a0f3aecda3d0ec98326324c4de8fe8d3b4 Mon Sep 17 00:00:00 2001 From: Niko Martini Date: Thu, 25 Jul 2019 18:16:33 +0200 Subject: [PATCH 040/259] Toolset for conversion --- lib/core/tools/ConvertTo-Seconds.psm1 | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 lib/core/tools/ConvertTo-Seconds.psm1 diff --git a/lib/core/tools/ConvertTo-Seconds.psm1 b/lib/core/tools/ConvertTo-Seconds.psm1 new file mode 100644 index 0000000..afb3a22 --- /dev/null +++ b/lib/core/tools/ConvertTo-Seconds.psm1 @@ -0,0 +1,27 @@ +# year month week days hours minutes seconds milliseconds + +function ConvertTo-Seconds() +{ + param( + [single]$Value, + [string]$Unit + ); + + switch ($Unit) { + { 'ms', 'milliseconds' -contains $_ } { $result = ($Value / [math]::Pow(10, 3)); $boolOption = $true; } + { 's', 'seconds' -contains $_ } { $result = $Value; $boolOption = $true; } + { 'm', 'minutes' -contains $_ } { $result = ($Value * 60); $boolOption = $true; } + { 'h', 'hours' -contains $_ } { $result = ($Value * 3600); $boolOption = $true; } + { 'd', 'day' -contains $_ } { $result = ($Value * 86400); $boolOption = $true; } + { 'W', 'Week' -contains $_ } { $result = ($Value * 604800); $boolOption = $true; } + { 'M', 'Month' -contains $_ } { $result = ($Value * [math]::Pow(2.628, 6)); $boolOption = $true; } + { 'Y', 'Year' -contains $_ } { $result = ($Value * [math]::Pow(10, 7)); $boolOption = $true; } + default { + if (-Not $boolOption) { + Throw 'Invalid input'; + } + } + } + + return $result; +} \ No newline at end of file From 44200eda946413cb45d90196bbbee698d9910c2d Mon Sep 17 00:00:00 2001 From: Niko Martini Date: Thu, 25 Jul 2019 18:29:21 +0200 Subject: [PATCH 041/259] List PerformanceCounter for Memory --- .../memory/Get-IcingaMemoryPerformanceCounter.psm1 | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 diff --git a/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 b/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 new file mode 100644 index 0000000..49e29e7 --- /dev/null +++ b/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 @@ -0,0 +1,13 @@ +function Get-IcingaMemoryPerformanceCounter() +{ + $MemoryStart = (Show-IcingaPerformanceCounters -CounterCategory 'Memory').Keys; + $MemoryCounter = New-IcingaPerformanceCounterArray -Counter $MemoryStart; + [hashtable]$Result = @{}; + + foreach ($item in $MemoryCounter.Keys) { + $counter = $item.trimstart('\Memory\'); + $Result.Add($counter, $MemoryCounter[$item]); + } + + return $Result; +} From 26d0887ae9271b711753a859e28f296be4b23a0b Mon Sep 17 00:00:00 2001 From: Niko Martini Date: Thu, 25 Jul 2019 18:31:08 +0200 Subject: [PATCH 042/259] List various MemoryUsage --- lib/provider/memory/Get-IcingaMemoryUsage.psm1 | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 lib/provider/memory/Get-IcingaMemoryUsage.psm1 diff --git a/lib/provider/memory/Get-IcingaMemoryUsage.psm1 b/lib/provider/memory/Get-IcingaMemoryUsage.psm1 new file mode 100644 index 0000000..bf206a1 --- /dev/null +++ b/lib/provider/memory/Get-IcingaMemoryUsage.psm1 @@ -0,0 +1,14 @@ +function Get-IcingaMemoryUsage() +{ + $MEMUsageInformations = Get-CimInstance Win32_OperatingSystem; + + [hashtable]$MEMUsageData = @{ + 'FreePhysicalMemory' = $MEMUsageInformations.FreePhysicalMemory; + 'FreeVirtualMemory' = $MEMUsageInformations.FreeVirtualMemory; + 'TotalVirtualMemorySize' = $MEMUsageInformations.TotalVirtualMemorySize; + 'TotalVisibleMemorySize' = $MEMUsageInformations.TotalVisibleMemorySize; + 'MaxProcessMemorySize' = $MEMUsageInformations.MaxProcessMemorySize; + } + + return $MEMUsageData; +} From c6e40b18a6c3feb31466ea834a4259ef6e12e7ef Mon Sep 17 00:00:00 2001 From: Crited Date: Fri, 26 Jul 2019 13:01:51 +0200 Subject: [PATCH 043/259] Added IcingaCheckUsers and Libraray for users --- lib/plugins/Invoke-IcingaCheckUsers.psm1 | 26 ++++++++++++++++++++++++ lib/provider/users/Get-IcingaUsers.psm1 | 18 ++++++++++++++++ 2 files changed, 44 insertions(+) create mode 100644 lib/provider/users/Get-IcingaUsers.psm1 diff --git a/lib/plugins/Invoke-IcingaCheckUsers.psm1 b/lib/plugins/Invoke-IcingaCheckUsers.psm1 index fd2a3e3..0a87ebe 100644 --- a/lib/plugins/Invoke-IcingaCheckUsers.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUsers.psm1 @@ -1,4 +1,30 @@ +Import-IcingaLib icinga\plugin; +Import-IcingaLib provider\users; + function Invoke-IcingaCheckUsers() { + param ( + [array]$username, + [switch]$NoPerfData, + $Verbose + + ); + $UsersPackage = New-IcingaCheckPackage -Name 'Users' -OperatorAnd -Verbos $Verbose; + $UserInformation = Get-IcingaUsers -Username $username; + + foreach ($ExistingUser in $UserInformation) { + Write-Host $ExistingUser; + If ($null -eq $ExistingUser) + { + continue; + } + $Status = $ExistingUser.Enabled; + + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('User {0} Status {1} ', $ExistingUser, $Status)) -Value $Status -NoPerfData; + $IcingaCheck.CritIfNotMatch('True') | Out-Null; + $UsersPackage.AddCheck($IcingaCheck); + } + + exit (New-IcingaCheckResult -Name 'Users' -Check $UsersPackage -NoPerfData $NoPerfData -Compile); } \ No newline at end of file diff --git a/lib/provider/users/Get-IcingaUsers.psm1 b/lib/provider/users/Get-IcingaUsers.psm1 new file mode 100644 index 0000000..366e974 --- /dev/null +++ b/lib/provider/users/Get-IcingaUsers.psm1 @@ -0,0 +1,18 @@ +function Get-IcingaUsers () +{ + param ( + [array]$Username + ); + + + if ($null -eq $Username) { + return Get-LocalUser; + } else { + [array]$UserInformation + foreach ($UniqueUser in $Username) { + [array]$UserInformation += Get-LocalUser -Name $UniqueUser; + } + } + + return $UserInformation; +} \ No newline at end of file From 1da13b3eb1bdc2fa11d91df9687db8d6a90761a1 Mon Sep 17 00:00:00 2001 From: Niko Martini Date: Thu, 15 Aug 2019 11:28:18 +0200 Subject: [PATCH 044/259] WIP --- lib/core/tools/ConvertTo-Seconds.psm1 | 29 +++++++++++++++++---------- 1 file changed, 18 insertions(+), 11 deletions(-) diff --git a/lib/core/tools/ConvertTo-Seconds.psm1 b/lib/core/tools/ConvertTo-Seconds.psm1 index afb3a22..85e7f41 100644 --- a/lib/core/tools/ConvertTo-Seconds.psm1 +++ b/lib/core/tools/ConvertTo-Seconds.psm1 @@ -3,19 +3,26 @@ function ConvertTo-Seconds() { param( - [single]$Value, - [string]$Unit + [string]$Value, + [char]$Unit, + [switch]$Milliseconds ); - switch ($Unit) { - { 'ms', 'milliseconds' -contains $_ } { $result = ($Value / [math]::Pow(10, 3)); $boolOption = $true; } - { 's', 'seconds' -contains $_ } { $result = $Value; $boolOption = $true; } - { 'm', 'minutes' -contains $_ } { $result = ($Value * 60); $boolOption = $true; } - { 'h', 'hours' -contains $_ } { $result = ($Value * 3600); $boolOption = $true; } - { 'd', 'day' -contains $_ } { $result = ($Value * 86400); $boolOption = $true; } - { 'W', 'Week' -contains $_ } { $result = ($Value * 604800); $boolOption = $true; } - { 'M', 'Month' -contains $_ } { $result = ($Value * [math]::Pow(2.628, 6)); $boolOption = $true; } - { 'Y', 'Year' -contains $_ } { $result = ($Value * [math]::Pow(10, 7)); $boolOption = $true; } + #100 D + #100 D + $Unit = $Value.Substring($Value.get_Length()-2)[0]; + [single]$ValueSplitted = $Value; + #$Name.Substring($Name.get_Length()-1); + #$Name.Substring(0,$Name.get_Length()-1); + switch ([int][char]$Unit) { +# { 'ms', 'milliseconds' -contains $_ } { $result = ($Value / [math]::Pow(10, 3)); $boolOption = $true; } + { 115 -contains $_ } { $result = $ValueSplitted; $boolOption = $true; } + { 109 -contains $_ } { $result = ($ValueSplitted * 60); $boolOption = $true; } + { 104 -contains $_ } { $result = ($ValueSplitted * 3600); $boolOption = $true; } + { 100 -contains $_ } { $result = ($ValueSplitted * 86400); $boolOption = $true; } + { 87 -contains $_ } { $result = ($ValueSplitted * 604800); $boolOption = $true; } + { 77 -contains $_ } { $result = ($ValueSplitted * (2.5[math]::Pow(10, 6))); $boolOption = $true; } + { 89 -contains $_ } { $result = ($ValueSplitted * (3.10[math]::Pow(10, 7))); $boolOption = $true; } default { if (-Not $boolOption) { Throw 'Invalid input'; From 208df5a8bc2f8458f9f1535fa38f18366fc68b4e Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 19 Aug 2019 12:12:11 +0200 Subject: [PATCH 045/259] Improved code styling and small fixes for IcingaUsers --- lib/provider/users/Get-IcingaUsers.psm1 | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/lib/provider/users/Get-IcingaUsers.psm1 b/lib/provider/users/Get-IcingaUsers.psm1 index 366e974..01ec6ed 100644 --- a/lib/provider/users/Get-IcingaUsers.psm1 +++ b/lib/provider/users/Get-IcingaUsers.psm1 @@ -1,18 +1,17 @@ -function Get-IcingaUsers () +function Get-IcingaUsers() { param ( [array]$Username ); - if ($null -eq $Username) { return Get-LocalUser; } else { - [array]$UserInformation + [array]$UserInformation = @(); foreach ($UniqueUser in $Username) { - [array]$UserInformation += Get-LocalUser -Name $UniqueUser; + $UserInformation += (Get-LocalUser -Name $UniqueUser); } } return $UserInformation; -} \ No newline at end of file +} From a02c57b9a039c0a3310ece60a1c3be329c7ceac3 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 19 Aug 2019 12:12:59 +0200 Subject: [PATCH 046/259] Added provider for logged in Windows users --- .../users/Get-IcingaLoggedOnUsers.psm1 | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 lib/provider/users/Get-IcingaLoggedOnUsers.psm1 diff --git a/lib/provider/users/Get-IcingaLoggedOnUsers.psm1 b/lib/provider/users/Get-IcingaLoggedOnUsers.psm1 new file mode 100644 index 0000000..351525c --- /dev/null +++ b/lib/provider/users/Get-IcingaLoggedOnUsers.psm1 @@ -0,0 +1,43 @@ +function Get-IcingaLoggedOnUsers() +{ + param( + [array]$UserFilter = @() + ); + + [hashtable]$UserList = @{}; + [int]$UserCount = 0; + $UserList.Add('users', @{ }); + + $Users = Get-CIMInstance Win32_LoggedOnUser | Select-Object Antecedent, Dependent; + + foreach ($user in $Users) { + [string]$username = $user.Antecedent.Name; + + if ($UserFilter.Count -ne 0) { + if (-Not $UserFilter.Contains($username)) { + continue; + } + } + + $UserCount += 1; + + if ($UserList.users.ContainsKey($username) -eq $FALSE) { + $UserList.users.Add( + $username, + @{ + 'domains' = @($user.Antecedent.Domain); + 'logonid' = @($user.Dependent.LogonId); + 'count' = 1; + } + ); + } else { + $UserList.users[$username].domains += $user.Antecedent.Domain; + $UserList.users[$username].logonid += $user.Dependent.LogonId; + $UserList.users[$username].count += 1; + } + } + + $UserList.Add('count', $UserCount); + + return $UserList; +} From 8e8d879ff217070b8f75da39a32413a118ce5a33 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 19 Aug 2019 12:13:24 +0200 Subject: [PATCH 047/259] Improved Icinga Check User Plugin --- lib/plugins/Invoke-IcingaCheckUsers.psm1 | 44 +++++++++++++++--------- 1 file changed, 28 insertions(+), 16 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckUsers.psm1 b/lib/plugins/Invoke-IcingaCheckUsers.psm1 index 0a87ebe..1b43dcc 100644 --- a/lib/plugins/Invoke-IcingaCheckUsers.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUsers.psm1 @@ -4,27 +4,39 @@ Import-IcingaLib provider\users; function Invoke-IcingaCheckUsers() { param ( - [array]$username, + [array]$Username, + $Warning, + $Critical, [switch]$NoPerfData, - $Verbose - + [int]$Verbose ); - $UsersPackage = New-IcingaCheckPackage -Name 'Users' -OperatorAnd -Verbos $Verbose; - $UserInformation = Get-IcingaUsers -Username $username; + $UsersPackage = New-IcingaCheckPackage -Name 'Users' -OperatorAnd -Verbose $Verbose; + $LoggedOnUsers = Get-IcingaLoggedOnUsers -UserFilter $Username; - foreach ($ExistingUser in $UserInformation) { - Write-Host $ExistingUser; - If ($null -eq $ExistingUser) - { - continue; - } - $Status = $ExistingUser.Enabled; + if ($Username.Count -ne 0) { + foreach ($User in $Username) { + $IcingaCheck = $null; + [int]$LoginCount = 0; - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('User {0} Status {1} ', $ExistingUser, $Status)) -Value $Status -NoPerfData; - $IcingaCheck.CritIfNotMatch('True') | Out-Null; - $UsersPackage.AddCheck($IcingaCheck); + if ($LoggedOnUsers.users.ContainsKey($User)) { + $LoginCount = $LoggedOnUsers.users.$User.count; + } + + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Logged On User "{0}"', $User)) -Value $LoginCount; + $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + $UsersPackage.AddCheck($IcingaCheck); + } + } else { + foreach ($User in $LoggedOnUsers.users.Keys) { + $UsersPackage.AddCheck( + (New-IcingaCheck -Name ([string]::Format('Logged On User "{0}"', $User)) -Value $LoggedOnUsers.users.$User.count) + ); + } + $IcingaCheck = New-IcingaCheck -Name 'Logged On Users' -Value $LoggedOnUsers.count; + $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + $UsersPackage.AddCheck($IcingaCheck) } exit (New-IcingaCheckResult -Name 'Users' -Check $UsersPackage -NoPerfData $NoPerfData -Compile); -} \ No newline at end of file +} From 89647ede8f287564a768be13cad1e8ea566ca523 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 19 Aug 2019 12:14:02 +0200 Subject: [PATCH 048/259] Added tool function to translate Icinga Args in PS Args --- lib/core/tools/Split-IcingaCheckCommandArgs.psm1 | 9 +++++++++ 1 file changed, 9 insertions(+) create mode 100644 lib/core/tools/Split-IcingaCheckCommandArgs.psm1 diff --git a/lib/core/tools/Split-IcingaCheckCommandArgs.psm1 b/lib/core/tools/Split-IcingaCheckCommandArgs.psm1 new file mode 100644 index 0000000..7e04d82 --- /dev/null +++ b/lib/core/tools/Split-IcingaCheckCommandArgs.psm1 @@ -0,0 +1,9 @@ +function Split-IcingaCheckCommandArgs() +{ + [array]$arguments = @(); + foreach ($arg in $args) { + $arguments += $arg; + } + + return $arguments; +} From 8f836fce18906850012a1efdc8354abb3e81b4ec Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 19 Aug 2019 12:26:23 +0200 Subject: [PATCH 049/259] Added error for missing argument on PerformanceCounters --- .../perfcounter/Show-IcingaPerformanceCounters.psm1 | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/lib/core/perfcounter/Show-IcingaPerformanceCounters.psm1 b/lib/core/perfcounter/Show-IcingaPerformanceCounters.psm1 index f78e479..5080aa6 100644 --- a/lib/core/perfcounter/Show-IcingaPerformanceCounters.psm1 +++ b/lib/core/perfcounter/Show-IcingaPerformanceCounters.psm1 @@ -4,9 +4,17 @@ # function Show-IcingaPerformanceCounters() { - param ([string]$CounterCategory); + param ( + [string]$CounterCategory + ); [hashtable]$counters = @{}; + + if ([string]::IsNullOrEmpty($CounterCategory)) { + $counters.Add('error', 'Please specify a counter category'); + return $counters; + } + try { # At first create our Performance Counter object for the category we specified $Category = New-Object System.Diagnostics.PerformanceCounterCategory($CounterCategory); From 66163245893976a936ec1638ea67d1fa723dcaa8 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 19 Aug 2019 18:07:51 +0200 Subject: [PATCH 050/259] Fixed missing argument of check object for InitCheck --- lib/icinga/plugin/New-IcingaCheckPackage.psm1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 index 8d8428e..5c11fcb 100644 --- a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 +++ b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 @@ -35,6 +35,8 @@ function New-IcingaCheckPackage() } $Check | Add-Member -membertype ScriptMethod -name 'InitCheck' -value { + param($check); + if ($null -eq $check) { return; } From 7bde4fad0b2bbb36a753c8a72d44e1360b81c68b Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 19 Aug 2019 18:08:50 +0200 Subject: [PATCH 051/259] Fixed Plugin Output for multiple check packages --- lib/icinga/plugin/New-IcingaCheckPackage.psm1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 index 5c11fcb..9c8ab0d 100644 --- a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 +++ b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 @@ -72,6 +72,8 @@ function New-IcingaCheckPackage() return; } + $this.compiled = $TRUE; + if ($this.checks.Count -ne 0) { if ($this.opand) { if ($this.CheckAllOk() -eq $FALSE) { @@ -109,12 +111,10 @@ function New-IcingaCheckPackage() $this.exitcode = $IcingaEnums.IcingaExitCode.Ok; } - if ($Verbose -eq $TRUE -Or [int]$this.exitcode -ne $IcingaEnums.IcingaExitCode.Unknown) { + if ($Verbose -eq $TRUE) { $this.PrintOutputMessages(); } - $this.compiled = $TRUE; - return $this.exitcode; } @@ -259,6 +259,7 @@ function New-IcingaCheckPackage() $Check | Add-Member -membertype ScriptMethod -name 'PrintOutputMessages' -value { [bool]$printDetails = $FALSE; [bool]$printAll = $FALSE; + switch ($this.verbose) { 0 { break; }; 1 { break; }; @@ -270,7 +271,6 @@ function New-IcingaCheckPackage() $printAll = $TRUE; break; } - } $this.WritePackageOutputStatus(); From 1b08267f6f78898928ef4d70eba736e221bcfb96 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 19 Aug 2019 18:09:59 +0200 Subject: [PATCH 052/259] Improved organising for Pending Updates provider --- lib/provider/updates/Get-IcingaUpdatesPending.psm1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/provider/updates/Get-IcingaUpdatesPending.psm1 b/lib/provider/updates/Get-IcingaUpdatesPending.psm1 index 2caa728..5917f99 100644 --- a/lib/provider/updates/Get-IcingaUpdatesPending.psm1 +++ b/lib/provider/updates/Get-IcingaUpdatesPending.psm1 @@ -11,6 +11,7 @@ function Get-IcingaUpdatesPending () # Get a list of current pending updates which are not yet installed on the system $Pending = $SearchIndex.Search("IsInstalled=0"); $PendingUpdates.Add('count', $Pending.Updates.Count); + $PendingUpdates.Add('updates', @{ }); foreach ($update in $Pending.Updates) { [hashtable]$PendingUpdateDetails = @{}; @@ -60,7 +61,7 @@ function Get-IcingaUpdatesPending () $name = [string]::Format('{0} ({1})', $name, $PendingUpdateNameCache[$name]); } - $PendingUpdates.Add($name, $PendingUpdateDetails); + $PendingUpdates.updates.Add($name, $PendingUpdateDetails); } } catch { if ($PendingUpdates.ContainsKey('Count') -eq $FALSE) { From 64b017684f295b1b7a87f931c5e035a65dc93575 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 19 Aug 2019 18:14:29 +0200 Subject: [PATCH 053/259] Added Pending Windows Update check --- lib/plugins/Invoke-IcingaCheckUpdates.psm1 | 54 ++++++++++++++++++++++ 1 file changed, 54 insertions(+) create mode 100644 lib/plugins/Invoke-IcingaCheckUpdates.psm1 diff --git a/lib/plugins/Invoke-IcingaCheckUpdates.psm1 b/lib/plugins/Invoke-IcingaCheckUpdates.psm1 new file mode 100644 index 0000000..7fd3cf4 --- /dev/null +++ b/lib/plugins/Invoke-IcingaCheckUpdates.psm1 @@ -0,0 +1,54 @@ +Import-IcingaLib icinga\plugin; +Import-IcingaLib provider\updates; + +function Invoke-IcingaCheckUpdates() +{ + param ( + [array]$UpdateFilter, + $Warning, + $Critical, + [switch]$NoPerfData, + [int]$Verbose + ); + + $PendingUpdates = Get-IcingaUpdatesPending; + + $UpdateCount = New-IcingaCheckPackage -Name 'Pending Update Count' -OperatorAnd; + $UpdateList = New-IcingaCheckPackage -Name 'Update List' -OperatorAnd; + $PendingCount = 0; + + if ($UpdateFilter.Count -ne 0) { + foreach ($Filter in $UpdateFilter) { + foreach ($Update in $PendingUpdates.updates.Keys) { + if ($Update -Like $Filter) { + $PendingCount += 1; + $UpdateList.AddCheck( + (New-IcingaCheck -Name $Update -Value 'pending' -NoPerfData) + ); + } + } + } + if ($PendingCount -eq 0) { + $UpdateList.AddCheck( + (New-IcingaCheck -Name 'No update' -Value 'pending' -NoPerfData) + ); + } + } else { + $PendingCount = $PendingUpdates.count; + foreach ($Update in $PendingUpdates.updates.Keys) { + $UpdateList.AddCheck( + (New-IcingaCheck -Name $Update -Value 'pending' -NoPerfData) + ); + } + } + + $IcingaCheck = New-IcingaCheck -Name 'Pending Update Count' -Value $PendingCount; + $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + $UpdateCount.AddCheck($IcingaCheck); + + $UpdatePackage = New-IcingaCheckPackage -Name 'Updates' -OperatorAnd -Verbose $Verbose -Checks @( + $UpdateCount, $UpdateList + ); + + exit (New-IcingaCheckResult -Name 'Pending Updates' -Check $UpdatePackage -NoPerfData $NoPerfData -Compile); +} From 3ee4f60df3d6ab7b9abe0cf13dde7816b2ebe04c Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 20 Aug 2019 15:09:43 +0200 Subject: [PATCH 054/259] Improved ConvertTo-Seconds Cmdlet --- lib/core/tools/ConvertTo-Seconds.psm1 | 76 ++++++++++++++++++--------- 1 file changed, 52 insertions(+), 24 deletions(-) diff --git a/lib/core/tools/ConvertTo-Seconds.psm1 b/lib/core/tools/ConvertTo-Seconds.psm1 index 85e7f41..68c1e65 100644 --- a/lib/core/tools/ConvertTo-Seconds.psm1 +++ b/lib/core/tools/ConvertTo-Seconds.psm1 @@ -1,34 +1,62 @@ +Import-IcingaLib core\tools; # year month week days hours minutes seconds milliseconds function ConvertTo-Seconds() { param( - [string]$Value, - [char]$Unit, - [switch]$Milliseconds + [string]$Value ); - #100 D - #100 D - $Unit = $Value.Substring($Value.get_Length()-2)[0]; - [single]$ValueSplitted = $Value; - #$Name.Substring($Name.get_Length()-1); - #$Name.Substring(0,$Name.get_Length()-1); - switch ([int][char]$Unit) { -# { 'ms', 'milliseconds' -contains $_ } { $result = ($Value / [math]::Pow(10, 3)); $boolOption = $true; } - { 115 -contains $_ } { $result = $ValueSplitted; $boolOption = $true; } - { 109 -contains $_ } { $result = ($ValueSplitted * 60); $boolOption = $true; } - { 104 -contains $_ } { $result = ($ValueSplitted * 3600); $boolOption = $true; } - { 100 -contains $_ } { $result = ($ValueSplitted * 86400); $boolOption = $true; } - { 87 -contains $_ } { $result = ($ValueSplitted * 604800); $boolOption = $true; } - { 77 -contains $_ } { $result = ($ValueSplitted * (2.5[math]::Pow(10, 6))); $boolOption = $true; } - { 89 -contains $_ } { $result = ($ValueSplitted * (3.10[math]::Pow(10, 7))); $boolOption = $true; } - default { - if (-Not $boolOption) { - Throw 'Invalid input'; - } + [string]$NumberPart = ''; + [string]$UnitPart = ''; + [bool]$Negate = $FALSE; + + foreach($char in $Value.ToCharArray()) { + if ((Test-Numeric $char)) { + $NumberPart += $char; + } else { + if ($char -eq '-') { + $Negate = $TRUE; + } elseif ($char -eq '.' -Or $char -eq ',') { + $NumberPart += '.'; + } else { + $UnitPart += $char; + } } } - + + [single]$ValueSplitted = $NumberPart; + $result = 0; + + if ($Negate) { + $ValueSplitted *= -1; + } + + [string]$errorMsg = ( + [string]::Format('Invalid unit type "{0}" specified for convertion. Allowed units: ms, s, m, h, d, w, M, y', $UnitPart) + ); + + if ($UnitPart -Match 'ms') { + $result = ($ValueSplitted / [math]::Pow(10, 3)); + } else { + if ($UnitPart.Length -gt 1) { + Throw $errorMsg; + } + + switch ([int][char]$UnitPart) { + { 115 -contains $_ } { $result = $ValueSplitted; break; } # s + { 109 -contains $_ } { $result = $ValueSplitted * 60; break; } # m + { 104 -contains $_ } { $result = $ValueSplitted * 3600; break; } # h + { 100 -contains $_ } { $result = $ValueSplitted * 86400; break; } # d + { 119 -contains $_ } { $result = $ValueSplitted * 604800; break; } # w + { 77 -contains $_ } { $result = $ValueSplitted * 2592000; break; } # M + { 121 -contains $_ } { $result = $ValueSplitted * 31536000; break; } # y + default { + Throw $errorMsg; + break; + } + } + } + return $result; -} \ No newline at end of file +} From 5791dbedddcaf4578e30ed12c1dfe0845cedd832 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 20 Aug 2019 16:31:07 +0200 Subject: [PATCH 055/259] Extended Second conversion with Icinga threshold handling --- lib/core/tools/ConvertTo-Seconds.psm1 | 45 +++++++++++++++++++++++++++ 1 file changed, 45 insertions(+) diff --git a/lib/core/tools/ConvertTo-Seconds.psm1 b/lib/core/tools/ConvertTo-Seconds.psm1 index 68c1e65..194f3ed 100644 --- a/lib/core/tools/ConvertTo-Seconds.psm1 +++ b/lib/core/tools/ConvertTo-Seconds.psm1 @@ -7,9 +7,14 @@ function ConvertTo-Seconds() [string]$Value ); + if ([string]::IsNullOrEmpty($Value)) { + return $Value; + } + [string]$NumberPart = ''; [string]$UnitPart = ''; [bool]$Negate = $FALSE; + [bool]$hasUnit = $FALSE; foreach($char in $Value.ToCharArray()) { if ((Test-Numeric $char)) { @@ -21,10 +26,15 @@ function ConvertTo-Seconds() $NumberPart += '.'; } else { $UnitPart += $char; + $hasUnit = $TRUE; } } } + if (-Not $hasUnit) { + return $Value; + } + [single]$ValueSplitted = $NumberPart; $result = 0; @@ -60,3 +70,38 @@ function ConvertTo-Seconds() return $result; } + +function ConvertTo-SecondsFromIcingaThresholds() +{ + param( + [string]$Threshold + ); + + [array]$Content = $Threshold.Split(':'); + [array]$NewContent = @(); + + foreach ($entry in $Content) { + $NewContent += (Get-IcingaThresholdsAsSeconds -Value $entry) + } + + return [string]::Join(':', $NewContent); +} + +function Get-IcingaThresholdsAsSeconds() +{ + param( + [string]$Value + ); + + if ($Value.Contains('~')) { + $Value = $Value.Replace('~', ''); + return [string]::Format('~{0}', (ConvertTo-Seconds $Value)); + } elseif ($Value.Contains('@')) { + $Value = $Value.Replace('@', ''); + return [string]::Format('@{0}', (ConvertTo-Seconds $Value)); + } + + return (ConvertTo-Seconds $Value); +} + +Export-ModuleMember -Function @( 'ConvertTo-Seconds', 'ConvertTo-SecondsFromIcingaThresholds' ); From c6ae93cb7ba14c99436cd20b431ed95bfa3ee61c Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 20 Aug 2019 17:01:20 +0200 Subject: [PATCH 056/259] Added function to convert seconds to runtime --- lib/core/tools/ConvertFrom-TimeSpan.psm1 | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 lib/core/tools/ConvertFrom-TimeSpan.psm1 diff --git a/lib/core/tools/ConvertFrom-TimeSpan.psm1 b/lib/core/tools/ConvertFrom-TimeSpan.psm1 new file mode 100644 index 0000000..0369ece --- /dev/null +++ b/lib/core/tools/ConvertFrom-TimeSpan.psm1 @@ -0,0 +1,18 @@ +Import-IcingaLib core\tools; + +function ConvertFrom-TimeSpan() +{ + param( + $Seconds + ); + + $TimeSpan = [TimeSpan]::FromSeconds($Seconds); + + return [string]::Format( + 'Days: {0} Hours: {1} Minutes: {2} Seconds: {3}', + $TimeSpan.Days, + $TimeSpan.Hours, + $TimeSpan.Minutes, + $TimeSpan.Seconds + ); +} From 232a3732390661fddd19301abc75bd0221d1e442 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 20 Aug 2019 17:02:58 +0200 Subject: [PATCH 057/259] Added check for Windows Uptime --- lib/plugins/Invoke-IcingaCheckUptime.psm1 | 27 +++++++++++++++++++++++ 1 file changed, 27 insertions(+) create mode 100644 lib/plugins/Invoke-IcingaCheckUptime.psm1 diff --git a/lib/plugins/Invoke-IcingaCheckUptime.psm1 b/lib/plugins/Invoke-IcingaCheckUptime.psm1 new file mode 100644 index 0000000..78f685e --- /dev/null +++ b/lib/plugins/Invoke-IcingaCheckUptime.psm1 @@ -0,0 +1,27 @@ +Import-IcingaLib icinga\plugin; +Import-IcingaLib provider\windows; +Import-IcingaLib core\tools; + +function Invoke-IcingaCheckUptime() +{ + param( + $Warning, + $Critical, + [switch]$NoPerfData, + [int]$Verbose + ); + + $WindowsData = Get-IcingaWindows; + $Name = ([string]::Format('Windows Uptime: {0}', (ConvertFrom-TimeSpan -Seconds $WindowsData.windows.metadata.uptime.value))); + + $IcingaCheck = New-IcingaCheck -Name 'Windows Uptime' -Value $WindowsData.windows.metadata.uptime.value -Unit 's'; + $IcingaCheck.WarnOutOfRange( + (ConvertTo-SecondsFromIcingaThresholds -Threshold $Warning) + ).CritOutOfRange( + (ConvertTo-SecondsFromIcingaThresholds -Threshold $Critical) + ) | Out-Null; + + $CheckPackage = New-IcingaCheckPackage -Name $Name -OperatorAnd -Checks $IcingaCheck -Verbose $Verbose; + + exit (New-IcingaCheckresult -Check $CheckPackage -NoPerfData $NoPerfData -Compile); +} From df1763bcceeb495b771d44564973085056379ac0 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 22 Aug 2019 10:43:00 +0200 Subject: [PATCH 058/259] Changed Plugin Text Status to allow colored Icinga Web 2 output --- lib/icinga/enums/Icinga_IcingaEnums.psm1 | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/icinga/enums/Icinga_IcingaEnums.psm1 b/lib/icinga/enums/Icinga_IcingaEnums.psm1 index 098cb80..e0267ae 100644 --- a/lib/icinga/enums/Icinga_IcingaEnums.psm1 +++ b/lib/icinga/enums/Icinga_IcingaEnums.psm1 @@ -12,10 +12,10 @@ }; [hashtable]$IcingaExitCodeText = @{ - 0 = 'Ok'; - 1 = 'Warning'; - 2 = 'Critical'; - 3 = 'Unknown'; + 0 = '[OK]'; + 1 = '[WARNING]'; + 2 = '[CRITICAL]'; + 3 = '[UNKNOWN]'; }; [hashtable]$IcingaMeasurementUnits = @{ From 74d48a2096714330e8eba64d79361d3f803312ae Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 9 Sep 2019 10:12:02 +0200 Subject: [PATCH 059/259] Added basic documentation for Check-Commands --- doc/02-Installation.md | 7 ++-- doc/12-Icinga2AgentExample.md | 71 +++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+), 3 deletions(-) create mode 100644 doc/12-Icinga2AgentExample.md diff --git a/doc/02-Installation.md b/doc/02-Installation.md index 020e33f..77410b2 100644 --- a/doc/02-Installation.md +++ b/doc/02-Installation.md @@ -25,7 +25,7 @@ To validate if the module is installed properly, you can start a new PowerShell ```powershell Get-Module -ListAvailable -Name icinga-module-windows -``` +``` If you receive an output stating that the module is installed, you are fine to continue. @@ -43,7 +43,7 @@ This will create the base configuration of the module including the setup of dir Once completed successfully, you are ready to get started with using it. This will include * Using it localy with scripts -* Integrate it with the Icinga 2 Agent +* Integration into for the Icinga 2 Agent * Use it as Remote Execution target * Integrate it into Icinga Web 2 @@ -61,5 +61,6 @@ Of course if you wish to actively send data to Icinga Web 2 for example, you can For additional setup possibilities, please take a look on the following pages: +* [Use the module as Icinga Plugin Framework](12-Icinga2AgentExample.md) * [Install the module as Windows Service](10-InstallService.md) -* [Integration into Icinga Web 2](11-IcingaWeb2Integration.md) \ No newline at end of file +* [Integration into Icinga Web 2](11-IcingaWeb2Integration.md) diff --git a/doc/12-Icinga2AgentExample.md b/doc/12-Icinga2AgentExample.md new file mode 100644 index 0000000..a184f2e --- /dev/null +++ b/doc/12-Icinga2AgentExample.md @@ -0,0 +1,71 @@ +Icinga Agent integration as Framework Modules +===================================== + +This PowerShell modules provides a wide range of Check-Plugins for Icinga 2 to fetch information from a Windows system. Once the module is installed, the Plugins are ready to use. + +Requirements +-------------- + +To properly work we recommend using the Icinga 2 Agent. + +Usage of the Check-Commands +-------------- + +Each call from the Icinga 2 Agent requires a short initialisation of the module. This can either be done by using the `Import-Module` Cmdlet in case the module is not autoloaded, or by calling + +```powershell +Use-Icinga; +``` + +before each function call. An example on the PowerShell would be this: + +``` +Use-Icinga; Invoke-IcingaCheckCPU; +``` + +This will initialise the module and execute the Check-Command afterwards. + +Check-Command definition for Icinga +-------------- + +A example Check-Command for Icinga could look like this: + +``` +object CheckCommand "Windows Check CPU" { + import "plugin-check-command" + command = [ + "C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe" + ] + timeout = 3m + arguments += { + "-C" = { + order = 0 + value = "Use-Icinga; exit Invoke-IcingaCheckCPU" + } + "-Critical" = { + order = 2 + value = "$PowerShell_Critical$" + } + "-NoPerfData" = { + order = 6 + set_if = "$PowerShell_NoPerfData$" + } + "-Verbose" = { + order = 4 + value = "$PowerShell_Verbose$" + } + "-Warning" = { + order = 1 + value = "$PowerShell_Warning$" + } + } + vars.PowerShell_Critical = "$$null" + vars.PowerShell_NoPerfData = "0" + vars.PowerShell_Verbose = "0" + vars.PowerShell_Warning = "$$null" +} +``` + +This will call the PowerShell, execute the provided initialisation function `Use-Icinga` and afterwards execute the Check-Plugin with the provided arguments. + +Unlike other PowerShell integrations, it will automaticly exit with the proper exit code - no special handling is required here. From b352a5b5443615288b844c17af6eddec75483345 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 10 Sep 2019 09:37:27 +0200 Subject: [PATCH 060/259] Fixed code type for documentation --- doc/12-Icinga2AgentExample.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/12-Icinga2AgentExample.md b/doc/12-Icinga2AgentExample.md index a184f2e..0a463d4 100644 --- a/doc/12-Icinga2AgentExample.md +++ b/doc/12-Icinga2AgentExample.md @@ -19,7 +19,7 @@ Use-Icinga; before each function call. An example on the PowerShell would be this: -``` +```powershell Use-Icinga; Invoke-IcingaCheckCPU; ``` @@ -30,7 +30,7 @@ Check-Command definition for Icinga A example Check-Command for Icinga could look like this: -``` +```icinga object CheckCommand "Windows Check CPU" { import "plugin-check-command" command = [ From 2f874fa4d2bd9a80ef4610f46c5f206a3f6b5385 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 10 Sep 2019 09:38:35 +0200 Subject: [PATCH 061/259] Added Tool-Function to get Sha1 from String elements --- lib/core/tools/Get-StringSha1.psm1 | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) create mode 100644 lib/core/tools/Get-StringSha1.psm1 diff --git a/lib/core/tools/Get-StringSha1.psm1 b/lib/core/tools/Get-StringSha1.psm1 new file mode 100644 index 0000000..cbaad28 --- /dev/null +++ b/lib/core/tools/Get-StringSha1.psm1 @@ -0,0 +1,17 @@ +function Get-StringSha1() +{ + param( + [string]$Content + ); + + $CryptoAlgorithm = New-Object System.Security.Cryptography.SHA1CryptoServiceProvider; + $ContentHash = [System.Text.Encoding]::UTF8.GetBytes($Content); + $ContentBytes = $CryptoAlgorithm.ComputeHash($ContentHash); + $OutputHash = ''; + + foreach($byte in $ContentBytes) { + $OutputHash += $byte.ToString() + } + + return $OutputHash; +} From df1911c3c8d36a7d33aa37a472b6552e37277fee Mon Sep 17 00:00:00 2001 From: Crited Date: Wed, 11 Sep 2019 15:08:30 +0200 Subject: [PATCH 062/259] Pulled from testing, build basic IcingaCheckCommandBasket-Function --- .../Invoke-IcingaCheckCommandBasket.psm1 | 311 ++++++++++++++++++ 1 file changed, 311 insertions(+) create mode 100644 lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 diff --git a/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 b/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 new file mode 100644 index 0000000..7c3121e --- /dev/null +++ b/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 @@ -0,0 +1,311 @@ +function Invoke-IcingaCheckCommandBasket() +{ + param( + $CheckName + ); + + [hashtable]$AllChecks = @{}; + + if ($NULL -eq $CheckName) { + $CheckName = (Get-Command Invoke-IcingaCheck*).Name + } + + foreach ($check in $CheckName) { + + [hashtable]$Basket = @{}; + + [int]$FieldID = 0; + + $Data = (Get-Help $check) + + $Basket.Add( + 'Command', @{ + $Data.Syntax.syntaxItem.Name = @{ + 'arguments'= @{ + '-C' = @{ + 'value' = [string]::Format('Use-Icinga; {0}', $Data.Syntax.syntaxItem.Name); + 'order' = '0'; + } + } + 'command' = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"; #Gehört noch geändert + 'disabled' = $FALSE; + 'fields' = @{}; + 'imports' = @(); + 'is_string' = $NULL; + 'methods_excute' = 'PluginCheck'; + 'object_name' = $Data.Syntax.syntaxItem.Name; + 'object_type' = 'object'; + 'timeout' = '180'; + 'vars' = @{}; + 'zone' = $NULL; + } + } + ) + + $Basket.Add('Datafield', @{}); + $Basket.Add('DataList', @{}); + + foreach ($parameter in $Data.Syntax.syntaxItem.parameter) { + if ($parameter.name -ne 'core') { + # Is Numeric Check on position to determine the order value + If (Test-Numeric($parameter.position) -eq $TRUE) { + [string]$Order = [int]$parameter.position + 1 + } else { + [string]$Order = 99 + } + + $IcingaCustomVariable = [string]::Format('$PowerShell_{0}$', $parameter.Name); + + # Conditional whether type of parameter is switch + if ($parameter.type.name -eq 'switch') { + $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( + [string]::Format('-{0}', $parameter.Name), @{ + 'set_if' = $IcingaCustomVariable; + 'set_if_format' = 'string'; + 'order' = $Order; + } + ); + $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add( + $parameter.Name, "0" + ); + # Condotional whether type of parameter is array + } elseif ($parameter.type.name -eq 'array') { + $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( + [string]::Format('-{0}', $parameter.Name), @{ + 'value' = [string]::Format('(Split-IcingaCheckCommandArgs {0})', $IcingaCustomVariable); + 'order' = $Order; + } + ); + } else { + # Default to Object + $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( + [string]::Format('-{0}', $parameter.Name), @{ + 'value' = $IcingaCustomVariable; + 'order' = $Order; + } + ); + if ($parameter.name -ne 'Verbose') { + $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add($parameter.Name, '$$null'); + } else { + $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add($parameter.Name, "0"); + } + } + # Fields + # Required? + if ($parameter.required -eq $TRUE) { + $Required = 'y'; + } else { + $Required = 'n'; + } + $Basket.Command[$Data.Syntax.syntaxItem.Name].fields.Add( + [string]$FieldID, @{ + 'datafield_id' = [int]$FieldID; + 'is_required' = $Required; + 'var_filter' = $NULL; + } + ); + + $IcingaCustomVariable = [string]::Format('PowerShell_{0}', $parameter.Name); + + $DataListName = [string]::Format('PowerShell {0}', $parameter.Name) + + if ($parameter.type.name -eq 'switch') { + $IcingaDataType='Datalist'; + $Basket.DataList.Add( + $DataListName, @{ + 'list_name' = $DataListName; + 'owner' = $env:username; + 'originalId' = '50'; #Gehört noch geändert + 'entries' = @{}; + } + ); + + } elseif ($parameter.type.name -eq 'Object') { + if ($parameter.Name -eq 'Verbose') { + $IcingaDataType='Datalist' + } + $IcingaDataType='String'; + } elseif ($parameter.type.name -eq 'Array') { + $IcingaDataType='Array'; + } else { + $IcingaDataType='String'; + } + $IcingaDataType = [string]::Format('Icinga\Module\Director\DataType\DataType{0}', $IcingaDataType) + + $Basket.Datafield.Add( + [string]$FieldID, @{ + 'varname' = $IcingaCustomVariable; + 'caption' = $parameter.Name; + 'description' = $NULL; + 'datatype' = $IcingaDataType; + 'format' = $NULL; + 'originalId' = [string]$FieldID; + } + ); + + if ($parameter.type.name -eq 'switch' -or $parameter.Name -eq 'Verbose') { + $Basket.Datafield[[string]$FieldID].Add( + 'settings', @{ + 'behavior' = 'strict'; + 'datatype' = 'string'; + 'datalist' = $DataListName; + } + ); + } elseif ($parameter.type.name -eq 'Object') { + $Basket.Datafield[[string]$FieldID].Add( + 'settings', @{ + 'visbility' = 'visible'; + } + ); + } else { + $Basket.Datafield[[string]$FieldID].Add( + 'settings', @{} + ); + } + [int]$FieldID = $FieldID + 1; + } +} + + # Check whether or not noperfdata and verbose is set and add it if necessary + if ($Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.ContainsKey('-Verbose') -eq $FALSE) { + [int]$FieldID = $FieldID + 1; + $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( + '-Verbose', @{ + 'value' = '$PowerShell_Verbose$'; + 'order' = 'o'; + } + ); + $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add( + 'PowerShell_Verbose', "0" + ); + $Basket.Datafield.Add( + [string]$FieldID, @{ + 'varname' = 'PowerShell_Verbose'; + 'caption' = 'Verbose'; + 'description' = $NULL; + 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; + 'format' = $NULL; + 'originalId' = [string]$FieldID; + 'settings' = @{ + 'behavior' = 'strict'; + 'data_type' = 'string'; + 'datalist' = 'PowerShell Verbose' + } + } + ); + } + + + if ($Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.ContainsKey('-NoPerfData') -eq $FALSE) { + [int]$FieldID = $FieldID + 1; + $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( + '-NoPerfData', @{ + 'set_if' = '$PowerShell_NoPerfData$'; + 'set_if_format' = 'string'; + 'order' = '99'; + } + ); + $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add( + 'PowerShell_NoPerfData', "0" + ); + $Basket.Datafield.Add( + [string]$FieldID, @{ + 'varname' = 'PowerShell_NoPerfData'; + 'caption' = 'Perf Data'; + 'description' = $NULL; + 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; + 'format' = $NULL; + 'originalId' = [string]$FieldID; + 'settings' = @{ + 'behavior' = 'strict'; + 'data_type' = 'string'; + 'datalist' = 'PowerShell NoPerfData' + } + } + ); + } + # DataList Entries (Default for NoPerfData) + if ($Basket.DataList.ContainsKey('PowerShell NoPerfData') -eq $FALSE) { + $Basket.DataList.Add( + 'PowerShell NoPerfData', @{ + 'list_name' = 'PowerShell NoPerfData'; + 'owner' = $env:username; + 'originalId' = '1'; #Gehört noch geändert + 'entries' = @{}; + } + ); + } + $Basket.DataList["PowerShell NoPerfData"].entries.Add( + '0', @{ + 'entry_name' = '0'; + 'entry_value:' = "yes"; + 'format' = 'string'; + 'allowed_roles' = $NULL; + } + ); + $Basket.DataList["PowerShell NoPerfData"].entries.Add( + '1', @{ + 'entry_name' = '1'; + 'entry_value:' = "no"; + 'format' = 'string'; + 'allowed_roles' = $NULL; + } + ); + + # DataList Entries (Default for Verbose) + if ($Basket.DataList.ContainsKey('PowerShell Verbose') -eq $FALSE) { + $Basket.DataList.Add( + 'PowerShell Verbose', @{ + 'list_name' = 'PowerShell Verbose'; + 'owner' = $env:username; + 'originalId' = '50'; #Gehört noch geändert + 'entries' = @{}; + } + ); + } + $Basket.DataList["PowerShell Verbose"].entries.Add( + '0', @{ + 'entry_name' = '0'; + 'entry_value:' = "Show Default"; + 'format' = 'string'; + 'allowed_roles' = $NULL; + } + ); + $Basket.DataList["PowerShell Verbose"].entries.Add( + '1', @{ + 'entry_name' = '1'; + 'entry_value:' = "Show Operator"; + 'format' = 'string'; + 'allowed_roles' = $NULL; + } + ); + $Basket.DataList["PowerShell Verbose"].entries.Add( + '2', @{ + 'entry_name' = '2'; + 'entry_value:' = "Show Problems"; + 'format' = 'string'; + 'allowed_roles' = $NULL; + } + ) + $Basket.DataList["PowerShell Verbose"].entries.Add( + '3', @{ + 'entry_name' = '3'; + 'entry_value:' = "Show All"; + 'format' = 'string'; + 'allowed_roles' = $NULL; + } + ); + $AllChecks.Add($check, $Basket); + } + +Write-Host $CheckName; +Write-Host $CheckName.Count; + + if ([string]$CheckName.Count -eq '1') { + $output=ConvertTo-Json -D 100 $Basket > Check.json; + } else { + $output=ConvertTo-Json -D 100 $AllChecks > Check.json; + } + + return $output; +} \ No newline at end of file From e7950c1616e2cba547a440d876e8136303906506 Mon Sep 17 00:00:00 2001 From: Crited Date: Wed, 11 Sep 2019 16:07:52 +0200 Subject: [PATCH 063/259] Update CheckBasket --- .../Invoke-IcingaCheckCommandBasket.psm1 | 207 ++++++++++-------- 1 file changed, 114 insertions(+), 93 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 b/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 index 7c3121e..4398190 100644 --- a/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 +++ b/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 @@ -10,17 +10,96 @@ function Invoke-IcingaCheckCommandBasket() $CheckName = (Get-Command Invoke-IcingaCheck*).Name } + [int]$FieldID = 0; + [hashtable]$Basket = @{}; + $Basket.Add('Datafield', @{}); + $Basket.Add('DataList', @{}); + $Basket.Add('Command', @{}); + + # DataList Entries (Default for NoPerfData) + if ($Basket.DataList.ContainsKey('PowerShell NoPerfData') -eq $FALSE) { + $Basket.DataList.Add( + 'PowerShell NoPerfData', @{ + 'list_name' = 'PowerShell NoPerfData'; + 'owner' = $env:username; + 'originalId' = '1'; #Gehört noch geändert + 'entries' = @{}; + } + ); + } + + $Basket.DataList["PowerShell NoPerfData"].entries.Add( + '0', @{ + 'entry_name' = '0'; + 'entry_value:' = "yes"; + 'format' = 'string'; + 'allowed_roles' = $NULL; + } + ); + $Basket.DataList["PowerShell NoPerfData"].entries.Add( + '1', @{ + 'entry_name' = '1'; + 'entry_value:' = "no"; + 'format' = 'string'; + 'allowed_roles' = $NULL; + } + ); + + # DataList Entries (Default for Verbose) + if ($Basket.DataList.ContainsKey('PowerShell Verbose') -eq $FALSE) { + $Basket.DataList.Add( + 'PowerShell Verbose', @{ + 'list_name' = 'PowerShell Verbose'; + 'owner' = $env:username; + 'originalId' = '50'; #Gehört noch geändert + 'entries' = @{}; + } + ); + } + $Basket.DataList["PowerShell Verbose"].entries.Add( + '0', @{ + 'entry_name' = '0'; + 'entry_value:' = "Show Default"; + 'format' = 'string'; + 'allowed_roles' = $NULL; + } + ); + $Basket.DataList["PowerShell Verbose"].entries.Add( + '1', @{ + 'entry_name' = '1'; + 'entry_value:' = "Show Operator"; + 'format' = 'string'; + 'allowed_roles' = $NULL; + } + ); + $Basket.DataList["PowerShell Verbose"].entries.Add( + '2', @{ + 'entry_name' = '2'; + 'entry_value:' = "Show Problems"; + 'format' = 'string'; + 'allowed_roles' = $NULL; + } + ) + $Basket.DataList["PowerShell Verbose"].entries.Add( + '3', @{ + 'entry_name' = '3'; + 'entry_value:' = "Show All"; + 'format' = 'string'; + 'allowed_roles' = $NULL; + } + ); + + foreach ($check in $CheckName) { - [hashtable]$Basket = @{}; +# [hashtable]$Basket = @{}; - [int]$FieldID = 0; +# [int]$FieldID = 0; $Data = (Get-Help $check) - $Basket.Add( - 'Command', @{ - $Data.Syntax.syntaxItem.Name = @{ + $Basket.Command.Add( + $Data.Syntax.syntaxItem.Name, @{ 'arguments'= @{ '-C' = @{ 'value' = [string]::Format('Use-Icinga; {0}', $Data.Syntax.syntaxItem.Name); @@ -39,11 +118,10 @@ function Invoke-IcingaCheckCommandBasket() 'vars' = @{}; 'zone' = $NULL; } - } ) - $Basket.Add('Datafield', @{}); - $Basket.Add('DataList', @{}); +# $Basket.Add('Datafield', @{}); +# $Basket.Add('DataList', @{}); foreach ($parameter in $Data.Syntax.syntaxItem.parameter) { if ($parameter.name -ne 'core') { @@ -54,7 +132,7 @@ function Invoke-IcingaCheckCommandBasket() [string]$Order = 99 } - $IcingaCustomVariable = [string]::Format('$PowerShell_{0}$', $parameter.Name); + $IcingaCustomVariable = [string]::Format('$PowerShell_{0}_{1}$', $parameter.type.name, $parameter.Name); # Conditional whether type of parameter is switch if ($parameter.type.name -eq 'switch') { @@ -105,12 +183,13 @@ function Invoke-IcingaCheckCommandBasket() } ); - $IcingaCustomVariable = [string]::Format('PowerShell_{0}', $parameter.Name); + $IcingaCustomVariable = [string]::Format('PowerShell_{0}_{1}', $parameter.type.name, $parameter.Name); $DataListName = [string]::Format('PowerShell {0}', $parameter.Name) if ($parameter.type.name -eq 'switch') { $IcingaDataType='Datalist'; + if ($Basket.DataList.ContainsKey($DataListName) -eq $FALSE) { $Basket.DataList.Add( $DataListName, @{ 'list_name' = $DataListName; @@ -119,7 +198,7 @@ function Invoke-IcingaCheckCommandBasket() 'entries' = @{}; } ); - + } } elseif ($parameter.type.name -eq 'Object') { if ($parameter.Name -eq 'Verbose') { $IcingaDataType='Datalist' @@ -132,6 +211,11 @@ function Invoke-IcingaCheckCommandBasket() } $IcingaDataType = [string]::Format('Icinga\Module\Director\DataType\DataType{0}', $IcingaDataType) + if ($Basket.Datafield.Values.varname -eq $IcingaCustomVariable) + { + } + else { + [int]$FieldID = $FieldID + 1; $Basket.Datafield.Add( [string]$FieldID, @{ 'varname' = $IcingaCustomVariable; @@ -143,6 +227,7 @@ function Invoke-IcingaCheckCommandBasket() } ); + if ($parameter.type.name -eq 'switch' -or $parameter.Name -eq 'Verbose') { $Basket.Datafield[[string]$FieldID].Add( 'settings', @{ @@ -162,6 +247,7 @@ function Invoke-IcingaCheckCommandBasket() 'settings', @{} ); } + } [int]$FieldID = $FieldID + 1; } } @@ -171,16 +257,18 @@ function Invoke-IcingaCheckCommandBasket() [int]$FieldID = $FieldID + 1; $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( '-Verbose', @{ - 'value' = '$PowerShell_Verbose$'; - 'order' = 'o'; + 'value' = '$PowerShell_Object_Verbose$'; + 'order' = '99'; } ); $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add( - 'PowerShell_Verbose', "0" + 'PowerShell_Object_Verbose', "0" ); + if ($Basket.Datafield.Values.varname -eq $IcingaCustomVariable) { + } else { $Basket.Datafield.Add( [string]$FieldID, @{ - 'varname' = 'PowerShell_Verbose'; + 'varname' = 'PowerShell_Object_Verbose'; 'caption' = 'Verbose'; 'description' = $NULL; 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; @@ -193,6 +281,7 @@ function Invoke-IcingaCheckCommandBasket() } } ); + } } @@ -200,17 +289,19 @@ function Invoke-IcingaCheckCommandBasket() [int]$FieldID = $FieldID + 1; $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( '-NoPerfData', @{ - 'set_if' = '$PowerShell_NoPerfData$'; + 'set_if' = '$PowerShell_switch_NoPerfData$'; 'set_if_format' = 'string'; 'order' = '99'; } ); $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add( - 'PowerShell_NoPerfData', "0" + 'PowerShell_switch_NoPerfData', "0" ); + if ($Basket.Datafield.Values.varname -eq $IcingaCustomVariable) { + } else { $Basket.Datafield.Add( [string]$FieldID, @{ - 'varname' = 'PowerShell_NoPerfData'; + 'varname' = 'PowerShell_switch_NoPerfData'; 'caption' = 'Perf Data'; 'description' = $NULL; 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; @@ -223,89 +314,19 @@ function Invoke-IcingaCheckCommandBasket() } } ); - } - # DataList Entries (Default for NoPerfData) - if ($Basket.DataList.ContainsKey('PowerShell NoPerfData') -eq $FALSE) { - $Basket.DataList.Add( - 'PowerShell NoPerfData', @{ - 'list_name' = 'PowerShell NoPerfData'; - 'owner' = $env:username; - 'originalId' = '1'; #Gehört noch geändert - 'entries' = @{}; - } - ); - } - $Basket.DataList["PowerShell NoPerfData"].entries.Add( - '0', @{ - 'entry_name' = '0'; - 'entry_value:' = "yes"; - 'format' = 'string'; - 'allowed_roles' = $NULL; - } - ); - $Basket.DataList["PowerShell NoPerfData"].entries.Add( - '1', @{ - 'entry_name' = '1'; - 'entry_value:' = "no"; - 'format' = 'string'; - 'allowed_roles' = $NULL; - } - ); - - # DataList Entries (Default for Verbose) - if ($Basket.DataList.ContainsKey('PowerShell Verbose') -eq $FALSE) { - $Basket.DataList.Add( - 'PowerShell Verbose', @{ - 'list_name' = 'PowerShell Verbose'; - 'owner' = $env:username; - 'originalId' = '50'; #Gehört noch geändert - 'entries' = @{}; - } - ); } - $Basket.DataList["PowerShell Verbose"].entries.Add( - '0', @{ - 'entry_name' = '0'; - 'entry_value:' = "Show Default"; - 'format' = 'string'; - 'allowed_roles' = $NULL; - } - ); - $Basket.DataList["PowerShell Verbose"].entries.Add( - '1', @{ - 'entry_name' = '1'; - 'entry_value:' = "Show Operator"; - 'format' = 'string'; - 'allowed_roles' = $NULL; - } - ); - $Basket.DataList["PowerShell Verbose"].entries.Add( - '2', @{ - 'entry_name' = '2'; - 'entry_value:' = "Show Problems"; - 'format' = 'string'; - 'allowed_roles' = $NULL; - } - ) - $Basket.DataList["PowerShell Verbose"].entries.Add( - '3', @{ - 'entry_name' = '3'; - 'entry_value:' = "Show All"; - 'format' = 'string'; - 'allowed_roles' = $NULL; - } - ); + } $AllChecks.Add($check, $Basket); } Write-Host $CheckName; Write-Host $CheckName.Count; - if ([string]$CheckName.Count -eq '1') { +# if ([string]$CheckName.Count -eq '1') { $output=ConvertTo-Json -D 100 $Basket > Check.json; - } else { - $output=ConvertTo-Json -D 100 $AllChecks > Check.json; - } +# } else { +# $output=ConvertTo-Json -D 100 $AllChecks > Check.json; +# } return $output; } \ No newline at end of file From e137a4dbcf200e7d25bd34acda8ca6dbc786b87a Mon Sep 17 00:00:00 2001 From: Crited Date: Thu, 12 Sep 2019 09:10:55 +0200 Subject: [PATCH 064/259] Changed DataLists to Array; Added Synopsis, Description, Examples, Parameter, Inputs, Outputs, Link in Comment-Based-Help; Fixed 'self-export'; Changed codestyling; Deleted unnecessary code; Deleted unnecessary comments and added new one as deemed necessary --- .../Invoke-IcingaCheckCommandBasket.psm1 | 368 ++++++++++-------- 1 file changed, 211 insertions(+), 157 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 b/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 index 4398190..744b1a2 100644 --- a/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 +++ b/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 @@ -1,112 +1,155 @@ +<# +.SYNOPSIS + Exports command as JSON for icinga director + +.DESCRIPTION + Invoke-IcingaCheckCommandBasket returns a JSON-file of one or all 'Invoke-IcingaCheck'-Commands, which can be imported via Icinga-Director + When no single command is specified all commands will be exported, and vice versa. + + More Information on https://github.com/LordHepipud/icinga-module-windows + +.EXAMPLE + PS>Invoke-IcingaCheckCommandBasket + The following commands have been exported: + - 'Invoke-IcingaCheckBiosSerial' + - 'Invoke-IcingaCheckCommandBasket' + - 'Invoke-IcingaCheckCPU' + - 'Invoke-IcingaCheckProcessCount' + - 'Invoke-IcingaCheckService' + - 'Invoke-IcingaCheckUpdates' + - 'Invoke-IcingaCheckUptime' + - 'Invoke-IcingaCheckUsedPartitionSpace' + - 'Invoke-IcingaCheckUsers' + JSON export created to 'C:\Program Files\WindowsPowerShell\Modules\icinga-module-windows\Checks.json' + +.EXAMPLE + PS>Invoke-IcingaCheckCommandBasket Invoke-IcingaCheckCPU + The following commands have been exported: + - 'Invoke-IcingaCheckCPU' + JSON export created to 'C:\Program Files\WindowsPowerShell\Modules\icinga-module-windows\Invoke-IcingaCheckCPU.json' +.PARAMETER CheckName + Used to specify a single command which should be exported. + Has to be a single string. + .INPUTS + System.String + + .OUTPUTS + System.String + System.Object + + .LINK + https://github.com/LordHepipud/icinga-module-windows + + .NOTES +#> + function Invoke-IcingaCheckCommandBasket() { param( $CheckName ); - [hashtable]$AllChecks = @{}; - + # Check whether all Checks will be exported or just the single one specified if ($NULL -eq $CheckName) { $CheckName = (Get-Command Invoke-IcingaCheck*).Name } + # Variable definition and initialization [int]$FieldID = 0; [hashtable]$Basket = @{}; + + # Define basic hashtable structure by adding fields: "Datafield", "DataList", "Command" $Basket.Add('Datafield', @{}); $Basket.Add('DataList', @{}); $Basket.Add('Command', @{}); - # DataList Entries (Default for NoPerfData) - if ($Basket.DataList.ContainsKey('PowerShell NoPerfData') -eq $FALSE) { - $Basket.DataList.Add( - 'PowerShell NoPerfData', @{ - 'list_name' = 'PowerShell NoPerfData'; - 'owner' = $env:username; - 'originalId' = '1'; #Gehört noch geändert - 'entries' = @{}; - } - ); - } - $Basket.DataList["PowerShell NoPerfData"].entries.Add( - '0', @{ - 'entry_name' = '0'; - 'entry_value:' = "yes"; - 'format' = 'string'; - 'allowed_roles' = $NULL; - } - ); - $Basket.DataList["PowerShell NoPerfData"].entries.Add( - '1', @{ - 'entry_name' = '1'; - 'entry_value:' = "no"; - 'format' = 'string'; - 'allowed_roles' = $NULL; - } - ); + # "NoPerfData" gets added to all Checks build and exported no matter what, so we add it from the start + if ($Basket.DataList.ContainsKey('PowerShell NoPerfData') -eq $FALSE) { - # DataList Entries (Default for Verbose) - if ($Basket.DataList.ContainsKey('PowerShell Verbose') -eq $FALSE) { - $Basket.DataList.Add( - 'PowerShell Verbose', @{ - 'list_name' = 'PowerShell Verbose'; - 'owner' = $env:username; - 'originalId' = '50'; #Gehört noch geändert - 'entries' = @{}; - } + # DataList Content for NoPerfData + $Basket.DataList.Add( + 'PowerShell NoPerfData', @{ + 'list_name' = 'PowerShell NoPerfData'; + 'owner' = $env:username; + 'originalId' = '1'; #Gehört noch geändert + 'entries' = @( + @{ + 'entry_name' = '0'; + 'entry_value:' = "yes"; + 'format' = 'string'; + 'allowed_roles' = $NULL; + }, + @{ + 'entry_name' = '1'; + 'entry_value:' = "no"; + 'format' = 'string'; + 'allowed_roles' = $NULL; + } ); } - $Basket.DataList["PowerShell Verbose"].entries.Add( - '0', @{ + ); + } + # "Verbose" gets added to all Checks build and exported no matter what, so we add it from the start + if ($Basket.DataList.ContainsKey('PowerShell Verbose') -eq $FALSE) { + $Basket.DataList.Add( + 'PowerShell Verbose', @{ + 'list_name' = 'PowerShell Verbose'; + 'owner' = $env:username; + 'originalId' = '50'; + 'entries' = @( + @{ 'entry_name' = '0'; 'entry_value:' = "Show Default"; 'format' = 'string'; 'allowed_roles' = $NULL; - } - ); - $Basket.DataList["PowerShell Verbose"].entries.Add( - '1', @{ + }, + @{ 'entry_name' = '1'; 'entry_value:' = "Show Operator"; 'format' = 'string'; 'allowed_roles' = $NULL; - } - ); - $Basket.DataList["PowerShell Verbose"].entries.Add( - '2', @{ + }, + @{ 'entry_name' = '2'; 'entry_value:' = "Show Problems"; 'format' = 'string'; 'allowed_roles' = $NULL; - } - ) - $Basket.DataList["PowerShell Verbose"].entries.Add( - '3', @{ + }, + @{ 'entry_name' = '3'; 'entry_value:' = "Show All"; 'format' = 'string'; 'allowed_roles' = $NULL; } ); - + } + ); + } + <# + Loop through either: + $CheckName = (Get-Command Invoke-IcingaCheck*).Name + or one of $CheckName = 'Invoke-IcingaCheckCommand' + #> foreach ($check in $CheckName) { + if ($check -eq 'Invoke-IcingaCheckCommandBasket') { + } else { -# [hashtable]$Basket = @{}; - -# [int]$FieldID = 0; - + # Get Necessary Syntax-Information and more through cmdlet "Get-Help" $Data = (Get-Help $check) + # Add Command Structure $Basket.Command.Add( $Data.Syntax.syntaxItem.Name, @{ 'arguments'= @{ + # Gets set for every command as Default '-C' = @{ 'value' = [string]::Format('Use-Icinga; {0}', $Data.Syntax.syntaxItem.Name); 'order' = '0'; } } - 'command' = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"; #Gehört noch geändert + 'command' = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"; 'disabled' = $FALSE; 'fields' = @{}; 'imports' = @(); @@ -120,21 +163,21 @@ function Invoke-IcingaCheckCommandBasket() } ) -# $Basket.Add('Datafield', @{}); -# $Basket.Add('DataList', @{}); - + # Loop through Parameter of a given command foreach ($parameter in $Data.Syntax.syntaxItem.parameter) { + # Filter for Parameter 'core', because its set by default if ($parameter.name -ne 'core') { - # Is Numeric Check on position to determine the order value - If (Test-Numeric($parameter.position) -eq $TRUE) { - [string]$Order = [int]$parameter.position + 1 - } else { - [string]$Order = 99 - } - $IcingaCustomVariable = [string]::Format('$PowerShell_{0}_{1}$', $parameter.type.name, $parameter.Name); + # Is Numeric Check on position to determine the order value + If (Test-Numeric($parameter.position) -eq $TRUE) { + [string]$Order = [int]$parameter.position + 1 + } else { + [string]$Order = 99 + } - # Conditional whether type of parameter is switch + $IcingaCustomVariable = [string]::Format('$PowerShell_{0}_{1}$', $parameter.type.name, $parameter.Name); + + #Adding arguments to a given command if ($parameter.type.name -eq 'switch') { $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( [string]::Format('-{0}', $parameter.Name), @{ @@ -155,26 +198,31 @@ function Invoke-IcingaCheckCommandBasket() } ); } else { - # Default to Object + # Default to Object $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( [string]::Format('-{0}', $parameter.Name), @{ 'value' = $IcingaCustomVariable; 'order' = $Order; } ); + if ($parameter.name -ne 'Verbose') { $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add($parameter.Name, '$$null'); } else { $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add($parameter.Name, "0"); } } - # Fields - # Required? - if ($parameter.required -eq $TRUE) { + + # Fields + + # Determine wether a parameter is required based on given syntax-information + if ($parameter.required -eq $TRUE) { $Required = 'y'; - } else { + } else { $Required = 'n'; - } + } + + [int]$FieldID = $FieldID + 1; $Basket.Command[$Data.Syntax.syntaxItem.Name].fields.Add( [string]$FieldID, @{ 'datafield_id' = [int]$FieldID; @@ -190,14 +238,14 @@ function Invoke-IcingaCheckCommandBasket() if ($parameter.type.name -eq 'switch') { $IcingaDataType='Datalist'; if ($Basket.DataList.ContainsKey($DataListName) -eq $FALSE) { - $Basket.DataList.Add( - $DataListName, @{ - 'list_name' = $DataListName; - 'owner' = $env:username; - 'originalId' = '50'; #Gehört noch geändert - 'entries' = @{}; - } - ); + $Basket.DataList.Add( + $DataListName, @{ + 'list_name' = $DataListName; + 'owner' = $env:username; + 'originalId' = '50'; #Gehört noch geändert + 'entries' = @{}; + } + ); } } elseif ($parameter.type.name -eq 'Object') { if ($parameter.Name -eq 'Verbose') { @@ -209,84 +257,79 @@ function Invoke-IcingaCheckCommandBasket() } else { $IcingaDataType='String'; } + $IcingaDataType = [string]::Format('Icinga\Module\Director\DataType\DataType{0}', $IcingaDataType) - if ($Basket.Datafield.Values.varname -eq $IcingaCustomVariable) - { - } - else { - [int]$FieldID = $FieldID + 1; - $Basket.Datafield.Add( - [string]$FieldID, @{ - 'varname' = $IcingaCustomVariable; - 'caption' = $parameter.Name; - 'description' = $NULL; - 'datatype' = $IcingaDataType; - 'format' = $NULL; - 'originalId' = [string]$FieldID; - } - ); - - - if ($parameter.type.name -eq 'switch' -or $parameter.Name -eq 'Verbose') { - $Basket.Datafield[[string]$FieldID].Add( - 'settings', @{ - 'behavior' = 'strict'; - 'datatype' = 'string'; - 'datalist' = $DataListName; - } - ); - } elseif ($parameter.type.name -eq 'Object') { - $Basket.Datafield[[string]$FieldID].Add( - 'settings', @{ - 'visbility' = 'visible'; - } - ); + if ($Basket.Datafield.Values.varname -eq $IcingaCustomVariable) { } else { - $Basket.Datafield[[string]$FieldID].Add( - 'settings', @{} + $Basket.Datafield.Add( + [string]$FieldID, @{ + 'varname' = $IcingaCustomVariable; + 'caption' = $parameter.Name; + 'description' = $NULL; + 'datatype' = $IcingaDataType; + 'format' = $NULL; + 'originalId' = [string]$FieldID; + } ); + + if ($parameter.type.name -eq 'switch' -or $parameter.Name -eq 'Verbose') { + $Basket.Datafield[[string]$FieldID].Add( + 'settings', @{ + 'behavior' = 'strict'; + 'datatype' = 'string'; + 'datalist' = $DataListName; + } + ); + } elseif ($parameter.type.name -eq 'Object') { + $Basket.Datafield[[string]$FieldID].Add( + 'settings', @{ + 'visbility' = 'visible'; + } + ); + } else { + $Basket.Datafield[[string]$FieldID].Add( + 'settings', @{} + ); + } } } - [int]$FieldID = $FieldID + 1; } -} # Check whether or not noperfdata and verbose is set and add it if necessary if ($Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.ContainsKey('-Verbose') -eq $FALSE) { - [int]$FieldID = $FieldID + 1; $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( '-Verbose', @{ 'value' = '$PowerShell_Object_Verbose$'; 'order' = '99'; } ); + $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add( 'PowerShell_Object_Verbose', "0" ); + if ($Basket.Datafield.Values.varname -eq $IcingaCustomVariable) { } else { - $Basket.Datafield.Add( - [string]$FieldID, @{ - 'varname' = 'PowerShell_Object_Verbose'; - 'caption' = 'Verbose'; - 'description' = $NULL; - 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; - 'format' = $NULL; - 'originalId' = [string]$FieldID; - 'settings' = @{ - 'behavior' = 'strict'; - 'data_type' = 'string'; - 'datalist' = 'PowerShell Verbose' + $Basket.Datafield.Add( + [string]$FieldID, @{ + 'varname' = 'PowerShell_Object_Verbose'; + 'caption' = 'Verbose'; + 'description' = $NULL; + 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; + 'format' = $NULL; + 'originalId' = [string]$FieldID; + 'settings' = @{ + 'behavior' = 'strict'; + 'data_type' = 'string'; + 'datalist' = 'PowerShell Verbose' + } } - } - ); + ); } } - if ($Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.ContainsKey('-NoPerfData') -eq $FALSE) { - [int]$FieldID = $FieldID + 1; $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( '-NoPerfData', @{ 'set_if' = '$PowerShell_switch_NoPerfData$'; @@ -297,36 +340,47 @@ function Invoke-IcingaCheckCommandBasket() $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add( 'PowerShell_switch_NoPerfData', "0" ); + if ($Basket.Datafield.Values.varname -eq $IcingaCustomVariable) { } else { - $Basket.Datafield.Add( - [string]$FieldID, @{ - 'varname' = 'PowerShell_switch_NoPerfData'; - 'caption' = 'Perf Data'; - 'description' = $NULL; - 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; - 'format' = $NULL; - 'originalId' = [string]$FieldID; - 'settings' = @{ - 'behavior' = 'strict'; - 'data_type' = 'string'; - 'datalist' = 'PowerShell NoPerfData' + $Basket.Datafield.Add( + [string]$FieldID, @{ + 'varname' = 'PowerShell_switch_NoPerfData'; + 'caption' = 'Perf Data'; + 'description' = $NULL; + 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; + 'format' = $NULL; + 'originalId' = [string]$FieldID; + 'settings' = @{ + 'behavior' = 'strict'; + 'data_type' = 'string'; + 'datalist' = 'PowerShell NoPerfData' + } } - } - ); + ); } } - $AllChecks.Add($check, $Basket); + } } -Write-Host $CheckName; -Write-Host $CheckName.Count; + if ($CheckName.Count -eq 1) { + $FileName = "${CheckName}.json"; + } else { + $FileName = "Checks.json"; + } -# if ([string]$CheckName.Count -eq '1') { - $output=ConvertTo-Json -D 100 $Basket > Check.json; -# } else { -# $output=ConvertTo-Json -D 100 $AllChecks > Check.json; -# } + $output=ConvertTo-Json -D 100 $Basket > "$FileName"; + + $FilePath = (Get-Location).Path + + # Output-Text + Write-Host "The following commands have been exported:" + foreach ($check in $CheckName) { + if ($check -ne "Invoke-IcingaCheckCommandBasket") { + Write-Host "- '$check'" + } + } + Write-Host "JSON export created in '${FilePath}\${FileName}'" return $output; } \ No newline at end of file From 2295398f2990874a0a1f39f060c139a29f670173 Mon Sep 17 00:00:00 2001 From: Crited Date: Fri, 13 Sep 2019 08:18:31 +0200 Subject: [PATCH 065/259] Probably fixed ID issues --- .../Invoke-IcingaCheckCommandBasket.psm1 | 62 +++++++++++++++---- 1 file changed, 51 insertions(+), 11 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 b/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 index 744b1a2..cb2818a 100644 --- a/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 +++ b/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 @@ -56,6 +56,7 @@ function Invoke-IcingaCheckCommandBasket() # Variable definition and initialization [int]$FieldID = 0; +# [int]$FieldNumeration = 0; [hashtable]$Basket = @{}; # Define basic hashtable structure by adding fields: "Datafield", "DataList", "Command" @@ -96,7 +97,7 @@ function Invoke-IcingaCheckCommandBasket() 'PowerShell Verbose', @{ 'list_name' = 'PowerShell Verbose'; 'owner' = $env:username; - 'originalId' = '50'; + 'originalId' = '2'; 'entries' = @( @{ 'entry_name' = '0'; @@ -133,6 +134,7 @@ function Invoke-IcingaCheckCommandBasket() or one of $CheckName = 'Invoke-IcingaCheckCommand' #> foreach ($check in $CheckName) { + [int]$FieldNumeration = 0; if ($check -eq 'Invoke-IcingaCheckCommandBasket') { } else { @@ -222,15 +224,6 @@ function Invoke-IcingaCheckCommandBasket() $Required = 'n'; } - [int]$FieldID = $FieldID + 1; - $Basket.Command[$Data.Syntax.syntaxItem.Name].fields.Add( - [string]$FieldID, @{ - 'datafield_id' = [int]$FieldID; - 'is_required' = $Required; - 'var_filter' = $NULL; - } - ); - $IcingaCustomVariable = [string]::Format('PowerShell_{0}_{1}', $parameter.type.name, $parameter.Name); $DataListName = [string]::Format('PowerShell {0}', $parameter.Name) @@ -289,11 +282,16 @@ function Invoke-IcingaCheckCommandBasket() ); } else { $Basket.Datafield[[string]$FieldID].Add( - 'settings', @{} + 'settings', @{ + 'visbility' = 'visible'; + } ); } + [int]$FieldID = [int]$FieldID + 1; } } + +[int]$FieldNumeration = [int]$FieldNumeration + 1; } # Check whether or not noperfdata and verbose is set and add it if necessary @@ -362,6 +360,48 @@ function Invoke-IcingaCheckCommandBasket() } } } + foreach ($check in $CheckName) { + [int]$FieldNumeration = 0; + if ($check -eq 'Invoke-IcingaCheckCommandBasket') { + } else { + + $Data = (Get-Help $check) + + foreach ($parameter in $Data.Syntax.syntaxItem.parameter){ + $IcingaCustomVariable = [string]::Format('PowerShell_{0}_{1}', $parameter.type.name, $parameter.Name); + + + [hashtable]$translationdatafield = @{} + foreach ($DID in $Basket.Datafield.Keys) + { + + $translationdatafield.Add($Basket.Datafield.$DID.varname, $DID); + } + +# $translationdatafield.Add() + foreach($key in $translationdatafield.Keys) + { + if ([string]$IcingaCustomVariable -eq [string]$key) + { + $otherID = $translationdatafield[$IcingaCustomVariable]; + } else {} + } + # Get Necessary Syntax-Information and more through cmdlet "Get-Help" + Write-Host $Data.Syntax.syntaxItem.Name + Write-Host $Parameter.Name + # [int]$FieldID = [int]$FieldID + 1; + $Basket.Command[$Data.Syntax.syntaxItem.Name].fields.Add( + [string]$FieldNumeration, @{ + 'datafield_id' = [int]$otherID; + 'is_required' = $Required; + 'var_filter' = $NULL; + } + ); + + [int]$FieldNumeration = [int]$FieldNumeration + 1; + } + } +} if ($CheckName.Count -eq 1) { $FileName = "${CheckName}.json"; From c29983c4379d7964d4d50f1cbaa9790aa40c9bc2 Mon Sep 17 00:00:00 2001 From: Crited Date: Fri, 13 Sep 2019 09:22:27 +0200 Subject: [PATCH 066/259] Presumably finished Invoke-IcingaCheckCommandBasket Module --- .../Invoke-IcingaCheckCommandBasket.psm1 | 79 ++++++++++++++++++- 1 file changed, 75 insertions(+), 4 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 b/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 index cb2818a..70b0cae 100644 --- a/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 +++ b/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 @@ -8,6 +8,10 @@ More Information on https://github.com/LordHepipud/icinga-module-windows +.FUNCTIONALITY + This module is intended to be used to export one or all PowerShell-Modules with the namespace 'Invoke-IcingaCheck'. + The JSON-Export, which will be egenerated through this module is structured like an Icinga-Director-JSON-Export, so it can be imported via the Icinga-Director the same way. + .EXAMPLE PS>Invoke-IcingaCheckCommandBasket The following commands have been exported: @@ -32,6 +36,8 @@ Has to be a single string. .INPUTS System.String + Oder: + None. You cannot pipe objects to Add-Extension. .OUTPUTS System.String @@ -55,7 +61,7 @@ function Invoke-IcingaCheckCommandBasket() } # Variable definition and initialization - [int]$FieldID = 0; + [int]$FieldID = 3; # [int]$FieldNumeration = 0; [hashtable]$Basket = @{}; @@ -251,6 +257,56 @@ function Invoke-IcingaCheckCommandBasket() $IcingaDataType='String'; } + if($Basket.Datafield.ContainsKey('0') -eq $FALSE){ + $Basket.Datafield.Add( + '0', @{ + 'varname' = 'PowerShell_switch_NoPerfData'; + 'caption' = 'NoPerfData'; + 'description' = $NULL; + 'datatype' = 'Icinga\\Module\\Director\\DataType\\DataTypeDatalist'; + 'format' = $NULL; + 'originalId' = '0'; + 'settings' = @{ + 'datalist' = 'PowerShell NoPerfData'; + 'datatype' = 'string'; + 'behavior' = 'strict'; + } + } + ) + } + + if($Basket.Datafield.ContainsKey('1') -eq $FALSE){ + $Basket.Datafield.Add( + '1', @{ + 'varname' = 'PowerShell_switch_NoPerfData'; + 'caption' = 'Verbose'; + 'description' = $NULL; + 'datatype' = 'Icinga\\Module\\Director\\DataType\\DataTypeString'; + 'format' = $NULL; + 'originalId' = '1'; + 'settings' = @{ + 'datalist' = 'PowerShell Verbose'; + 'datatype' = 'string'; + 'behavior' = 'strict'; + } + } + ) + } + + if($Basket.Datafield.ContainsKey('2') -eq $FALSE){ + $Basket.Datafield.Add( + '2', @{ + 'varname' = 'Basket_Check_Variable'; + 'caption' = 'Basket_Check'; + 'description' = $NULL; + 'datatype' = 'Icinga\\Module\\Director\\DataType\\DataTypeArray'; + 'format' = $NULL; + 'originalId' = '2'; + 'settings' = @{}; + } + ) + } + $IcingaDataType = [string]::Format('Icinga\Module\Director\DataType\DataType{0}', $IcingaDataType) if ($Basket.Datafield.Values.varname -eq $IcingaCustomVariable) { @@ -361,7 +417,7 @@ function Invoke-IcingaCheckCommandBasket() } } foreach ($check in $CheckName) { - [int]$FieldNumeration = 0; + [int]$FieldNumeration = 1; if ($check -eq 'Invoke-IcingaCheckCommandBasket') { } else { @@ -370,12 +426,26 @@ function Invoke-IcingaCheckCommandBasket() foreach ($parameter in $Data.Syntax.syntaxItem.parameter){ $IcingaCustomVariable = [string]::Format('PowerShell_{0}_{1}', $parameter.type.name, $parameter.Name); + if ($Basket.Command[$Data.Syntax.syntaxItem.Name].fields.ContainsKey('0') -eq $FALSE){ + $Basket.Command[$Data.Syntax.syntaxItem.Name].fields.Add( + '0', @{ + 'datafield_id' = '2'; + 'is_required' = 'n'; + 'var_filter' = $NULL; + } + ); + } + + [hashtable]$translationdatafield = @{} foreach ($DID in $Basket.Datafield.Keys) { + if ($translationdatafield.Contains('PowerShell_switch_NoPerfData') -eq $TRUE){ + }else{ $translationdatafield.Add($Basket.Datafield.$DID.varname, $DID); + } } # $translationdatafield.Add() @@ -387,9 +457,10 @@ function Invoke-IcingaCheckCommandBasket() } else {} } # Get Necessary Syntax-Information and more through cmdlet "Get-Help" - Write-Host $Data.Syntax.syntaxItem.Name - Write-Host $Parameter.Name +# Write-Host $Data.Syntax.syntaxItem.Name +# Write-Host $Parameter.Name # [int]$FieldID = [int]$FieldID + 1; + $Basket.Command[$Data.Syntax.syntaxItem.Name].fields.Add( [string]$FieldNumeration, @{ 'datafield_id' = [int]$otherID; From f74261088ff802db49da97d2eebee71f3f4e6562 Mon Sep 17 00:00:00 2001 From: Crited Date: Fri, 13 Sep 2019 11:44:37 +0200 Subject: [PATCH 067/259] Renamed Module; Code-Styling; Added Timestamp; Rewrote Commentbased Help; This is the supposedly last version that works (has worked) --- lib/plugins/Get-IcingaCheckCommandConfig.psm1 | 492 +++++++++++++++++ .../Invoke-IcingaCheckCommandBasket.psm1 | 497 ------------------ 2 files changed, 492 insertions(+), 497 deletions(-) create mode 100644 lib/plugins/Get-IcingaCheckCommandConfig.psm1 delete mode 100644 lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 diff --git a/lib/plugins/Get-IcingaCheckCommandConfig.psm1 b/lib/plugins/Get-IcingaCheckCommandConfig.psm1 new file mode 100644 index 0000000..3b1f42a --- /dev/null +++ b/lib/plugins/Get-IcingaCheckCommandConfig.psm1 @@ -0,0 +1,492 @@ +<# +.SYNOPSIS + Exports command as JSON for icinga director + +.DESCRIPTION + Get-IcingaCheckCommandConfig returns a JSON-file of one or all 'Invoke-IcingaCheck'-Commands, which can be imported via Icinga-Director + When no single command is specified all commands will be exported, and vice versa. + + More Information on https://github.com/LordHepipud/icinga-module-windows + +.FUNCTIONALITY + This module is intended to be used to export one or all PowerShell-Modules with the namespace 'Invoke-IcingaCheck'. + The JSON-Export, which will be egenerated through this module is structured like an Icinga-Director-JSON-Export, so it can be imported via the Icinga-Director the same way. + +.EXAMPLE + PS>Get-IcingaCheckCommandConfig + Check Command JSON for the following commands: + - 'Invoke-IcingaCheckBiosSerial' + - 'Invoke-IcingaCheckCPU' + - 'Invoke-IcingaCheckProcessCount' + - 'Invoke-IcingaCheckService' + - 'Invoke-IcingaCheckUpdates' + - 'Invoke-IcingaCheckUptime' + - 'Invoke-IcingaCheckUsedPartitionSpace' + - 'Invoke-IcingaCheckUsers' +############################################################ + + +.EXAMPLE + Get-IcingaCheckCommandConfig -OutFile 'C:\Users\icinga\config-exports' + The following commands have been exported: + - 'Invoke-IcingaCheckBiosSerial' + - 'Invoke-IcingaCheckCPU' + - 'Invoke-IcingaCheckProcessCount' + - 'Invoke-IcingaCheckService' + - 'Invoke-IcingaCheckUpdates' + - 'Invoke-IcingaCheckUptime' + - 'Invoke-IcingaCheckUsedPartitionSpace' + - 'Invoke-IcingaCheckUsers' + JSON export created in 'C:\Users\icinga\config-exports\PowerShell_CheckCommands_09-13-2019-10-55-1989.json' + +.EXAMPLE + Get-IcingaCheckCommandConfig Invoke-IcingaCheckBiosSerial, Invoke-IcingaCheckCPU -OutFile 'C:\Users\icinga\config-exports' + The following commands have been exported: + - 'Invoke-IcingaCheckBiosSerial' + - 'Invoke-IcingaCheckCPU' + JSON export created in 'C:\Users\icinga\config-exports\PowerShell_CheckCommands_09-13-2019-10-58-5342.json' + +.PARAMETER CheckName + Used to specify an array of commands which should be exported. + Seperated with ',' + + .INPUTS + System.Array + + .OUTPUTS + System.String + + .LINK + https://github.com/LordHepipud/icinga-module-windows + + .NOTES +#> + +function Get-IcingaCheckCommandConfig() +{ + param( + [Parameter(ValueFromPipeline)] + [array]$CheckName, + [string]$OutFile + ); + + # Check whether all Checks will be exported or just the ones specified + if ([string]::IsNullOrEmpty($CheckName) -eq $true) { + $CheckName = (Get-Command Invoke-IcingaCheck*).Name + } + + [int]$FieldID = 2; # Starts at '2', because '0' and '1' are reserved for 'Verbose' and 'NoPerfData' + [hashtable]$Basket = @{}; + + # Define basic hashtable structure by adding fields: "Datafield", "DataList", "Command" + $Basket.Add('Datafield', @{}); + $Basket.Add('DataList', @{}); + $Basket.Add('Command', @{}); + + + # "NoPerfData" gets added to all checks build and exported no matter what, so we add it from the start + if ($Basket.DataList.ContainsKey('PowerShell NoPerfData') -eq $FALSE) { + + # DataList Content for NoPerfData + $Basket.DataList.Add( + 'PowerShell NoPerfData', @{ + 'list_name' = 'PowerShell NoPerfData'; + 'owner' = $env:username; + 'originalId' = '1'; + 'entries' = @( + @{ + 'entry_name' = '0'; + 'entry_value:' = "yes"; + 'format' = 'string'; + 'allowed_roles' = $NULL; + }, + @{ + 'entry_name' = '1'; + 'entry_value:' = "no"; + 'format' = 'string'; + 'allowed_roles' = $NULL; + } + ); + } + ); + } + + # "Verbose" gets added to all Checks build and exported no matter what, so we add it from the start + if ($Basket.DataList.ContainsKey('PowerShell Verbose') -eq $FALSE) { + $Basket.DataList.Add( + 'PowerShell Verbose', @{ + 'list_name' = 'PowerShell Verbose'; + 'owner' = $env:username; + 'originalId' = '2'; + 'entries' = @( + @{ + 'entry_name' = '0'; + 'entry_value:' = "Show Default"; + 'format' = 'string'; + 'allowed_roles' = $NULL; + }, + @{ + 'entry_name' = '1'; + 'entry_value:' = "Show Operator"; + 'format' = 'string'; + 'allowed_roles' = $NULL; + }, + @{ + 'entry_name' = '2'; + 'entry_value:' = "Show Problems"; + 'format' = 'string'; + 'allowed_roles' = $NULL; + }, + @{ + 'entry_name' = '3'; + 'entry_value:' = "Show All"; + 'format' = 'string'; + 'allowed_roles' = $NULL; + } + ); + } + ); + } + + # Loop through ${CheckName}, to get information on every command specified/all commands. + foreach ($check in $CheckName) { + + [int]$FieldNumeration = 0; + + # Get necessary syntax-information and more through cmdlet "Get-Help" + $Data = (Get-Help $check) + + # Add command Structure + $Basket.Command.Add( + $Data.Syntax.syntaxItem.Name, @{ + 'arguments'= @{ + # Gets set for every command as default + '-C' = @{ + 'value' = [string]::Format('Use-Icinga; {0}', $Data.Syntax.syntaxItem.Name); + 'order' = '0'; + } + } + 'command' = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"; + 'disabled' = $FALSE; + 'fields' = @{}; + 'imports' = @(); + 'is_string' = $NULL; + 'methods_excute' = 'PluginCheck'; + 'object_name' = $Data.Syntax.syntaxItem.Name; + 'object_type' = 'object'; + 'timeout' = '180'; + 'vars' = @{}; + 'zone' = $NULL; + } + ); + + # Loop through parameters of a given command + foreach ($parameter in $Data.Syntax.syntaxItem.parameter) { + + # Filter for Parameter 'core', because its set by default + if ($parameter.name -ne 'core') { + + # IsNumeric-Check on position to determine the order-value + If (Test-Numeric($parameter.position) -eq $TRUE) { + [string]$Order = [int]$parameter.position + 1; + } else { + [string]$Order = 99 + } + + $IcingaCustomVariable = [string]::Format('$PowerShell_{0}_{1}$', $parameter.type.name, $parameter.Name); + + # Add arguments to a given command + if ($parameter.type.name -eq 'switch') { + $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( + [string]::Format('-{0}', $parameter.Name), @{ + 'set_if' = $IcingaCustomVariable; + 'set_if_format' = 'string'; + 'order' = $Order; + } + ); + + $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add($parameter.Name, "0"); + + # Conditional whether type of parameter is array + } elseif ($parameter.type.name -eq 'array') { + $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( + [string]::Format('-{0}', $parameter.Name), @{ + 'value' = [string]::Format('(Split-IcingaCheckCommandArgs {0})', $IcingaCustomVariable); + 'order' = $Order; + } + ); + } else { + # Default to Object + $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( + [string]::Format('-{0}', $parameter.Name), @{ + 'value' = $IcingaCustomVariable; + 'order' = $Order; + } + ); + + if ($parameter.name -ne 'Verbose') { + $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add($parameter.Name, '$$null'); + } else { + $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add($parameter.Name, "0"); + } + } + + # Determine wether a parameter is required based on given syntax-information + if ($parameter.required -eq $TRUE) { + $Required = 'y'; + } else { + $Required = 'n'; + } + + $IcingaCustomVariable = [string]::Format('PowerShell_{0}_{1}', $parameter.type.name, $parameter.Name); + + $DataListName = [string]::Format('PowerShell {0}', $parameter.Name) + + if ($parameter.type.name -eq 'switch') { + $IcingaDataType='Datalist'; + if ($Basket.DataList.ContainsKey($DataListName) -eq $FALSE) { + $Basket.DataList.Add( + $DataListName, @{ + 'list_name' = $DataListName; + 'owner' = $env:username; + 'originalId' = '50'; #Gehört noch geändert + 'entries' = @{}; + } + ); + } + } elseif ($parameter.type.name -eq 'Object') { + if ($parameter.Name -eq 'Verbose') { + $IcingaDataType='Datalist' + } + + $IcingaDataType='String'; + + } elseif ($parameter.type.name -eq 'Array') { + $IcingaDataType='Array'; + } else { + $IcingaDataType='String'; + } + + if($Basket.Datafield.ContainsKey('0') -eq $FALSE){ + $Basket.Datafield.Add( + '0', @{ + 'varname' = 'PowerShell_switch_NoPerfData'; + 'caption' = 'NoPerfData'; + 'description' = $NULL; + 'datatype' = 'Icinga\\Module\\Director\\DataType\\DataTypeDatalist'; + 'format' = $NULL; + 'originalId' = '0'; + 'settings' = @{ + 'datalist' = 'PowerShell NoPerfData'; + 'datatype' = 'string'; + 'behavior' = 'strict'; + } + } + ); + } + + if($Basket.Datafield.ContainsKey('1') -eq $FALSE){ + $Basket.Datafield.Add( + '1', @{ + 'varname' = 'PowerShell_switch_NoPerfData'; + 'caption' = 'Verbose'; + 'description' = $NULL; + 'datatype' = 'Icinga\\Module\\Director\\DataType\\DataTypeString'; + 'format' = $NULL; + 'originalId' = '1'; + 'settings' = @{ + 'datalist' = 'PowerShell Verbose'; + 'datatype' = 'string'; + 'behavior' = 'strict'; + } + } + ); + } + + $IcingaDataType = [string]::Format('Icinga\Module\Director\DataType\DataType{0}', $IcingaDataType) + + if ($Basket.Datafield.Values.varname -eq $IcingaCustomVariable) { + } else { + $Basket.Datafield.Add( + [string]$FieldID, @{ + 'varname' = $IcingaCustomVariable; + 'caption' = $parameter.Name; + 'description' = $NULL; + 'datatype' = $IcingaDataType; + 'format' = $NULL; + 'originalId' = [string]$FieldID; + } + ); + + if ($parameter.type.name -eq 'switch' -or $parameter.Name -eq 'Verbose') { + $Basket.Datafield[[string]$FieldID].Add( + 'settings', @{ + 'behavior' = 'strict'; + 'datatype' = 'string'; + 'datalist' = $DataListName; + } + ); + } elseif ($parameter.type.name -eq 'Object') { + $Basket.Datafield[[string]$FieldID].Add( + 'settings', @{ + 'visbility' = 'visible'; + } + ); + } else { + $Basket.Datafield[[string]$FieldID].Add( + 'settings', @{ + 'visbility' = 'visible'; + } + ); + } + + # Increment FieldID, so unique datafields are added. + [int]$FieldID = [int]$FieldID + 1; + } + } + + # Increment FieldNumeation, so unique fields for a given command are added. + [int]$FieldNumeration = [int]$FieldNumeration + 1; + } + + # Check whether or not noperfdata and verbose is set and add it if necessary + if ($Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.ContainsKey('-Verbose') -eq $FALSE) { + $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( + '-Verbose', @{ + 'value' = '$PowerShell_Object_Verbose$'; + 'order' = '99'; + } + ); + + $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add( + 'PowerShell_Object_Verbose', "0" + ); + + if ($Basket.Datafield.Values.varname -eq $IcingaCustomVariable) { + } else { + $Basket.Datafield.Add( + [string]$FieldID, @{ + 'varname' = 'PowerShell_Object_Verbose'; + 'caption' = 'Verbose'; + 'description' = $NULL; + 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; + 'format' = $NULL; + 'originalId' = [string]$FieldID; + 'settings' = @{ + 'behavior' = 'strict'; + 'data_type' = 'string'; + 'datalist' = 'PowerShell Verbose' + } + } + ); + } + } + + if ($Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.ContainsKey('-NoPerfData') -eq $FALSE) { + $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( + '-NoPerfData', @{ + 'set_if' = '$PowerShell_switch_NoPerfData$'; + 'set_if_format' = 'string'; + 'order' = '99'; + } + ); + $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add('PowerShell_switch_NoPerfData', "0"); + + if ($Basket.Datafield.Values.varname -eq $IcingaCustomVariable) { + } else { + $Basket.Datafield.Add( + [string]$FieldID, @{ + 'varname' = 'PowerShell_switch_NoPerfData'; + 'caption' = 'Perf Data'; + 'description' = $NULL; + 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; + 'format' = $NULL; + 'originalId' = [string]$FieldID; + 'settings' = @{ + 'behavior' = 'strict'; + 'data_type' = 'string'; + 'datalist' = 'PowerShell NoPerfData' + } + } + ); + } + } + } + + foreach ($check in $CheckName) { + [int]$FieldNumeration = 0; + + $Data = (Get-Help $check) + + foreach ($parameter in $Data.Syntax.syntaxItem.parameter){ + $IcingaCustomVariable = [string]::Format('PowerShell_{0}_{1}', $parameter.type.name, $parameter.Name); + + # Hashtable for Matching Command.Name.Fields to DataFields (and there given IDs) + [hashtable]$TranslationDataField = @{} + + # Looping through IDs of existing DataFields + foreach ($DataFieldID in $Basket.Datafield.Keys) + { + # Ignore Default-Set Deatafield "NoPerfData" + if ($TranslationDataField.Contains('PowerShell_switch_NoPerfData') -eq $TRUE){ + }else{ + $TranslationDataField.Add($Basket.Datafield.$DataFieldID.varname, $DataFieldID); + } + } + + foreach($key in $TranslationDataField.Keys) + { + if ([string]$IcingaCustomVariable -eq [string]$key) { + $MatchedDataFieldID = $TranslationDataField[$IcingaCustomVariable]; + } else {} + } + + $Basket.Command[$Data.Syntax.syntaxItem.Name].fields.Add( + [string]$FieldNumeration, @{ + 'datafield_id' = [int]$MatchedDataFieldID; + 'is_required' = $Required; + 'var_filter' = $NULL; + } + ); + + [int]$FieldNumeration = [int]$FieldNumeration + 1; + } + } + + # Build Filename with given Timestamp + $TimeStamp = (Get-Date -Format "MM-dd-yyyy-HH-mm-ffff"); + $FileName = "PowerShell_CheckCommands_$TimeStamp.json"; + + # Generate JSON Output from Hashtable + $output = ConvertTo-Json -Depth 100 $Basket -Compress; + + # Determine whether json output via powershell or in file (based on param -OutFile) + if ([string]::IsNullOrEmpty($OutFile) -eq $false) { + $OutFile = (Join-Path -Path $OutFile -ChildPath $FileName); + if ((Test-Path($OutFile)) -eq $false) { + New-Item -Path $OutFile -Force | Out-Null; + } + + if ((Test-Path($OutFile)) -eq $false) { + throw 'Failed to create specified directory. Please try again or use a different target location.'; + } + + Set-Content -Path $OutFile -Value $output; + + # Output-Text + Write-Host "The following commands have been exported:" + foreach ($check in $CheckName) { + Write-Host "- '$check'"; + } + Write-Host "JSON export created in '${OutFile}'" + return; + } + + Write-Host "Check Command JSON for the following commands:" + foreach ($check in $CheckName) { + Write-Host "- '$check'" + } + Write-Host '############################################################'; + + return $output; +} diff --git a/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 b/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 deleted file mode 100644 index 70b0cae..0000000 --- a/lib/plugins/Invoke-IcingaCheckCommandBasket.psm1 +++ /dev/null @@ -1,497 +0,0 @@ -<# -.SYNOPSIS - Exports command as JSON for icinga director - -.DESCRIPTION - Invoke-IcingaCheckCommandBasket returns a JSON-file of one or all 'Invoke-IcingaCheck'-Commands, which can be imported via Icinga-Director - When no single command is specified all commands will be exported, and vice versa. - - More Information on https://github.com/LordHepipud/icinga-module-windows - -.FUNCTIONALITY - This module is intended to be used to export one or all PowerShell-Modules with the namespace 'Invoke-IcingaCheck'. - The JSON-Export, which will be egenerated through this module is structured like an Icinga-Director-JSON-Export, so it can be imported via the Icinga-Director the same way. - -.EXAMPLE - PS>Invoke-IcingaCheckCommandBasket - The following commands have been exported: - - 'Invoke-IcingaCheckBiosSerial' - - 'Invoke-IcingaCheckCommandBasket' - - 'Invoke-IcingaCheckCPU' - - 'Invoke-IcingaCheckProcessCount' - - 'Invoke-IcingaCheckService' - - 'Invoke-IcingaCheckUpdates' - - 'Invoke-IcingaCheckUptime' - - 'Invoke-IcingaCheckUsedPartitionSpace' - - 'Invoke-IcingaCheckUsers' - JSON export created to 'C:\Program Files\WindowsPowerShell\Modules\icinga-module-windows\Checks.json' - -.EXAMPLE - PS>Invoke-IcingaCheckCommandBasket Invoke-IcingaCheckCPU - The following commands have been exported: - - 'Invoke-IcingaCheckCPU' - JSON export created to 'C:\Program Files\WindowsPowerShell\Modules\icinga-module-windows\Invoke-IcingaCheckCPU.json' -.PARAMETER CheckName - Used to specify a single command which should be exported. - Has to be a single string. - .INPUTS - System.String - Oder: - None. You cannot pipe objects to Add-Extension. - - .OUTPUTS - System.String - System.Object - - .LINK - https://github.com/LordHepipud/icinga-module-windows - - .NOTES -#> - -function Invoke-IcingaCheckCommandBasket() -{ - param( - $CheckName - ); - - # Check whether all Checks will be exported or just the single one specified - if ($NULL -eq $CheckName) { - $CheckName = (Get-Command Invoke-IcingaCheck*).Name - } - - # Variable definition and initialization - [int]$FieldID = 3; -# [int]$FieldNumeration = 0; - [hashtable]$Basket = @{}; - - # Define basic hashtable structure by adding fields: "Datafield", "DataList", "Command" - $Basket.Add('Datafield', @{}); - $Basket.Add('DataList', @{}); - $Basket.Add('Command', @{}); - - - # "NoPerfData" gets added to all Checks build and exported no matter what, so we add it from the start - if ($Basket.DataList.ContainsKey('PowerShell NoPerfData') -eq $FALSE) { - - # DataList Content for NoPerfData - $Basket.DataList.Add( - 'PowerShell NoPerfData', @{ - 'list_name' = 'PowerShell NoPerfData'; - 'owner' = $env:username; - 'originalId' = '1'; #Gehört noch geändert - 'entries' = @( - @{ - 'entry_name' = '0'; - 'entry_value:' = "yes"; - 'format' = 'string'; - 'allowed_roles' = $NULL; - }, - @{ - 'entry_name' = '1'; - 'entry_value:' = "no"; - 'format' = 'string'; - 'allowed_roles' = $NULL; - } - ); - } - ); - } - # "Verbose" gets added to all Checks build and exported no matter what, so we add it from the start - if ($Basket.DataList.ContainsKey('PowerShell Verbose') -eq $FALSE) { - $Basket.DataList.Add( - 'PowerShell Verbose', @{ - 'list_name' = 'PowerShell Verbose'; - 'owner' = $env:username; - 'originalId' = '2'; - 'entries' = @( - @{ - 'entry_name' = '0'; - 'entry_value:' = "Show Default"; - 'format' = 'string'; - 'allowed_roles' = $NULL; - }, - @{ - 'entry_name' = '1'; - 'entry_value:' = "Show Operator"; - 'format' = 'string'; - 'allowed_roles' = $NULL; - }, - @{ - 'entry_name' = '2'; - 'entry_value:' = "Show Problems"; - 'format' = 'string'; - 'allowed_roles' = $NULL; - }, - @{ - 'entry_name' = '3'; - 'entry_value:' = "Show All"; - 'format' = 'string'; - 'allowed_roles' = $NULL; - } - ); - } - ); - } - - <# - Loop through either: - $CheckName = (Get-Command Invoke-IcingaCheck*).Name - or one of $CheckName = 'Invoke-IcingaCheckCommand' - #> - foreach ($check in $CheckName) { - [int]$FieldNumeration = 0; - if ($check -eq 'Invoke-IcingaCheckCommandBasket') { - } else { - - # Get Necessary Syntax-Information and more through cmdlet "Get-Help" - $Data = (Get-Help $check) - - # Add Command Structure - $Basket.Command.Add( - $Data.Syntax.syntaxItem.Name, @{ - 'arguments'= @{ - # Gets set for every command as Default - '-C' = @{ - 'value' = [string]::Format('Use-Icinga; {0}', $Data.Syntax.syntaxItem.Name); - 'order' = '0'; - } - } - 'command' = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"; - 'disabled' = $FALSE; - 'fields' = @{}; - 'imports' = @(); - 'is_string' = $NULL; - 'methods_excute' = 'PluginCheck'; - 'object_name' = $Data.Syntax.syntaxItem.Name; - 'object_type' = 'object'; - 'timeout' = '180'; - 'vars' = @{}; - 'zone' = $NULL; - } - ) - - # Loop through Parameter of a given command - foreach ($parameter in $Data.Syntax.syntaxItem.parameter) { - # Filter for Parameter 'core', because its set by default - if ($parameter.name -ne 'core') { - - # Is Numeric Check on position to determine the order value - If (Test-Numeric($parameter.position) -eq $TRUE) { - [string]$Order = [int]$parameter.position + 1 - } else { - [string]$Order = 99 - } - - $IcingaCustomVariable = [string]::Format('$PowerShell_{0}_{1}$', $parameter.type.name, $parameter.Name); - - #Adding arguments to a given command - if ($parameter.type.name -eq 'switch') { - $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( - [string]::Format('-{0}', $parameter.Name), @{ - 'set_if' = $IcingaCustomVariable; - 'set_if_format' = 'string'; - 'order' = $Order; - } - ); - $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add( - $parameter.Name, "0" - ); - # Condotional whether type of parameter is array - } elseif ($parameter.type.name -eq 'array') { - $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( - [string]::Format('-{0}', $parameter.Name), @{ - 'value' = [string]::Format('(Split-IcingaCheckCommandArgs {0})', $IcingaCustomVariable); - 'order' = $Order; - } - ); - } else { - # Default to Object - $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( - [string]::Format('-{0}', $parameter.Name), @{ - 'value' = $IcingaCustomVariable; - 'order' = $Order; - } - ); - - if ($parameter.name -ne 'Verbose') { - $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add($parameter.Name, '$$null'); - } else { - $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add($parameter.Name, "0"); - } - } - - # Fields - - # Determine wether a parameter is required based on given syntax-information - if ($parameter.required -eq $TRUE) { - $Required = 'y'; - } else { - $Required = 'n'; - } - - $IcingaCustomVariable = [string]::Format('PowerShell_{0}_{1}', $parameter.type.name, $parameter.Name); - - $DataListName = [string]::Format('PowerShell {0}', $parameter.Name) - - if ($parameter.type.name -eq 'switch') { - $IcingaDataType='Datalist'; - if ($Basket.DataList.ContainsKey($DataListName) -eq $FALSE) { - $Basket.DataList.Add( - $DataListName, @{ - 'list_name' = $DataListName; - 'owner' = $env:username; - 'originalId' = '50'; #Gehört noch geändert - 'entries' = @{}; - } - ); - } - } elseif ($parameter.type.name -eq 'Object') { - if ($parameter.Name -eq 'Verbose') { - $IcingaDataType='Datalist' - } - $IcingaDataType='String'; - } elseif ($parameter.type.name -eq 'Array') { - $IcingaDataType='Array'; - } else { - $IcingaDataType='String'; - } - - if($Basket.Datafield.ContainsKey('0') -eq $FALSE){ - $Basket.Datafield.Add( - '0', @{ - 'varname' = 'PowerShell_switch_NoPerfData'; - 'caption' = 'NoPerfData'; - 'description' = $NULL; - 'datatype' = 'Icinga\\Module\\Director\\DataType\\DataTypeDatalist'; - 'format' = $NULL; - 'originalId' = '0'; - 'settings' = @{ - 'datalist' = 'PowerShell NoPerfData'; - 'datatype' = 'string'; - 'behavior' = 'strict'; - } - } - ) - } - - if($Basket.Datafield.ContainsKey('1') -eq $FALSE){ - $Basket.Datafield.Add( - '1', @{ - 'varname' = 'PowerShell_switch_NoPerfData'; - 'caption' = 'Verbose'; - 'description' = $NULL; - 'datatype' = 'Icinga\\Module\\Director\\DataType\\DataTypeString'; - 'format' = $NULL; - 'originalId' = '1'; - 'settings' = @{ - 'datalist' = 'PowerShell Verbose'; - 'datatype' = 'string'; - 'behavior' = 'strict'; - } - } - ) - } - - if($Basket.Datafield.ContainsKey('2') -eq $FALSE){ - $Basket.Datafield.Add( - '2', @{ - 'varname' = 'Basket_Check_Variable'; - 'caption' = 'Basket_Check'; - 'description' = $NULL; - 'datatype' = 'Icinga\\Module\\Director\\DataType\\DataTypeArray'; - 'format' = $NULL; - 'originalId' = '2'; - 'settings' = @{}; - } - ) - } - - $IcingaDataType = [string]::Format('Icinga\Module\Director\DataType\DataType{0}', $IcingaDataType) - - if ($Basket.Datafield.Values.varname -eq $IcingaCustomVariable) { - } else { - $Basket.Datafield.Add( - [string]$FieldID, @{ - 'varname' = $IcingaCustomVariable; - 'caption' = $parameter.Name; - 'description' = $NULL; - 'datatype' = $IcingaDataType; - 'format' = $NULL; - 'originalId' = [string]$FieldID; - } - ); - - if ($parameter.type.name -eq 'switch' -or $parameter.Name -eq 'Verbose') { - $Basket.Datafield[[string]$FieldID].Add( - 'settings', @{ - 'behavior' = 'strict'; - 'datatype' = 'string'; - 'datalist' = $DataListName; - } - ); - } elseif ($parameter.type.name -eq 'Object') { - $Basket.Datafield[[string]$FieldID].Add( - 'settings', @{ - 'visbility' = 'visible'; - } - ); - } else { - $Basket.Datafield[[string]$FieldID].Add( - 'settings', @{ - 'visbility' = 'visible'; - } - ); - } - [int]$FieldID = [int]$FieldID + 1; - } - } - -[int]$FieldNumeration = [int]$FieldNumeration + 1; - } - - # Check whether or not noperfdata and verbose is set and add it if necessary - if ($Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.ContainsKey('-Verbose') -eq $FALSE) { - $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( - '-Verbose', @{ - 'value' = '$PowerShell_Object_Verbose$'; - 'order' = '99'; - } - ); - - $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add( - 'PowerShell_Object_Verbose', "0" - ); - - if ($Basket.Datafield.Values.varname -eq $IcingaCustomVariable) { - } else { - $Basket.Datafield.Add( - [string]$FieldID, @{ - 'varname' = 'PowerShell_Object_Verbose'; - 'caption' = 'Verbose'; - 'description' = $NULL; - 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; - 'format' = $NULL; - 'originalId' = [string]$FieldID; - 'settings' = @{ - 'behavior' = 'strict'; - 'data_type' = 'string'; - 'datalist' = 'PowerShell Verbose' - } - } - ); - } - } - - if ($Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.ContainsKey('-NoPerfData') -eq $FALSE) { - $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( - '-NoPerfData', @{ - 'set_if' = '$PowerShell_switch_NoPerfData$'; - 'set_if_format' = 'string'; - 'order' = '99'; - } - ); - $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add( - 'PowerShell_switch_NoPerfData', "0" - ); - - if ($Basket.Datafield.Values.varname -eq $IcingaCustomVariable) { - } else { - $Basket.Datafield.Add( - [string]$FieldID, @{ - 'varname' = 'PowerShell_switch_NoPerfData'; - 'caption' = 'Perf Data'; - 'description' = $NULL; - 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; - 'format' = $NULL; - 'originalId' = [string]$FieldID; - 'settings' = @{ - 'behavior' = 'strict'; - 'data_type' = 'string'; - 'datalist' = 'PowerShell NoPerfData' - } - } - ); - } - } - } - } - foreach ($check in $CheckName) { - [int]$FieldNumeration = 1; - if ($check -eq 'Invoke-IcingaCheckCommandBasket') { - } else { - - $Data = (Get-Help $check) - - foreach ($parameter in $Data.Syntax.syntaxItem.parameter){ - $IcingaCustomVariable = [string]::Format('PowerShell_{0}_{1}', $parameter.type.name, $parameter.Name); - - if ($Basket.Command[$Data.Syntax.syntaxItem.Name].fields.ContainsKey('0') -eq $FALSE){ - $Basket.Command[$Data.Syntax.syntaxItem.Name].fields.Add( - '0', @{ - 'datafield_id' = '2'; - 'is_required' = 'n'; - 'var_filter' = $NULL; - } - ); - } - - - - [hashtable]$translationdatafield = @{} - foreach ($DID in $Basket.Datafield.Keys) - { - if ($translationdatafield.Contains('PowerShell_switch_NoPerfData') -eq $TRUE){ - - }else{ - $translationdatafield.Add($Basket.Datafield.$DID.varname, $DID); - } - } - -# $translationdatafield.Add() - foreach($key in $translationdatafield.Keys) - { - if ([string]$IcingaCustomVariable -eq [string]$key) - { - $otherID = $translationdatafield[$IcingaCustomVariable]; - } else {} - } - # Get Necessary Syntax-Information and more through cmdlet "Get-Help" -# Write-Host $Data.Syntax.syntaxItem.Name -# Write-Host $Parameter.Name - # [int]$FieldID = [int]$FieldID + 1; - - $Basket.Command[$Data.Syntax.syntaxItem.Name].fields.Add( - [string]$FieldNumeration, @{ - 'datafield_id' = [int]$otherID; - 'is_required' = $Required; - 'var_filter' = $NULL; - } - ); - - [int]$FieldNumeration = [int]$FieldNumeration + 1; - } - } -} - - if ($CheckName.Count -eq 1) { - $FileName = "${CheckName}.json"; - } else { - $FileName = "Checks.json"; - } - - $output=ConvertTo-Json -D 100 $Basket > "$FileName"; - - $FilePath = (Get-Location).Path - - # Output-Text - Write-Host "The following commands have been exported:" - foreach ($check in $CheckName) { - if ($check -ne "Invoke-IcingaCheckCommandBasket") { - Write-Host "- '$check'" - } - } - Write-Host "JSON export created in '${FilePath}\${FileName}'" - - return $output; -} \ No newline at end of file From d7fdeba91564c40f484a8db9526bd5c166deac16 Mon Sep 17 00:00:00 2001 From: Crited Date: Fri, 13 Sep 2019 11:46:09 +0200 Subject: [PATCH 068/259] Moved Get-IcingaCheckCommandConfig.psm1 to intended directory --- lib/{plugins => core/tools}/Get-IcingaCheckCommandConfig.psm1 | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename lib/{plugins => core/tools}/Get-IcingaCheckCommandConfig.psm1 (100%) diff --git a/lib/plugins/Get-IcingaCheckCommandConfig.psm1 b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 similarity index 100% rename from lib/plugins/Get-IcingaCheckCommandConfig.psm1 rename to lib/core/tools/Get-IcingaCheckCommandConfig.psm1 From 95ea8cf28f107b3a89dca201696ad7415d496ee0 Mon Sep 17 00:00:00 2001 From: Crited Date: Fri, 13 Sep 2019 14:29:38 +0200 Subject: [PATCH 069/259] Changed Invoke-IcingaCheckService.psm1 to support multiple inputs --- lib/plugins/Invoke-IcingaCheckService.psm1 | 24 ++++++++++++++++++++-- 1 file changed, 22 insertions(+), 2 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckService.psm1 b/lib/plugins/Invoke-IcingaCheckService.psm1 index 86cc058..2d86bb1 100644 --- a/lib/plugins/Invoke-IcingaCheckService.psm1 +++ b/lib/plugins/Invoke-IcingaCheckService.psm1 @@ -5,10 +5,28 @@ Import-IcingaLib icinga\plugin; function Invoke-IcingaCheckService() { param( + [array]$Service, [string]$Status, - [string]$Service + [int]$Verbose ); + $ServicesPackage = New-IcingaCheckPackage -Name 'Services' -OperatorAnd -Verbose $Verbose; + + if ($Service.Count -ne 1) { + foreach ($services in $Service) { + $IcingaCheck = $null; + + $FoundService = Get-IcingaServices -Service $services; + $ServiceName = Get-IcingaServiceCheckName -ServiceInput $services -Service $FoundService; + $ConvertedStatus = ConvertTo-ServiceStatusCode -Status $Status; + $StatusRaw = $FoundService.Values.configuration.Status.raw; + + $IcingaCheck = New-IcingaCheck -Name $ServiceName -Value $StatusRaw -ObjectExists $FoundService -Translation $ProviderEnums.ServiceStatusName; + $IcingaCheck.CritIfNotMatch($ConvertedStatus) | Out-Null; + $ServicesPackage.AddCheck($IcingaCheck) + } + } else { + $FoundService = Get-IcingaServices -Service $Service; $ServiceName = Get-IcingaServiceCheckName -ServiceInput $Service -Service $FoundService; $Status = ConvertTo-ServiceStatusCode -Status $Status; @@ -16,6 +34,8 @@ function Invoke-IcingaCheckService() $IcingaCheck = New-IcingaCheck -Name $ServiceName -Value $StatusRaw -ObjectExists $FoundService -Translation $ProviderEnums.ServiceStatusName; $IcingaCheck.CritIfNotMatch($Status) | Out-Null; + $ServicesPackage.AddCheck($IcingaCheck); - exit (New-IcingaCheckResult -Check $IcingaCheck -NoPerfData $TRUE -Compile); + } + exit (New-IcingaCheckResult -Name 'Services' -Check $ServicesPackage -NoPerfData $TRUE -Compile); } From ac061edaac1b3b132ac9414c029700362c32d3f3 Mon Sep 17 00:00:00 2001 From: Crited Date: Fri, 13 Sep 2019 15:59:22 +0200 Subject: [PATCH 070/259] Used Icinga-DSL for array-arg splitting --- lib/core/tools/Get-IcingaCheckCommandConfig.psm1 | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 index 3b1f42a..2301c07 100644 --- a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 +++ b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 @@ -211,7 +211,16 @@ function Get-IcingaCheckCommandConfig() } elseif ($parameter.type.name -eq 'array') { $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( [string]::Format('-{0}', $parameter.Name), @{ - 'value' = [string]::Format('(Split-IcingaCheckCommandArgs {0})', $IcingaCustomVariable); + 'value' = @{ + 'type' = 'Function'; + 'body' = [string]::Format( + 'var arr = macro("{0}");{1}if (len(arr) == 0) {2}{1}return "$null";{1}{3}{1}return arr.join(",");', + $IcingaCustomVariable, + "`r`n", + '{', + '}' + ); + } 'order' = $Order; } ); From f5a757dc99214da714ec102eea12698689dbba5b Mon Sep 17 00:00:00 2001 From: Crited Date: Fri, 13 Sep 2019 15:59:45 +0200 Subject: [PATCH 071/259] Added Description for Invoke-IcingaCheckService --- lib/plugins/Invoke-IcingaCheckService.psm1 | 38 ++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/lib/plugins/Invoke-IcingaCheckService.psm1 b/lib/plugins/Invoke-IcingaCheckService.psm1 index 2d86bb1..c29d59e 100644 --- a/lib/plugins/Invoke-IcingaCheckService.psm1 +++ b/lib/plugins/Invoke-IcingaCheckService.psm1 @@ -2,6 +2,44 @@ Import-IcingaLib provider\services; Import-IcingaLib provider\enums; Import-IcingaLib icinga\plugin; +<# +.SYNOPSIS + Checks if a service has a specified status. + +.DESCRIPTION + Invoke-icingaCheckService returns either 'OK' or 'CRITICAL', if a service status is matching status to be checked. + + More Information on https://github.com/LordHepipud/icinga-module-windows + +.FUNCTIONALITY + This module is intended to be used to check whether one or more services have a certain status. + As soon as one of the specified services does not match the status, the function returns 'CRITICAL' instead of 'OK'. + +.EXAMPLE + PS>Invoke-IcingaCheckService -Service WiaRPC, Spooler -Status '1' -Verbose 3 + [CRITICAL]: Check package "Services" is [CRITICAL] (Match All) + \_ [OK]: Service "Ereignisse zum Abrufen von Standbildern (WiaRPC)" is Stopped + \_ [CRITICAL]: Service "Druckwarteschlange (Spooler)" Running is not matching Stopped + +.PARAMETER Service + Used to specify an array of services which should be checked against the status. + Seperated with ',' + +.PARAMETER Status + Status for the specified service or services to check against. + + .INPUTS + System.Array + + .OUTPUTS + System.String + + .LINK + https://github.com/LordHepipud/icinga-module-windows + + .NOTES +#> + function Invoke-IcingaCheckService() { param( From 0a99db36efaa30bfc7d386b779b59b52cc786037 Mon Sep 17 00:00:00 2001 From: Crited Date: Fri, 13 Sep 2019 16:01:46 +0200 Subject: [PATCH 072/259] Fixed Codestyling --- lib/core/tools/Get-IcingaCheckCommandConfig.psm1 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 index 2301c07..57697c6 100644 --- a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 +++ b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 @@ -214,12 +214,12 @@ function Get-IcingaCheckCommandConfig() 'value' = @{ 'type' = 'Function'; 'body' = [string]::Format( - 'var arr = macro("{0}");{1}if (len(arr) == 0) {2}{1}return "$null";{1}{3}{1}return arr.join(",");', - $IcingaCustomVariable, - "`r`n", - '{', - '}' - ); + 'var arr = macro("{0}");{1}if (len(arr) == 0) {2}{1}return "$null";{1}{3}{1}return arr.join(",");', + $IcingaCustomVariable, + "`r`n", + '{', + '}' + ); } 'order' = $Order; } From 81589fa91057e5b8c3b1ead5d3269c86be54f003 Mon Sep 17 00:00:00 2001 From: Crited Date: Fri, 13 Sep 2019 16:23:34 +0200 Subject: [PATCH 073/259] Added missing description for documented plugin arguments --- lib/core/tools/Get-IcingaCheckCommandConfig.psm1 | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 index 57697c6..aee83f6 100644 --- a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 +++ b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 @@ -281,7 +281,7 @@ function Get-IcingaCheckCommandConfig() '0', @{ 'varname' = 'PowerShell_switch_NoPerfData'; 'caption' = 'NoPerfData'; - 'description' = $NULL; + 'description' = 'Specifies if the plugin will return performance data output or not'; 'datatype' = 'Icinga\\Module\\Director\\DataType\\DataTypeDatalist'; 'format' = $NULL; 'originalId' = '0'; @@ -299,7 +299,7 @@ function Get-IcingaCheckCommandConfig() '1', @{ 'varname' = 'PowerShell_switch_NoPerfData'; 'caption' = 'Verbose'; - 'description' = $NULL; + 'description' = 'Specifies if the plugin will return performance data output or not'; 'datatype' = 'Icinga\\Module\\Director\\DataType\\DataTypeString'; 'format' = $NULL; 'originalId' = '1'; @@ -320,7 +320,7 @@ function Get-IcingaCheckCommandConfig() [string]$FieldID, @{ 'varname' = $IcingaCustomVariable; 'caption' = $parameter.Name; - 'description' = $NULL; + 'description' = $parameter.Description.Text; 'datatype' = $IcingaDataType; 'format' = $NULL; 'originalId' = [string]$FieldID; @@ -377,7 +377,7 @@ function Get-IcingaCheckCommandConfig() [string]$FieldID, @{ 'varname' = 'PowerShell_Object_Verbose'; 'caption' = 'Verbose'; - 'description' = $NULL; + 'description' = 'Increase the plugin output for more information on the received result.'; 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; 'format' = $NULL; 'originalId' = [string]$FieldID; @@ -407,7 +407,7 @@ function Get-IcingaCheckCommandConfig() [string]$FieldID, @{ 'varname' = 'PowerShell_switch_NoPerfData'; 'caption' = 'Perf Data'; - 'description' = $NULL; + 'description' = 'Specifies if the plugin will return performance data output or not'; 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; 'format' = $NULL; 'originalId' = [string]$FieldID; From 3f0721f7eb73ecaa3010f773782543515cac0009 Mon Sep 17 00:00:00 2001 From: Crited Date: Fri, 13 Sep 2019 16:24:30 +0200 Subject: [PATCH 074/259] Fixed codestyling --- lib/core/tools/Get-IcingaCheckCommandConfig.psm1 | 9 ++++----- lib/plugins/Invoke-IcingaCheckService.psm1 | 8 ++++---- 2 files changed, 8 insertions(+), 9 deletions(-) diff --git a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 index aee83f6..6ddf2d7 100644 --- a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 +++ b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 @@ -25,7 +25,6 @@ - 'Invoke-IcingaCheckUsers' ############################################################ - .EXAMPLE Get-IcingaCheckCommandConfig -OutFile 'C:\Users\icinga\config-exports' The following commands have been exported: @@ -50,16 +49,16 @@ Used to specify an array of commands which should be exported. Seperated with ',' - .INPUTS +.INPUTS System.Array - .OUTPUTS +.OUTPUTS System.String - .LINK +.LINK https://github.com/LordHepipud/icinga-module-windows - .NOTES +.NOTES #> function Get-IcingaCheckCommandConfig() diff --git a/lib/plugins/Invoke-IcingaCheckService.psm1 b/lib/plugins/Invoke-IcingaCheckService.psm1 index c29d59e..3b2c323 100644 --- a/lib/plugins/Invoke-IcingaCheckService.psm1 +++ b/lib/plugins/Invoke-IcingaCheckService.psm1 @@ -28,16 +28,16 @@ Import-IcingaLib icinga\plugin; .PARAMETER Status Status for the specified service or services to check against. - .INPUTS +.INPUTS System.Array - .OUTPUTS +.OUTPUTS System.String - .LINK +.LINK https://github.com/LordHepipud/icinga-module-windows - .NOTES +.NOTES #> function Invoke-IcingaCheckService() From a33455f343ee22172fec4ed1d575a7449358d5b9 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Fri, 13 Sep 2019 17:04:05 +0200 Subject: [PATCH 075/259] Fixed update list throwing unknown for 0 pending updates --- lib/plugins/Invoke-IcingaCheckUpdates.psm1 | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/lib/plugins/Invoke-IcingaCheckUpdates.psm1 b/lib/plugins/Invoke-IcingaCheckUpdates.psm1 index 7fd3cf4..4b2fbc4 100644 --- a/lib/plugins/Invoke-IcingaCheckUpdates.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUpdates.psm1 @@ -47,8 +47,12 @@ function Invoke-IcingaCheckUpdates() $UpdateCount.AddCheck($IcingaCheck); $UpdatePackage = New-IcingaCheckPackage -Name 'Updates' -OperatorAnd -Verbose $Verbose -Checks @( - $UpdateCount, $UpdateList + $UpdateCount ); + if ($PendingCount -ne 0) { + $UpdatePackage.AddCheck($UpdateList); + } + exit (New-IcingaCheckResult -Name 'Pending Updates' -Check $UpdatePackage -NoPerfData $NoPerfData -Compile); } From b34f539d01137dfc3e70e2b421b54bfc0512e9b4 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Fri, 13 Sep 2019 19:04:27 +0200 Subject: [PATCH 076/259] Added first draft for permission exception handling --- .../Exit-IcingaMissingPermission.psm1 | 36 +++++++++++++++++++ .../Icinga_IcingaExceptionEnums.psm1 | 22 ++++++++++++ lib/plugins/Invoke-IcingaCheckCPU.psm1 | 3 ++ 3 files changed, 61 insertions(+) create mode 100644 lib/icinga/exception/Exit-IcingaMissingPermission.psm1 create mode 100644 lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 diff --git a/lib/icinga/exception/Exit-IcingaMissingPermission.psm1 b/lib/icinga/exception/Exit-IcingaMissingPermission.psm1 new file mode 100644 index 0000000..bf1a066 --- /dev/null +++ b/lib/icinga/exception/Exit-IcingaMissingPermission.psm1 @@ -0,0 +1,36 @@ +Import-IcingaLib icinga\enums; +Import-IcingaLib icinga\exception; + +function Exit-IcingaMissingPermission() +{ + param( + [string]$Input, + [string]$StringPattern, + [string]$CustomMessage, + [string]$ExeptionType + ); + + if ($null -eq $Input -Or [string]::IsNullOrEmpty($Input)) { + return; + } + + if (-Not $Input.Contains($StringPattern)) { + return; + } + + $OutputMessage = '{0}: Icinga Permission Error was thrown: {3}{1}{1}{2}'; + if ([string]::IsNullOrEmpty($CustomMessage) -eq $TRUE) { + $OutputMessage = '{0}: Icinga Permission Error was thrown {1}{1}{2}{3}'; + } + + $OutputMessage = [string]::Format( + $OutputMessage, + $IcingaEnums.IcingaExitCodeText.($IcingaEnums.IcingaExitCode.Unknown), + "`r`n", + $ExeptionType, + $CustomMessage + ); + + Write-Host $OutputMessage; + exit $IcingaEnums.IcingaExitCode.Unknown; +} diff --git a/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 b/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 new file mode 100644 index 0000000..8e87c40 --- /dev/null +++ b/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 @@ -0,0 +1,22 @@ +<# + # This script will provide 'Enums' we can use within our module to + # easier access constants and to maintain a better overview of the + # entire components + #> + + [hashtable]$Throw = @{ + PerformanceCounter = 'Icinga failed to fetch Performance Counter information. This may be caused when the Icinga Service User is not permited to access these information. To fix this, please add the User the Icinga Agent is running on into the "Performance Log Users" group.'; +}; + +<# + # Once we defined a new enum hashtable above, simply add it to this list + # to make it available within the entire module. + # + # Example usage: + # $IcingaExceptionEnums.IcingaExecptionHandlers.PerformanceCounter + #> +[hashtable]$IcingaExceptions = @{ + Throw = $Throw; +} + +Export-ModuleMember -Variable @( 'IcingaExceptions' ); diff --git a/lib/plugins/Invoke-IcingaCheckCPU.psm1 b/lib/plugins/Invoke-IcingaCheckCPU.psm1 index 0df4075..33f4191 100644 --- a/lib/plugins/Invoke-IcingaCheckCPU.psm1 +++ b/lib/plugins/Invoke-IcingaCheckCPU.psm1 @@ -1,5 +1,6 @@ Import-IcingaLib core\perfcounter; Import-IcingaLib icinga\plugin; +Import-IcingaLib icinga\exception; function Invoke-IcingaCheckCPU() { @@ -14,6 +15,8 @@ function Invoke-IcingaCheckCPU() $CpuCounter = New-IcingaPerformanceCounter -Counter ([string]::Format('\Processor({0})\% processor time', $Core)); $CpuPackage = New-IcingaCheckPackage -Name 'CPU Load' -OperatorAnd -Verbos $Verbose; + Exit-IcingaMissingPermission -Input $CpuCounter.ErrorMessage -StringPattern '"Global"' -ExeptionType $IcingaExceptions.Throw.PerformanceCounter; + if ($CpuCounter.Counters.Count -ne 0) { foreach ($counter in $CpuCounter.Counters) { $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core #{0}', $counter.Instance)) -Value $counter.Value().Value -Unit '%'; From 580b99b4443c3c31218c8b38faa2b0160d6674e4 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Fri, 13 Sep 2019 19:16:19 +0200 Subject: [PATCH 077/259] Fixed arguments to properly work on all Windows environments --- lib/icinga/exception/Exit-IcingaMissingPermission.psm1 | 6 +++--- lib/plugins/Invoke-IcingaCheckCPU.psm1 | 2 +- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/lib/icinga/exception/Exit-IcingaMissingPermission.psm1 b/lib/icinga/exception/Exit-IcingaMissingPermission.psm1 index bf1a066..425f984 100644 --- a/lib/icinga/exception/Exit-IcingaMissingPermission.psm1 +++ b/lib/icinga/exception/Exit-IcingaMissingPermission.psm1 @@ -4,17 +4,17 @@ Import-IcingaLib icinga\exception; function Exit-IcingaMissingPermission() { param( - [string]$Input, + [string]$InputString, [string]$StringPattern, [string]$CustomMessage, [string]$ExeptionType ); - if ($null -eq $Input -Or [string]::IsNullOrEmpty($Input)) { + if ($null -eq $InputString -Or [string]::IsNullOrEmpty($InputString)) { return; } - if (-Not $Input.Contains($StringPattern)) { + if (-Not $InputString.Contains($StringPattern)) { return; } diff --git a/lib/plugins/Invoke-IcingaCheckCPU.psm1 b/lib/plugins/Invoke-IcingaCheckCPU.psm1 index 33f4191..defd00b 100644 --- a/lib/plugins/Invoke-IcingaCheckCPU.psm1 +++ b/lib/plugins/Invoke-IcingaCheckCPU.psm1 @@ -15,7 +15,7 @@ function Invoke-IcingaCheckCPU() $CpuCounter = New-IcingaPerformanceCounter -Counter ([string]::Format('\Processor({0})\% processor time', $Core)); $CpuPackage = New-IcingaCheckPackage -Name 'CPU Load' -OperatorAnd -Verbos $Verbose; - Exit-IcingaMissingPermission -Input $CpuCounter.ErrorMessage -StringPattern '"Global"' -ExeptionType $IcingaExceptions.Throw.PerformanceCounter; + Exit-IcingaMissingPermission -InputString $CpuCounter.ErrorMessage -StringPattern '"Global"' -ExeptionType $IcingaExceptions.Throw.PerformanceCounter; if ($CpuCounter.Counters.Count -ne 0) { foreach ($counter in $CpuCounter.Counters) { From d1b30c77ae7ada66c3a71d66c4c690a79a51d2d6 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Fri, 13 Sep 2019 20:44:15 +0200 Subject: [PATCH 078/259] Fixed and improved Perf Data handling * Added proper sorting for checks, packages and check results by name * Fixed perf data formating to be supported by Icinga 2 * Fixed label naming by removing all invalid characters * Fixed displaying of values by rounding to 2 digits on floats --- .../tools/Format-IcingaPerfDataLabel.psm1 | 9 ++++ .../tools/Format-IcingaPerfDataValue.psm1 | 14 ++++++ lib/icinga/plugin/New-IcingaCheck.psm1 | 30 ++++++----- lib/icinga/plugin/New-IcingaCheckPackage.psm1 | 50 ++++++++++++++++--- lib/icinga/plugin/New-IcingaCheckResult.psm1 | 2 +- 5 files changed, 86 insertions(+), 19 deletions(-) create mode 100644 lib/core/tools/Format-IcingaPerfDataLabel.psm1 create mode 100644 lib/core/tools/Format-IcingaPerfDataValue.psm1 diff --git a/lib/core/tools/Format-IcingaPerfDataLabel.psm1 b/lib/core/tools/Format-IcingaPerfDataLabel.psm1 new file mode 100644 index 0000000..d28aaf1 --- /dev/null +++ b/lib/core/tools/Format-IcingaPerfDataLabel.psm1 @@ -0,0 +1,9 @@ +function Format-IcingaPerfDataLabel() +{ + param( + $PerfData + ); + + # Remove all special characters and spaces on label names + return ((($PerfData) -Replace ' ', '_') -Replace '[\W]', ''); +} diff --git a/lib/core/tools/Format-IcingaPerfDataValue.psm1 b/lib/core/tools/Format-IcingaPerfDataValue.psm1 new file mode 100644 index 0000000..b91966a --- /dev/null +++ b/lib/core/tools/Format-IcingaPerfDataValue.psm1 @@ -0,0 +1,14 @@ +function Format-IcingaPerfDataValue() +{ + param( + $PerfValue + ); + + if ((Test-Numeric $PerfValue) -eq $FALSE) { + return $PerfValue; + } + + # Convert our value to a string and replace ',' with a '.' to allow Icinga to parse the output + # In addition, round every output to 2 digits + return (([string]([math]::round($PerfValue, 2))).Replace(',', '.')); +} diff --git a/lib/icinga/plugin/New-IcingaCheck.psm1 b/lib/icinga/plugin/New-IcingaCheck.psm1 index 09a1155..590ca32 100644 --- a/lib/icinga/plugin/New-IcingaCheck.psm1 +++ b/lib/icinga/plugin/New-IcingaCheck.psm1 @@ -408,6 +408,8 @@ function New-IcingaCheck() $Check | Add-Member -membertype ScriptMethod -name 'TranslateValue' -value { param($value); + $value = Format-IcingaPerfDataValue $value; + if ($null -eq $this.translation -Or $null -eq $value) { return $value; } @@ -633,7 +635,7 @@ function New-IcingaCheck() $Check | Add-Member -membertype ScriptMethod -name 'GetPerfData' -value { if ($this.completed -Or -Not $this.perfdata) { - return ''; + return $null; } $this.AutodiscoverMinMax(); @@ -645,18 +647,22 @@ function New-IcingaCheck() $this.maximum = [string]::Format(';{0}', $this.maximum); } - $this.completed = $TRUE; + $this.completed = $TRUE; + [string]$LabelName = (Format-IcingaPerfDataLabel $this.name); - return [string]::Format( - "'{0}'={1}{2};{3};{4}{5}{6} ", - $this.name, - $this.value, - $this.unit, - $this.warning, - $this.critical, - $this.minimum, - $this.maximum - ); + return @{ + 'label' = $LabelName; + 'perfdata' = [string]::Format( + "'{0}'={1}{2};{3};{4}{5}{6} ", + $LabelName, + (Format-IcingaPerfDataValue $this.value), + $this.unit, + (Format-IcingaPerfDataValue $this.warning), + (Format-IcingaPerfDataValue $this.critical), + (Format-IcingaPerfDataValue $this.minimum), + (Format-IcingaPerfDataValue $this.maximum) + ); + }; } $Check | Add-Member -membertype ScriptMethod -name 'AutodiscoverMinMax' -value { diff --git a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 index 9c8ab0d..01204e9 100644 --- a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 +++ b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 @@ -207,8 +207,15 @@ function New-IcingaCheckPackage() } $Check | Add-Member -membertype ScriptMethod -name 'WriteAllOutput' -value { + [hashtable]$MessageOrdering = @{}; foreach ($check in $this.checks) { - $check.PrintAllMessages(); + $MessageOrdering.Add($check.name, $check); + } + + $SortedArray = $MessageOrdering.GetEnumerator() | Sort-Object name; + + foreach ($entry in $SortedArray) { + $entry.Value.PrintAllMessages(); } } @@ -218,11 +225,18 @@ function New-IcingaCheckPackage() } $Check | Add-Member -membertype ScriptMethod -name 'WriteCheckErrors' -value { + [hashtable]$MessageOrdering = @{}; foreach ($check in $this.checks) { if ([int]$check.exitcode -ne $IcingaEnums.IcingaExitCode.Ok) { - $check.PrintOutputMessages(); + $MessageOrdering.Add($check.name, $check); } } + + $SortedArray = $MessageOrdering.GetEnumerator() | Sort-Object name; + + foreach ($entry in $SortedArray) { + $entry.Value.PrintAllMessages(); + } } $Check | Add-Member -membertype ScriptMethod -name 'PrintNoChecksConfigured' -value { @@ -299,12 +313,36 @@ function New-IcingaCheckPackage() } $Check | Add-Member -membertype ScriptMethod -name 'GetPerfData' -value { - [string]$perfData = ''; + [string]$perfData = ''; + [hashtable]$CollectedPerfData = @{}; + + # At first lets collect all perf data, but ensure we only add possible label duplication only once foreach ($check in $this.checks) { - $perfData += $check.GetPerfData(); + $data = $check.GetPerfData(); + + if ($null -eq $data -Or $null -eq $data.label) { + continue; + } + + if ($CollectedPerfData.ContainsKey($data.label)) { + continue; + } + + $CollectedPerfData.Add($data.label, $data.perfdata); + } + + # Now sort the label output by name + $SortedArray = $CollectedPerfData.GetEnumerator() | Sort-Object name; + + # Buold the performance data output based on the sorted result + foreach ($entry in $SortedArray) { + $perfData += $entry.Value; + } + + return @{ + 'label' = $this.name; + 'perfdata' = $perfData; } - - return $perfData; } $Check.Initialise(); diff --git a/lib/icinga/plugin/New-IcingaCheckResult.psm1 b/lib/icinga/plugin/New-IcingaCheckResult.psm1 index b7b07c6..5e07112 100644 --- a/lib/icinga/plugin/New-IcingaCheckResult.psm1 +++ b/lib/icinga/plugin/New-IcingaCheckResult.psm1 @@ -21,7 +21,7 @@ function New-IcingaCheckresult() $this.check.Compile($TRUE) | Out-Null; if ([int]$this.check.exitcode -ne [int]$IcingaEnums.IcingaExitCode.Unknown -And -Not $this.noperfdata) { - Write-Host ([string]::Format('| {0}', $this.check.GetPerfData())); + Write-Host ([string]::Format('| {0}', $this.check.GetPerfData().perfdata)); } return $this.check.exitcode; From cf158dd3e8d4b198f68d6bb539c6b65b68092aa3 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 14 Sep 2019 16:12:24 +0200 Subject: [PATCH 079/259] Improved exception handling on a more global state --- .../New-IcingaPerformanceCounter.psm1 | 7 +- .../Exit-IcingaMissingPermission.psm1 | 36 ---------- .../exception/Exit-IcingaThrowException.psm1 | 72 +++++++++++++++++++ lib/plugins/Invoke-IcingaCheckCPU.psm1 | 3 - 4 files changed, 78 insertions(+), 40 deletions(-) delete mode 100644 lib/icinga/exception/Exit-IcingaMissingPermission.psm1 create mode 100644 lib/icinga/exception/Exit-IcingaThrowException.psm1 diff --git a/lib/core/perfcounter/New-IcingaPerformanceCounter.psm1 b/lib/core/perfcounter/New-IcingaPerformanceCounter.psm1 index 83bebfe..ac50711 100644 --- a/lib/core/perfcounter/New-IcingaPerformanceCounter.psm1 +++ b/lib/core/perfcounter/New-IcingaPerformanceCounter.psm1 @@ -71,7 +71,12 @@ $AllCountersIntances += $NewCounter; } } catch { - return (New-IcingaPerformanceCounterNullObject -FullName $Counter -ErrorMessage ([string]::Format('Failed to deserialize instances for counter "{0}". Exception: "{1}".', $Counter, $_.Exception.Message))); + # Throw an exception in case our permissions are not enough to fetch performance counter + Exit-IcingaThrowException -InputString $_.Exception -StringPattern 'System.UnauthorizedAccessException' -ExceptionType 'Permission' -ExceptionThrown $IcingaExceptions.Permission.PerformanceCounter; + Exit-IcingaThrowException -InputString $_.Exception -StringPattern 'System.InvalidOperationException' -ExceptionType 'Input' -CustomMessage $Counter -ExceptionThrown $IcingaExceptions.Inputs.PerformanceCounter; + Exit-IcingaThrowException -InputString $_.Exception -StringPattern '' -ExceptionType 'Unhandled'; + # Shouldn't actually get down here anyways + return (New-IcingaPerformanceCounterNullObject -FullName $Counter -ErrorMessage ([string]::Format('Failed to deserialize instances for counter "{0}". Exception: "{1}".', $Counter, $_.Exception.Message))); } # If we load multiple instances, we should add a global wait here instead of a wait for each single instance diff --git a/lib/icinga/exception/Exit-IcingaMissingPermission.psm1 b/lib/icinga/exception/Exit-IcingaMissingPermission.psm1 deleted file mode 100644 index 425f984..0000000 --- a/lib/icinga/exception/Exit-IcingaMissingPermission.psm1 +++ /dev/null @@ -1,36 +0,0 @@ -Import-IcingaLib icinga\enums; -Import-IcingaLib icinga\exception; - -function Exit-IcingaMissingPermission() -{ - param( - [string]$InputString, - [string]$StringPattern, - [string]$CustomMessage, - [string]$ExeptionType - ); - - if ($null -eq $InputString -Or [string]::IsNullOrEmpty($InputString)) { - return; - } - - if (-Not $InputString.Contains($StringPattern)) { - return; - } - - $OutputMessage = '{0}: Icinga Permission Error was thrown: {3}{1}{1}{2}'; - if ([string]::IsNullOrEmpty($CustomMessage) -eq $TRUE) { - $OutputMessage = '{0}: Icinga Permission Error was thrown {1}{1}{2}{3}'; - } - - $OutputMessage = [string]::Format( - $OutputMessage, - $IcingaEnums.IcingaExitCodeText.($IcingaEnums.IcingaExitCode.Unknown), - "`r`n", - $ExeptionType, - $CustomMessage - ); - - Write-Host $OutputMessage; - exit $IcingaEnums.IcingaExitCode.Unknown; -} diff --git a/lib/icinga/exception/Exit-IcingaThrowException.psm1 b/lib/icinga/exception/Exit-IcingaThrowException.psm1 new file mode 100644 index 0000000..d4610ee --- /dev/null +++ b/lib/icinga/exception/Exit-IcingaThrowException.psm1 @@ -0,0 +1,72 @@ +function Exit-IcingaThrowException() +{ + param( + [string]$InputString, + [string]$StringPattern, + [string]$CustomMessage, + [string]$ExceptionThrown, + [ValidateSet('Permission','Input','Unhandled')] + [string]$ExceptionType = 'Unhandled' + ); + + if ($null -eq $InputString -Or [string]::IsNullOrEmpty($InputString)) { + return; + } + + if (-Not $InputString.Contains($StringPattern)) { + return; + } + + $ExceptionMessageLib = $null; + $ExceptionTypeString = ''; + + switch ($ExceptionType) { + 'Permission' { + $ExceptionTypeString = 'Permission'; + $ExceptionMessageLib = $IcingaExceptions.Permission; + }; + 'Input' { + $ExceptionTypeString = 'Invalid Input'; + $ExceptionMessageLib = $IcingaExceptions.Inputs; + }; + 'Unhandled' { + $ExceptionTypeString = 'Unhandled'; + }; + } + + [string]$ExceptionName = ''; + + if ($null -ne $ExceptionMessageLib) { + foreach ($definedError in $ExceptionMessageLib.Keys) { + if ($ExceptionMessageLib.$definedError -eq $ExceptionThrown) { + $ExceptionName = $definedError; + break; + } + } + } else { + $ExceptionName = 'Unhandled Exception'; + $ExceptionThrown = [string]::Format( + 'Unhandled exception occured:{0}{1}', + "`r`n", + $InputString + ); + } + + $OutputMessage = '{0}: Icinga {5} Error was thrown: {3}: {4}{1}{1}{2}'; + if ([string]::IsNullOrEmpty($CustomMessage) -eq $TRUE) { + $OutputMessage = '{0}: Icinga {5} Error was thrown: {3}{1}{1}{2}{4}'; + } + + $OutputMessage = [string]::Format( + $OutputMessage, + $IcingaEnums.IcingaExitCodeText.($IcingaEnums.IcingaExitCode.Unknown), + "`r`n", + $ExceptionThrown, + $ExceptionName, + $CustomMessage, + $ExceptionTypeString + ); + + Write-Host $OutputMessage; + exit $IcingaEnums.IcingaExitCode.Unknown; +} diff --git a/lib/plugins/Invoke-IcingaCheckCPU.psm1 b/lib/plugins/Invoke-IcingaCheckCPU.psm1 index defd00b..0df4075 100644 --- a/lib/plugins/Invoke-IcingaCheckCPU.psm1 +++ b/lib/plugins/Invoke-IcingaCheckCPU.psm1 @@ -1,6 +1,5 @@ Import-IcingaLib core\perfcounter; Import-IcingaLib icinga\plugin; -Import-IcingaLib icinga\exception; function Invoke-IcingaCheckCPU() { @@ -15,8 +14,6 @@ function Invoke-IcingaCheckCPU() $CpuCounter = New-IcingaPerformanceCounter -Counter ([string]::Format('\Processor({0})\% processor time', $Core)); $CpuPackage = New-IcingaCheckPackage -Name 'CPU Load' -OperatorAnd -Verbos $Verbose; - Exit-IcingaMissingPermission -InputString $CpuCounter.ErrorMessage -StringPattern '"Global"' -ExeptionType $IcingaExceptions.Throw.PerformanceCounter; - if ($CpuCounter.Counters.Count -ne 0) { foreach ($counter in $CpuCounter.Counters) { $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core #{0}', $counter.Instance)) -Value $counter.Value().Value -Unit '%'; From 5fa812a7a17ef42cc6773a97b03eed7185eed03f Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 14 Sep 2019 16:12:59 +0200 Subject: [PATCH 080/259] Added missing exception definitions --- lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 b/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 index 8e87c40..553e172 100644 --- a/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 +++ b/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 @@ -4,8 +4,12 @@ # entire components #> - [hashtable]$Throw = @{ - PerformanceCounter = 'Icinga failed to fetch Performance Counter information. This may be caused when the Icinga Service User is not permited to access these information. To fix this, please add the User the Icinga Agent is running on into the "Performance Log Users" group.'; +[hashtable]$Permission = @{ + PerformanceCounter = 'A Plugin failed to fetch Performance Counter information. This may be caused when the used Service User is not permitted to access these information. To fix this, please add the User the Icinga Agent is running on into the "Performance Log Users" group.'; +}; + +[hashtable]$Inputs = @{ + PerformanceCounter = 'A plugin failed to fetch Performance Counter information. Please ensure the counter is written properly and available on your system.'; }; <# @@ -16,7 +20,8 @@ # $IcingaExceptionEnums.IcingaExecptionHandlers.PerformanceCounter #> [hashtable]$IcingaExceptions = @{ - Throw = $Throw; + Permission = $Permission; + Inputs = $Inputs; } Export-ModuleMember -Variable @( 'IcingaExceptions' ); From bee9b0a1c1ddb7900d48586327c8f5574c051367 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 14 Sep 2019 16:14:24 +0200 Subject: [PATCH 081/259] Added first draft to create new CheckCommands over CLI --- lib/core/tools/New-IcingaCheckCommand.psm1 | 93 ++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 lib/core/tools/New-IcingaCheckCommand.psm1 diff --git a/lib/core/tools/New-IcingaCheckCommand.psm1 b/lib/core/tools/New-IcingaCheckCommand.psm1 new file mode 100644 index 0000000..3f4070d --- /dev/null +++ b/lib/core/tools/New-IcingaCheckCommand.psm1 @@ -0,0 +1,93 @@ +function New-IcingaCheckCommand() +{ + param( + [string]$Name = '', + [array]$Arguments = @( + 'Warning', + 'Critical', + '[switch]NoPerfData', + 'Verbose' + ), + [array]$ImportLib = @() + ); + + if ([string]::IsNullOrEmpty($Name) -eq $TRUE) { + throw 'Please specify a command name'; + } + + if ($Name -match 'Invoke' -or $Name -match 'IcingaCheck') { + throw 'Please specify a command name only without PowerShell Cmdlet naming'; + } + + [string]$CommandName = [string]::Format( + 'Invoke-IcingaCheck{0}', + (Get-Culture).TextInfo.ToTitleCase($Name.ToLower()) + ); + + [string]$CommandFile = [string]::Format( + '{0}.psm1', + $CommandName + ); + + [string]$ScriptFile = Join-Path -Path (Get-IcingaPluginDir) -ChildPath $CommandFile; + + if ((Test-Path $ScriptFile) -eq $TRUE) { + throw 'This Check-Command does already exist.'; + } + + Add-Content -Path $ScriptFile -Value 'Import-IcingaLib icinga\plugin;'; + + foreach ($Library in $ImportLib) { + Add-Content -Path $ScriptFile -Value "Import-IcingaLib $Library;"; + } + + Add-Content -Path $ScriptFile -Value ''; + Add-Content -Path $ScriptFile -Value "function $CommandName()"; + Add-Content -Path $ScriptFile -Value "{"; + + if ($Arguments.Count -ne 0) { + Add-Content -Path $ScriptFile -Value " param("; + [int]$index = $Arguments.Count - 1; + foreach ($argument in $Arguments) { + + if ($argument.Contains('$') -eq $FALSE) { + if ($argument.Contains(']') -eq $TRUE) { + $splittedArguments = $argument.Split(']'); + $argument = [string]::Format('{0}]${1}', $splittedArguments[0], $splittedArguments[1]); + } else { + $argument = [string]::Format('${0}', $argument); + } + } + + if ($index -ne 0) { + [string]$content = [string]::Format('{0},', $argument); + } else { + [string]$content = [string]::Format('{0}', $argument); + } + Add-Content -Path $ScriptFile -Value " $content"; + + $index -= 1; + } + Add-Content -Path $ScriptFile -Value " );"; + } + + Add-Content -Path $ScriptFile -Value ""; + Add-Content -Path $ScriptFile -Value "}"; + + Write-Host ([string]::Format('The Check-Command "{0}" was successfully added.', $CommandName)); + + # Try to open the default Editor for the new Cmdlet + $DefaultEditor = (Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.psm1\OpenWithList' -Name a).a; + #$DefaultEditor = $DefaultEditor.Replace('.exe', ''); + + Write-Host ([string]::IsNullOrEmpty($DefaultEditor)); + Write-Host ((Get-Command $DefaultEditor -ErrorAction SilentlyContinue)); + Write-Host ((Test-Path $DefaultEditor)); + + if ([string]::IsNullOrEmpty($DefaultEditor) -eq $FALSE -And ((Get-Command $DefaultEditor -ErrorAction SilentlyContinue) -eq $null) -And ((Test-Path $DefaultEditor) -eq $FALSE)) { + Write-Host 'No default editor for .psm1 files found. Specify a default editor to automaticly open the newly generated check plugin.'; + return; + } + + & $DefaultEditor "$ScriptFile"; +} From 02ca9367c443ae9c8d4b0dd61a2e1d508ef8a751 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 16 Sep 2019 11:27:09 +0200 Subject: [PATCH 082/259] Added note to restart service for permission changes --- lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 b/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 index 553e172..21fb5d6 100644 --- a/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 +++ b/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 @@ -5,7 +5,7 @@ #> [hashtable]$Permission = @{ - PerformanceCounter = 'A Plugin failed to fetch Performance Counter information. This may be caused when the used Service User is not permitted to access these information. To fix this, please add the User the Icinga Agent is running on into the "Performance Log Users" group.'; + PerformanceCounter = 'A Plugin failed to fetch Performance Counter information. This may be caused when the used Service User is not permitted to access these information. To fix this, please add the User the Icinga Agent is running on into the "Performance Log Users" group and restart the service.'; }; [hashtable]$Inputs = @{ From 865c94fc6cd6b348d04779564c202cad5ea6f9c9 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 16 Sep 2019 12:02:38 +0200 Subject: [PATCH 083/259] Fixed invalid entry_value key name --- lib/core/tools/Get-IcingaCheckCommandConfig.psm1 | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 index 6ddf2d7..1918a27 100644 --- a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 +++ b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 @@ -95,13 +95,13 @@ function Get-IcingaCheckCommandConfig() 'entries' = @( @{ 'entry_name' = '0'; - 'entry_value:' = "yes"; + 'entry_value' = "yes"; 'format' = 'string'; 'allowed_roles' = $NULL; }, @{ 'entry_name' = '1'; - 'entry_value:' = "no"; + 'entry_value' = "no"; 'format' = 'string'; 'allowed_roles' = $NULL; } @@ -120,25 +120,25 @@ function Get-IcingaCheckCommandConfig() 'entries' = @( @{ 'entry_name' = '0'; - 'entry_value:' = "Show Default"; + 'entry_value' = "Show Default"; 'format' = 'string'; 'allowed_roles' = $NULL; }, @{ 'entry_name' = '1'; - 'entry_value:' = "Show Operator"; + 'entry_value' = "Show Operator"; 'format' = 'string'; 'allowed_roles' = $NULL; }, @{ 'entry_name' = '2'; - 'entry_value:' = "Show Problems"; + 'entry_value' = "Show Problems"; 'format' = 'string'; 'allowed_roles' = $NULL; }, @{ 'entry_name' = '3'; - 'entry_value:' = "Show All"; + 'entry_value' = "Show All"; 'format' = 'string'; 'allowed_roles' = $NULL; } From ef736beca6f2b780b6e1eccf381607d1c0702ffe Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 16 Sep 2019 12:06:05 +0200 Subject: [PATCH 084/259] Fixed methods_execute variable naming --- lib/core/tools/Get-IcingaCheckCommandConfig.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 index 1918a27..0d2743f 100644 --- a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 +++ b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 @@ -170,7 +170,7 @@ function Get-IcingaCheckCommandConfig() 'fields' = @{}; 'imports' = @(); 'is_string' = $NULL; - 'methods_excute' = 'PluginCheck'; + 'methods_execute' = 'PluginCheck'; 'object_name' = $Data.Syntax.syntaxItem.Name; 'object_type' = 'object'; 'timeout' = '180'; From f7a80cc477b15817e33e26ed54c7e9bf8f8e5383 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 16 Sep 2019 15:33:57 +0200 Subject: [PATCH 085/259] Improved Check-Command Config generation * Switch arguments will now use boolean data types in Director * Fixed an issue for Check Commands with integrated help, as arguments were not rendered properly * Fixed an issue on datafield ID lookup and assigning * Fixed an issue with assigning default values --- .../tools/Get-IcingaCheckCommandConfig.psm1 | 167 +++++------------- 1 file changed, 45 insertions(+), 122 deletions(-) diff --git a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 index 0d2743f..0853fce 100644 --- a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 +++ b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 @@ -82,34 +82,6 @@ function Get-IcingaCheckCommandConfig() $Basket.Add('DataList', @{}); $Basket.Add('Command', @{}); - - # "NoPerfData" gets added to all checks build and exported no matter what, so we add it from the start - if ($Basket.DataList.ContainsKey('PowerShell NoPerfData') -eq $FALSE) { - - # DataList Content for NoPerfData - $Basket.DataList.Add( - 'PowerShell NoPerfData', @{ - 'list_name' = 'PowerShell NoPerfData'; - 'owner' = $env:username; - 'originalId' = '1'; - 'entries' = @( - @{ - 'entry_name' = '0'; - 'entry_value' = "yes"; - 'format' = 'string'; - 'allowed_roles' = $NULL; - }, - @{ - 'entry_name' = '1'; - 'entry_value' = "no"; - 'format' = 'string'; - 'allowed_roles' = $NULL; - } - ); - } - ); - } - # "Verbose" gets added to all Checks build and exported no matter what, so we add it from the start if ($Basket.DataList.ContainsKey('PowerShell Verbose') -eq $FALSE) { $Basket.DataList.Add( @@ -149,29 +121,27 @@ function Get-IcingaCheckCommandConfig() # Loop through ${CheckName}, to get information on every command specified/all commands. foreach ($check in $CheckName) { - - [int]$FieldNumeration = 0; # Get necessary syntax-information and more through cmdlet "Get-Help" $Data = (Get-Help $check) # Add command Structure $Basket.Command.Add( - $Data.Syntax.syntaxItem.Name, @{ + $Data.Name, @{ 'arguments'= @{ # Gets set for every command as default '-C' = @{ - 'value' = [string]::Format('Use-Icinga; {0}', $Data.Syntax.syntaxItem.Name); + 'value' = [string]::Format('Use-Icinga; {0}', $Data.Name); 'order' = '0'; } } 'command' = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"; 'disabled' = $FALSE; - 'fields' = @{}; + 'fields' = @(); 'imports' = @(); 'is_string' = $NULL; 'methods_execute' = 'PluginCheck'; - 'object_name' = $Data.Syntax.syntaxItem.Name; + 'object_name' = $Data.Name; 'object_type' = 'object'; 'timeout' = '180'; 'vars' = @{}; @@ -180,7 +150,7 @@ function Get-IcingaCheckCommandConfig() ); # Loop through parameters of a given command - foreach ($parameter in $Data.Syntax.syntaxItem.parameter) { + foreach ($parameter in $Data.parameters.parameter) { # Filter for Parameter 'core', because its set by default if ($parameter.name -ne 'core') { @@ -196,19 +166,19 @@ function Get-IcingaCheckCommandConfig() # Add arguments to a given command if ($parameter.type.name -eq 'switch') { - $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( + $Basket.Command[$Data.Name].arguments.Add( [string]::Format('-{0}', $parameter.Name), @{ 'set_if' = $IcingaCustomVariable; 'set_if_format' = 'string'; 'order' = $Order; } ); - - $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add($parameter.Name, "0"); + + $Basket.Command[$Data.Name].vars.Add($parameter.Name, $FALSE); # Conditional whether type of parameter is array } elseif ($parameter.type.name -eq 'array') { - $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( + $Basket.Command[$Data.Name].arguments.Add( [string]::Format('-{0}', $parameter.Name), @{ 'value' = @{ 'type' = 'Function'; @@ -224,8 +194,8 @@ function Get-IcingaCheckCommandConfig() } ); } else { - # Default to Object - $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( + # Default to Object + $Basket.Command[$Data.Name].arguments.Add( [string]::Format('-{0}', $parameter.Name), @{ 'value' = $IcingaCustomVariable; 'order' = $Order; @@ -233,9 +203,9 @@ function Get-IcingaCheckCommandConfig() ); if ($parameter.name -ne 'Verbose') { - $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add($parameter.Name, '$$null'); + $Basket.Command[$Data.Name].vars.Add($parameter.Name, '$$null'); } else { - $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add($parameter.Name, "0"); + $Basket.Command[$Data.Name].vars.Add($parameter.Name, ""); } } @@ -249,19 +219,9 @@ function Get-IcingaCheckCommandConfig() $IcingaCustomVariable = [string]::Format('PowerShell_{0}_{1}', $parameter.type.name, $parameter.Name); $DataListName = [string]::Format('PowerShell {0}', $parameter.Name) - + if ($parameter.type.name -eq 'switch') { - $IcingaDataType='Datalist'; - if ($Basket.DataList.ContainsKey($DataListName) -eq $FALSE) { - $Basket.DataList.Add( - $DataListName, @{ - 'list_name' = $DataListName; - 'owner' = $env:username; - 'originalId' = '50'; #Gehört noch geändert - 'entries' = @{}; - } - ); - } + $IcingaDataType='Boolean'; } elseif ($parameter.type.name -eq 'Object') { if ($parameter.Name -eq 'Verbose') { $IcingaDataType='Datalist' @@ -279,16 +239,11 @@ function Get-IcingaCheckCommandConfig() $Basket.Datafield.Add( '0', @{ 'varname' = 'PowerShell_switch_NoPerfData'; - 'caption' = 'NoPerfData'; + 'caption' = 'Ignore Performance Data'; 'description' = 'Specifies if the plugin will return performance data output or not'; - 'datatype' = 'Icinga\\Module\\Director\\DataType\\DataTypeDatalist'; + 'datatype' = 'Icinga\Module\Director\DataType\DataTypeBoolean'; 'format' = $NULL; 'originalId' = '0'; - 'settings' = @{ - 'datalist' = 'PowerShell NoPerfData'; - 'datatype' = 'string'; - 'behavior' = 'strict'; - } } ); } @@ -296,10 +251,10 @@ function Get-IcingaCheckCommandConfig() if($Basket.Datafield.ContainsKey('1') -eq $FALSE){ $Basket.Datafield.Add( '1', @{ - 'varname' = 'PowerShell_switch_NoPerfData'; + 'varname' = 'PowerShell_Object_Verbose'; 'caption' = 'Verbose'; 'description' = 'Specifies if the plugin will return performance data output or not'; - 'datatype' = 'Icinga\\Module\\Director\\DataType\\DataTypeString'; + 'datatype' = 'Icinga\Module\Director\DataType\DataTypeString'; 'format' = $NULL; 'originalId' = '1'; 'settings' = @{ @@ -313,8 +268,8 @@ function Get-IcingaCheckCommandConfig() $IcingaDataType = [string]::Format('Icinga\Module\Director\DataType\DataType{0}', $IcingaDataType) - if ($Basket.Datafield.Values.varname -eq $IcingaCustomVariable) { - } else { + + if ($Basket.Datafield.Values.varname -ne $IcingaCustomVariable) { $Basket.Datafield.Add( [string]$FieldID, @{ 'varname' = $IcingaCustomVariable; @@ -326,7 +281,7 @@ function Get-IcingaCheckCommandConfig() } ); - if ($parameter.type.name -eq 'switch' -or $parameter.Name -eq 'Verbose') { + if ($parameter.Name -eq 'Verbose') { $Basket.Datafield[[string]$FieldID].Add( 'settings', @{ 'behavior' = 'strict'; @@ -353,20 +308,20 @@ function Get-IcingaCheckCommandConfig() } } - # Increment FieldNumeation, so unique fields for a given command are added. + # Increment FieldNumeration, so unique fields for a given command are added. [int]$FieldNumeration = [int]$FieldNumeration + 1; } # Check whether or not noperfdata and verbose is set and add it if necessary - if ($Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.ContainsKey('-Verbose') -eq $FALSE) { - $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( + if ($Basket.Command[$Data.Name].arguments.ContainsKey('-Verbose') -eq $FALSE) { + $Basket.Command[$Data.Name].arguments.Add( '-Verbose', @{ 'value' = '$PowerShell_Object_Verbose$'; 'order' = '99'; } ); - $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add( + $Basket.Command[$Data.Name].vars.Add( 'PowerShell_Object_Verbose', "0" ); @@ -390,74 +345,42 @@ function Get-IcingaCheckCommandConfig() } } - if ($Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.ContainsKey('-NoPerfData') -eq $FALSE) { - $Basket.Command[$Data.Syntax.syntaxItem.Name].arguments.Add( + if ($Basket.Command[$Data.Name].arguments.ContainsKey('-NoPerfData') -eq $FALSE) { + $Basket.Command[$Data.Name].arguments.Add( '-NoPerfData', @{ 'set_if' = '$PowerShell_switch_NoPerfData$'; 'set_if_format' = 'string'; 'order' = '99'; } ); - $Basket.Command[$Data.Syntax.syntaxItem.Name].vars.Add('PowerShell_switch_NoPerfData', "0"); - - if ($Basket.Datafield.Values.varname -eq $IcingaCustomVariable) { - } else { - $Basket.Datafield.Add( - [string]$FieldID, @{ - 'varname' = 'PowerShell_switch_NoPerfData'; - 'caption' = 'Perf Data'; - 'description' = 'Specifies if the plugin will return performance data output or not'; - 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; - 'format' = $NULL; - 'originalId' = [string]$FieldID; - 'settings' = @{ - 'behavior' = 'strict'; - 'data_type' = 'string'; - 'datalist' = 'PowerShell NoPerfData' - } - } - ); - } + $Basket.Command[$Data.Name].vars.Add('PowerShell_switch_NoPerfData', $FALSE); } } foreach ($check in $CheckName) { [int]$FieldNumeration = 0; - $Data = (Get-Help $check) - - foreach ($parameter in $Data.Syntax.syntaxItem.parameter){ + $Data = (Get-Help $check) + + foreach ($parameter in $Data.parameters.parameter){ $IcingaCustomVariable = [string]::Format('PowerShell_{0}_{1}', $parameter.type.name, $parameter.Name); - # Hashtable for Matching Command.Name.Fields to DataFields (and there given IDs) - [hashtable]$TranslationDataField = @{} + # Todo: Should we improve this? Actually the handling would be identical, we just need to assign + # the proper field for this + if ($IcingaCustomVariable -eq 'PowerShell_Int32_Verbose') { + $IcingaCustomVariable = 'PowerShell_Object_Verbose'; + } - # Looping through IDs of existing DataFields - foreach ($DataFieldID in $Basket.Datafield.Keys) - { - # Ignore Default-Set Deatafield "NoPerfData" - if ($TranslationDataField.Contains('PowerShell_switch_NoPerfData') -eq $TRUE){ - }else{ - $TranslationDataField.Add($Basket.Datafield.$DataFieldID.varname, $DataFieldID); + foreach ($DataFieldID in $Basket.Datafield.Keys) { + [string]$varname = $Basket.Datafield[$DataFieldID].varname; + if ([string]$varname -eq [string]$IcingaCustomVariable) { + $Basket.Command[$Data.Name].fields += @{ + 'datafield_id' = [int]$DataFieldID; + 'is_required' = $Required; + 'var_filter' = $NULL; + }; } } - - foreach($key in $TranslationDataField.Keys) - { - if ([string]$IcingaCustomVariable -eq [string]$key) { - $MatchedDataFieldID = $TranslationDataField[$IcingaCustomVariable]; - } else {} - } - - $Basket.Command[$Data.Syntax.syntaxItem.Name].fields.Add( - [string]$FieldNumeration, @{ - 'datafield_id' = [int]$MatchedDataFieldID; - 'is_required' = $Required; - 'var_filter' = $NULL; - } - ); - - [int]$FieldNumeration = [int]$FieldNumeration + 1; } } From 9c2a65a9add2ac85ac67dfd24d97b3e49028f49c Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 16 Sep 2019 16:31:15 +0200 Subject: [PATCH 086/259] Fixed Verbose Argument duplication and DataList type --- .../tools/Get-IcingaCheckCommandConfig.psm1 | 38 +++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) diff --git a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 index 0853fce..3b640f9 100644 --- a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 +++ b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 @@ -164,6 +164,12 @@ function Get-IcingaCheckCommandConfig() $IcingaCustomVariable = [string]::Format('$PowerShell_{0}_{1}$', $parameter.type.name, $parameter.Name); + # Todo: Should we improve this? Actually the handling would be identical, we just need to assign + # the proper field for this + if ($IcingaCustomVariable -eq '$PowerShell_Int32_Verbose$' -Or $IcingaCustomVariable -eq '$PowerShell_Int_Verbose$') { + $IcingaCustomVariable = '$PowerShell_Object_Verbose$'; + } + # Add arguments to a given command if ($parameter.type.name -eq 'switch') { $Basket.Command[$Data.Name].arguments.Add( @@ -218,6 +224,25 @@ function Get-IcingaCheckCommandConfig() $IcingaCustomVariable = [string]::Format('PowerShell_{0}_{1}', $parameter.type.name, $parameter.Name); + # Todo: Should we improve this? Actually the handling would be identical, we just need to assign + # the proper field for this + if ($IcingaCustomVariable -eq 'PowerShell_Int32_Verbose' -Or $IcingaCustomVariable -eq 'PowerShell_Int_Verbose') { + $IcingaCustomVariable = 'PowerShell_Object_Verbose'; + } + + [bool]$ArgumentKnown = $FALSE; + + foreach ($argument in $Basket.Datafield.Keys) { + if ($Basket.Datafield[$argument].varname -eq $IcingaCustomVariable) { + $ArgumentKnown = $TRUE; + break; + } + } + + if ($ArgumentKnown) { + continue; + } + $DataListName = [string]::Format('PowerShell {0}', $parameter.Name) if ($parameter.type.name -eq 'switch') { @@ -235,7 +260,7 @@ function Get-IcingaCheckCommandConfig() $IcingaDataType='String'; } - if($Basket.Datafield.ContainsKey('0') -eq $FALSE){ + if($Basket.Datafield.ContainsKey('0') -eq $FALSE){ $Basket.Datafield.Add( '0', @{ 'varname' = 'PowerShell_switch_NoPerfData'; @@ -254,7 +279,7 @@ function Get-IcingaCheckCommandConfig() 'varname' = 'PowerShell_Object_Verbose'; 'caption' = 'Verbose'; 'description' = 'Specifies if the plugin will return performance data output or not'; - 'datatype' = 'Icinga\Module\Director\DataType\DataTypeString'; + 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; 'format' = $NULL; 'originalId' = '1'; 'settings' = @{ @@ -267,7 +292,6 @@ function Get-IcingaCheckCommandConfig() } $IcingaDataType = [string]::Format('Icinga\Module\Director\DataType\DataType{0}', $IcingaDataType) - if ($Basket.Datafield.Values.varname -ne $IcingaCustomVariable) { $Basket.Datafield.Add( @@ -331,14 +355,14 @@ function Get-IcingaCheckCommandConfig() [string]$FieldID, @{ 'varname' = 'PowerShell_Object_Verbose'; 'caption' = 'Verbose'; - 'description' = 'Increase the plugin output for more information on the received result.'; + 'description' = 'Specifies if the plugin will return performance data output or not'; 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; 'format' = $NULL; 'originalId' = [string]$FieldID; 'settings' = @{ - 'behavior' = 'strict'; + 'behavior' = 'strict'; 'data_type' = 'string'; - 'datalist' = 'PowerShell Verbose' + 'datalist' = 'PowerShell Verbose' } } ); @@ -367,7 +391,7 @@ function Get-IcingaCheckCommandConfig() # Todo: Should we improve this? Actually the handling would be identical, we just need to assign # the proper field for this - if ($IcingaCustomVariable -eq 'PowerShell_Int32_Verbose') { + if ($IcingaCustomVariable -eq 'PowerShell_Int32_Verbose' -Or $IcingaCustomVariable -eq 'PowerShell_Int_Verbose') { $IcingaCustomVariable = 'PowerShell_Object_Verbose'; } From 0fed0f938cb2dd700170b42ae06b2eef5b868ea0 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 16 Sep 2019 17:02:13 +0200 Subject: [PATCH 087/259] Fixed default value for Verbose argument on Config generation --- lib/core/tools/Get-IcingaCheckCommandConfig.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 index 3b640f9..4c0a485 100644 --- a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 +++ b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 @@ -211,7 +211,7 @@ function Get-IcingaCheckCommandConfig() if ($parameter.name -ne 'Verbose') { $Basket.Command[$Data.Name].vars.Add($parameter.Name, '$$null'); } else { - $Basket.Command[$Data.Name].vars.Add($parameter.Name, ""); + $Basket.Command[$Data.Name].vars.Add($parameter.Name, "0"); } } From 423791750a9a64a510024e07abcd41fb87dc1626 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 16 Sep 2019 17:32:25 +0200 Subject: [PATCH 088/259] Added tool function to increase digit count * Added new function Format-IcingaDigitCount to fill digits with leading 0 depending on missing values * Added this function to CPU check --- lib/core/tools/Format-IcingaDigitCount.psm1 | 22 +++++++++++++++++++++ lib/plugins/Invoke-IcingaCheckCPU.psm1 | 5 +++-- 2 files changed, 25 insertions(+), 2 deletions(-) create mode 100644 lib/core/tools/Format-IcingaDigitCount.psm1 diff --git a/lib/core/tools/Format-IcingaDigitCount.psm1 b/lib/core/tools/Format-IcingaDigitCount.psm1 new file mode 100644 index 0000000..8e6d012 --- /dev/null +++ b/lib/core/tools/Format-IcingaDigitCount.psm1 @@ -0,0 +1,22 @@ +function Format-IcingaDigitCount() +{ + param( + [string]$Value, + [int]$Digits + ); + + if ([string]::IsNullOrEmpty($Value)) { + return $Value; + } + + $CurrentLength = $Value.Length; + if ($CurrentLength -ge $Digits) { + return $Value; + } + + while ($Value.Length -lt $Digits) { + $Value = [string]::Format('0{0}', $Value); + } + + return $Value; +} diff --git a/lib/plugins/Invoke-IcingaCheckCPU.psm1 b/lib/plugins/Invoke-IcingaCheckCPU.psm1 index 0df4075..8fc2034 100644 --- a/lib/plugins/Invoke-IcingaCheckCPU.psm1 +++ b/lib/plugins/Invoke-IcingaCheckCPU.psm1 @@ -1,4 +1,5 @@ Import-IcingaLib core\perfcounter; +Import-IcingaLib core\tools; Import-IcingaLib icinga\plugin; function Invoke-IcingaCheckCPU() @@ -16,12 +17,12 @@ function Invoke-IcingaCheckCPU() if ($CpuCounter.Counters.Count -ne 0) { foreach ($counter in $CpuCounter.Counters) { - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core #{0}', $counter.Instance)) -Value $counter.Value().Value -Unit '%'; + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core #{0}', (Format-IcingaDigitCount $counter.Instance -Digits 3))) -Value $counter.Value().Value -Unit '%'; $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; $CpuPackage.AddCheck($IcingaCheck); } } else { - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core #{0}',$Core)) -Value $CpuCounter.Value().Value -Unit '%'; + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core #{0}', (Format-IcingaDigitCount $Core -Digits 3))) -Value $CpuCounter.Value().Value -Unit '%'; $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; $CpuPackage.AddCheck($IcingaCheck); } From b92d3004b9fdb1a7318f773f7f92d88d2cbf2e09 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 16 Sep 2019 17:53:29 +0200 Subject: [PATCH 089/259] Extended digit format with custom symbol --- lib/core/tools/Format-IcingaDigitCount.psm1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/core/tools/Format-IcingaDigitCount.psm1 b/lib/core/tools/Format-IcingaDigitCount.psm1 index 8e6d012..d1228ec 100644 --- a/lib/core/tools/Format-IcingaDigitCount.psm1 +++ b/lib/core/tools/Format-IcingaDigitCount.psm1 @@ -2,7 +2,8 @@ function Format-IcingaDigitCount() { param( [string]$Value, - [int]$Digits + [int]$Digits, + [string]$Symbol = 0 ); if ([string]::IsNullOrEmpty($Value)) { @@ -15,7 +16,7 @@ function Format-IcingaDigitCount() } while ($Value.Length -lt $Digits) { - $Value = [string]::Format('0{0}', $Value); + $Value = [string]::Format('{0}{1}', $Symbol, $Value); } return $Value; From a96347e54fca8321b243e5e11e7ea6b2d4c9e047 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 16 Sep 2019 17:59:12 +0200 Subject: [PATCH 090/259] Replaced 0 with space for digits and auto added spacing --- lib/plugins/Invoke-IcingaCheckCPU.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckCPU.psm1 b/lib/plugins/Invoke-IcingaCheckCPU.psm1 index 8fc2034..7cab6e2 100644 --- a/lib/plugins/Invoke-IcingaCheckCPU.psm1 +++ b/lib/plugins/Invoke-IcingaCheckCPU.psm1 @@ -17,12 +17,12 @@ function Invoke-IcingaCheckCPU() if ($CpuCounter.Counters.Count -ne 0) { foreach ($counter in $CpuCounter.Counters) { - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core #{0}', (Format-IcingaDigitCount $counter.Instance -Digits 3))) -Value $counter.Value().Value -Unit '%'; + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core {0}', (Format-IcingaDigitCount $counter.Instance -Digits ([string](Get-IcingaCpuCount)).Length -Symbol ' '))) -Value $counter.Value().Value -Unit '%'; $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; $CpuPackage.AddCheck($IcingaCheck); } } else { - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core #{0}', (Format-IcingaDigitCount $Core -Digits 3))) -Value $CpuCounter.Value().Value -Unit '%'; + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core {0}', (Format-IcingaDigitCount $Core -Digits ([string](Get-IcingaCpuCount)).Length -Symbol ' '))) -Value $CpuCounter.Value().Value -Unit '%'; $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; $CpuPackage.AddCheck($IcingaCheck); } From 2ffeeb26d8bbdb5c80dc3ebffa72bdd451567149 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 16 Sep 2019 18:02:41 +0200 Subject: [PATCH 091/259] Improved performance for CPU plugin execution with digit detection --- lib/plugins/Invoke-IcingaCheckCPU.psm1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckCPU.psm1 b/lib/plugins/Invoke-IcingaCheckCPU.psm1 index 7cab6e2..da9809f 100644 --- a/lib/plugins/Invoke-IcingaCheckCPU.psm1 +++ b/lib/plugins/Invoke-IcingaCheckCPU.psm1 @@ -14,15 +14,16 @@ function Invoke-IcingaCheckCPU() $CpuCounter = New-IcingaPerformanceCounter -Counter ([string]::Format('\Processor({0})\% processor time', $Core)); $CpuPackage = New-IcingaCheckPackage -Name 'CPU Load' -OperatorAnd -Verbos $Verbose; + $CpuCount = ([string](Get-IcingaCpuCount)).Length; if ($CpuCounter.Counters.Count -ne 0) { foreach ($counter in $CpuCounter.Counters) { - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core {0}', (Format-IcingaDigitCount $counter.Instance -Digits ([string](Get-IcingaCpuCount)).Length -Symbol ' '))) -Value $counter.Value().Value -Unit '%'; + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core {0}', (Format-IcingaDigitCount $counter.Instance -Digits $CpuCount -Symbol ' '))) -Value $counter.Value().Value -Unit '%'; $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; $CpuPackage.AddCheck($IcingaCheck); } } else { - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core {0}', (Format-IcingaDigitCount $Core -Digits ([string](Get-IcingaCpuCount)).Length -Symbol ' '))) -Value $CpuCounter.Value().Value -Unit '%'; + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core {0}', (Format-IcingaDigitCount $Core -Digits $CpuCount -Symbol ' '))) -Value $CpuCounter.Value().Value -Unit '%'; $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; $CpuPackage.AddCheck($IcingaCheck); } From 61214342720be3c5dcec85c28f380fe1ef8b287a Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 16 Sep 2019 18:07:57 +0200 Subject: [PATCH 092/259] Removed leading '_' from Total core --- lib/plugins/Invoke-IcingaCheckCPU.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckCPU.psm1 b/lib/plugins/Invoke-IcingaCheckCPU.psm1 index da9809f..189649b 100644 --- a/lib/plugins/Invoke-IcingaCheckCPU.psm1 +++ b/lib/plugins/Invoke-IcingaCheckCPU.psm1 @@ -18,12 +18,12 @@ function Invoke-IcingaCheckCPU() if ($CpuCounter.Counters.Count -ne 0) { foreach ($counter in $CpuCounter.Counters) { - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core {0}', (Format-IcingaDigitCount $counter.Instance -Digits $CpuCount -Symbol ' '))) -Value $counter.Value().Value -Unit '%'; + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core {0}', (Format-IcingaDigitCount $counter.Instance.Replace('_', '') -Digits $CpuCount -Symbol ' '))) -Value $counter.Value().Value -Unit '%'; $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; $CpuPackage.AddCheck($IcingaCheck); } } else { - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core {0}', (Format-IcingaDigitCount $Core -Digits $CpuCount -Symbol ' '))) -Value $CpuCounter.Value().Value -Unit '%'; + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core {0}', (Format-IcingaDigitCount $Core.Replace('_', '') -Digits $CpuCount -Symbol ' '))) -Value $CpuCounter.Value().Value -Unit '%'; $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; $CpuPackage.AddCheck($IcingaCheck); } From dc2729e8c522e2e92eea4daf073e805e0cbb9a2a Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 17 Sep 2019 17:12:06 +0200 Subject: [PATCH 093/259] Added ability to force exception throwing --- ...96991491710121821213111390108.lastcheck.json | 3 +++ .../exception/Exit-IcingaThrowException.psm1 | 17 ++++++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) create mode 100644 cache/provider/eventlog/1781451901841216379518196991491710121821213111390108.lastcheck.json diff --git a/cache/provider/eventlog/1781451901841216379518196991491710121821213111390108.lastcheck.json b/cache/provider/eventlog/1781451901841216379518196991491710121821213111390108.lastcheck.json new file mode 100644 index 0000000..599898a --- /dev/null +++ b/cache/provider/eventlog/1781451901841216379518196991491710121821213111390108.lastcheck.json @@ -0,0 +1,3 @@ +{ + "1781451901841216379518196991491710121821213111390108.lastcheck": 132132048543175098 +} diff --git a/lib/icinga/exception/Exit-IcingaThrowException.psm1 b/lib/icinga/exception/Exit-IcingaThrowException.psm1 index d4610ee..2e2ae8f 100644 --- a/lib/icinga/exception/Exit-IcingaThrowException.psm1 +++ b/lib/icinga/exception/Exit-IcingaThrowException.psm1 @@ -6,15 +6,18 @@ function Exit-IcingaThrowException() [string]$CustomMessage, [string]$ExceptionThrown, [ValidateSet('Permission','Input','Unhandled')] - [string]$ExceptionType = 'Unhandled' + [string]$ExceptionType = 'Unhandled', + [switch]$Force ); - if ($null -eq $InputString -Or [string]::IsNullOrEmpty($InputString)) { - return; - } + if ($Force -eq $FALSE) { + if ($null -eq $InputString -Or [string]::IsNullOrEmpty($InputString)) { + return; + } - if (-Not $InputString.Contains($StringPattern)) { - return; + if (-Not $InputString.Contains($StringPattern)) { + return; + } } $ExceptionMessageLib = $null; @@ -44,7 +47,7 @@ function Exit-IcingaThrowException() } } } else { - $ExceptionName = 'Unhandled Exception'; + $ExceptionName = 'Unhandled Exception'; $ExceptionThrown = [string]::Format( 'Unhandled exception occured:{0}{1}', "`r`n", From 300a8d4d409640586d1ada39344a0b785f10ab55 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 17 Sep 2019 17:17:38 +0200 Subject: [PATCH 094/259] Added support to create and load cache data (prototype) --- lib/core/cache/Get-IcingaCacheData.psm1 | 30 +++++++++++++++++++++++ lib/core/cache/Set-IcingaCacheData.psm1 | 32 +++++++++++++++++++++++++ 2 files changed, 62 insertions(+) create mode 100644 lib/core/cache/Get-IcingaCacheData.psm1 create mode 100644 lib/core/cache/Set-IcingaCacheData.psm1 diff --git a/lib/core/cache/Get-IcingaCacheData.psm1 b/lib/core/cache/Get-IcingaCacheData.psm1 new file mode 100644 index 0000000..27b09d9 --- /dev/null +++ b/lib/core/cache/Get-IcingaCacheData.psm1 @@ -0,0 +1,30 @@ +function Get-IcingaCacheData() +{ + param( + [string]$Space, + [string]$CacheStore, + [string]$KeyName + ); + + $CacheFile = Join-Path -Path (Join-Path -Path (Join-Path -Path (Get-IcingaCacheDir) -ChildPath $Space) -ChildPath $CacheStore) -ChildPath ([string]::Format('{0}.json', $KeyName)); + [string]$Content = ''; + $cacheData = @{}; + + if ((Test-Path $CacheFile) -eq $FALSE) { + return $null; + } + + $Content = Get-Content -Path $CacheFile; + + if ([string]::IsNullOrEmpty($Content)) { + return $null; + } + + $cacheData = ConvertFrom-Json -InputObject ([string]$Content); + + if ([string]::IsNullOrEmpty($KeyName)) { + return $cacheData; + } else { + return $cacheData.$KeyName; + } +} diff --git a/lib/core/cache/Set-IcingaCacheData.psm1 b/lib/core/cache/Set-IcingaCacheData.psm1 new file mode 100644 index 0000000..7595410 --- /dev/null +++ b/lib/core/cache/Set-IcingaCacheData.psm1 @@ -0,0 +1,32 @@ +function Set-IcingaCacheData() +{ + param( + [string]$Space, + [string]$CacheStore, + [string]$KeyName, + $Value + ); + + $CacheFile = Join-Path -Path (Join-Path -Path (Join-Path -Path (Get-IcingaCacheDir) -ChildPath $Space) -ChildPath $CacheStore) -ChildPath ([string]::Format('{0}.json', $KeyName)); + $cacheData = @{}; + + if ((Test-Path $CacheFile)) { + $cacheData = Get-IcingaCacheData -Space $Space -CacheStore $CacheStore; + } else { + New-Item -Path $CacheFile -Force | Out-Null; + } + + if ($null -eq $cacheData -or $cacheData.Count -eq 0) { + $cacheData = @{ + $KeyName = $Value + }; + } else { + if ($cacheData.PSobject.Properties.Name -ne $KeyName) { + $cacheData | Add-Member -MemberType NoteProperty -Name $KeyName -Value $Value -Force; + } else { + $cacheData.$KeyName = $Value; + } + } + + Set-Content -Path $CacheFile -Value (ConvertTo-Json -InputObject $cacheData -Depth 100) | Out-Null; +} From d2cad7afde7f15b0d103e805019299c7adefd719 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 17 Sep 2019 17:23:29 +0200 Subject: [PATCH 095/259] Added Cmdlet to get Plugin and Cache dir --- icinga-module-windows.psd1 | 2 +- icinga-module-windows.psm1 | 9 +++++++++ 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/icinga-module-windows.psd1 b/icinga-module-windows.psd1 index 35e62cb..c1e1e85 100644 --- a/icinga-module-windows.psd1 +++ b/icinga-module-windows.psd1 @@ -25,7 +25,7 @@ Description = 'Icinga 2 Windows Agent Module, which allows to entirely monitor t PowerShellVersion = '3.0' # Aus diesem Modul zu exportierende Funktionen. Um optimale Leistung zu erzielen, verwenden Sie keine Platzhalter und löschen den Eintrag nicht. Verwenden Sie ein leeres Array, wenn keine zu exportierenden Funktionen vorhanden sind. -FunctionsToExport = @( 'Use-Icinga', 'Import-IcingaLib', 'Start-Icinga-Checker', 'Stop-Icinga-Checker', 'Get-Icinga-Lib', 'Get-Icinga-Object', 'Get-Icinga-Service', 'Start-Icinga-Service', 'Stop-Icinga-Service', 'Restart-Icinga-Service', 'Install-Icinga-Service', 'Uninstall-Icinga-Service', 'Get-Icinga-Setup', 'Install-Icinga', 'Start-Icinga-Daemon', 'Stop-Icinga-Daemon', 'Icinga-Client', 'Get-Icinga-Command', 'New-Icinga-Monitoring', 'Get-Icinga-Counter', 'Get-Icinga-Config', 'Set-Icinga-Config', 'Remove-Icinga-Config', 'New-Icinga-Config' ) +FunctionsToExport = @( 'Use-Icinga', 'Import-IcingaLib', 'Get-IcingaPluginDir', 'Get-IcingaCacheDir', 'Start-Icinga-Checker', 'Stop-Icinga-Checker', 'Get-Icinga-Lib', 'Get-Icinga-Object', 'Get-Icinga-Service', 'Start-Icinga-Service', 'Stop-Icinga-Service', 'Restart-Icinga-Service', 'Install-Icinga-Service', 'Uninstall-Icinga-Service', 'Get-Icinga-Setup', 'Install-Icinga', 'Start-Icinga-Daemon', 'Stop-Icinga-Daemon', 'Icinga-Client', 'Get-Icinga-Command', 'New-Icinga-Monitoring', 'Get-Icinga-Counter', 'Get-Icinga-Config', 'Set-Icinga-Config', 'Remove-Icinga-Config', 'New-Icinga-Config' ) # Aus diesem Modul zu exportierende Cmdlets. Um optimale Leistung zu erzielen, verwenden Sie keine Plat'zhalter und löschen den Eintrag nicht. Verwenden Sie ein leeres Array, wenn keine zu exportierenden Cmdlets vorhanden sind. CmdletsToExport = @() diff --git a/icinga-module-windows.psm1 b/icinga-module-windows.psm1 index 990a151..7de4f52 100644 --- a/icinga-module-windows.psm1 +++ b/icinga-module-windows.psm1 @@ -66,6 +66,15 @@ function Import-IcingaLib() } } +function Get-IcingaPluginDir() +{ + return (Join-Path -Path $PSScriptRoot -ChildPath 'lib\plugins\'); +} + +function Get-IcingaCacheDir() +{ + return (Join-Path -Path $PSScriptRoot -ChildPath 'cache'); +} function Install-Icinga() { [string]$command = Get-Icinga-Command('setup'); From f2a2aed8a228d3bf0675c32f6d6926f706cd6550 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 17 Sep 2019 17:24:09 +0200 Subject: [PATCH 096/259] Added missing Cmdlet definition to init function --- core/init.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/core/init.ps1 b/core/init.ps1 index e57c9e8..f8e41da 100644 --- a/core/init.ps1 +++ b/core/init.ps1 @@ -9,6 +9,8 @@ Set-Variable -Name Icinga2 -Option Constant -Value @{ Function = @( 'Use-Icinga', 'Import-IcingaLib', + 'Get-IcingaPluginDir', + 'Get-IcingaCacheDir', 'Get-Icinga-Lib', 'Get-Icinga-Object', 'Get-Icinga-Service', From f92fc807074bde57eeed3f56c4b765b3c8036584 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 17 Sep 2019 17:24:39 +0200 Subject: [PATCH 097/259] Added EventLog Check Command and Provider --- .../Icinga_IcingaExceptionEnums.psm1 | 1 + lib/plugins/Invoke-IcingaCheckEventlog.psm1 | 54 +++++++ lib/provider/eventlog/Get-IcingaEventLog.psm1 | 137 ++++++++++++++++++ 3 files changed, 192 insertions(+) create mode 100644 lib/plugins/Invoke-IcingaCheckEventlog.psm1 create mode 100644 lib/provider/eventlog/Get-IcingaEventLog.psm1 diff --git a/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 b/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 index 21fb5d6..ea508dd 100644 --- a/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 +++ b/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 @@ -10,6 +10,7 @@ [hashtable]$Inputs = @{ PerformanceCounter = 'A plugin failed to fetch Performance Counter information. Please ensure the counter is written properly and available on your system.'; + EventLog = 'Failed to fetch EventLog information. Please specify a LogName.'; }; <# diff --git a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 new file mode 100644 index 0000000..dd150b8 --- /dev/null +++ b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 @@ -0,0 +1,54 @@ +Import-IcingaLib icinga\plugin; + +function Invoke-IcingaCheckEventlog() +{ + param( + $Warning, + $Critical, + [string]$LogName, + [array]$IncludeEventId, + [array]$ExcludeEventId, + [array]$IncludeUsername, + [array]$ExcludeUsername, + [array]$IncludeEntryType, + [array]$ExcludeEntryType, + [array]$IncludeMessage, + [array]$ExcludeMessage, + $After = $null, + $Before = $null, + [bool]$DisableTimeCache, + [switch]$NoPerfData, + $Verbose + ); + + $EventLogPackage = New-IcingaCheckPackage -Name 'EventLog' -OperatorAnd -Verbose $Verbose; + $EventLogData = Get-IcingaEventLog -LogName $LogName -IncludeEventId $IncludeEventId -ExcludeEventId $ExcludeEventId -IncludeUsername $IncludeUsername -ExcludeUsername $ExcludeUsername ` + -IncludeEntryType $IncludeEntryType -ExcludeEntryType $ExcludeEntryType -IncludeMessage $IncludeMessage -ExcludeMessage $ExcludeMessage ` + -After $After -Before $Before -DisableTimeCache $DisableTimeCache; + + if ($EventLogData.eventlog.Count -ne 0) { + foreach ($event in $EventLogData.eventlog.Keys) { + $eventEntry = $EventLogData.eventlog[$event]; + $EventLogEntryPackage = New-IcingaCheckPackage -Name ([string]::Format('Between: {0}-{1} there occured {2} event(s). Message: "{3}" {4}', $eventEntry.OldestEntry, $eventEntry.NewestEntry, $eventEntry.Count, $eventEntry.Severity, $eventEntry.Message)) -OperatorAnd -Verbose $Verbose; + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('EventId {0}', $EventLogData.eventlog[$event].EventId)) -NoPerfData; + $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + $EventLogEntryPackage.AddCheck($IcingaCheck); + + $EventLogPackage.AddCheck($EventLogEntryPackage); + } + + $EventLogCountPackage = New-IcingaCheckPackage -Name 'EventLog Count' -OperatorAnd -Verbose $Verbose; + + foreach ($event in $EventLogData.events.Keys) { + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('EventId {0}', $event)) -Value $EventLogData.events[$event] -Unit 'c'; + $EventLogCountPackage.AddCheck($IcingaCheck); + } + + $EventLogPackage.AddCheck($EventLogCountPackage); + } else { + $IcingaCheck = New-IcingaCheck -Name 'No EventLogs found' -Value 0 -Unit 'c' -NoPerfData; + $EventLogPackage.AddCheck($IcingaCheck); + } + + exit (New-IcingaCheckResult -Name 'EventLog' -Check $EventLogPackage -NoPerfData $NoPerfData -Compile); +} diff --git a/lib/provider/eventlog/Get-IcingaEventLog.psm1 b/lib/provider/eventlog/Get-IcingaEventLog.psm1 new file mode 100644 index 0000000..487d759 --- /dev/null +++ b/lib/provider/eventlog/Get-IcingaEventLog.psm1 @@ -0,0 +1,137 @@ +Import-IcingaLib icinga\exception; + +function Get-IcingaEventLog() +{ + param( + [string]$LogName, + [array]$IncludeEventId, + [array]$ExcludeEventId, + [array]$IncludeUsername, + [array]$ExcludeUsername, + [array]$IncludeEntryType, + [array]$ExcludeEntryType, + [array]$IncludeMessage, + [array]$ExcludeMessage, + $After, + $Before, + [bool]$DisableTimeCache + ); + + if ([string]::IsNullOrEmpty($LogName)) { + Exit-IcingaThrowException -ExceptionType 'Input' -ExceptionThrown $IcingaExceptions.Inputs.EventLog -Force; + } + + [hashtable]$EventLogArguments = @{ + LogName = $LogName; + }; + + # This will generate a unique hash for each possible configured EventLog check to store the last check time for each of these checks + [string]$CheckHash = (Get-StringSha1 ($LogName + $IncludeEventId + $ExcludeEventId + $IncludeUsername + $ExcludeUsername + $IncludeEntryType + $ExcludeEntryType + $IncludeMessage + $ExcludeMessage)) + '.lastcheck'; + + if ($null -eq $After -and $DisableTimeCache -eq $FALSE) { + $time = Get-IcingaCacheData -Space 'provider' -CacheStore 'eventlog' -KeyName $CheckHash; + Set-IcingaCacheData -Space 'provider' -CacheStore 'eventlog' -KeyName $CheckHash -Value ((Get-Date).ToFileTime()); + + if ($null -ne $time) { + $After = [datetime]::FromFileTime($time); + } + } + + if ($null -ne $IncludeEventId) { + $EventLogArguments.Add('InstanceID', $IncludeEventId); + } + if ($null -ne $IncludeUsername) { + $EventLogArguments.Add('UserName', $IncludeUsername); + } + if ($null -ne $IncludeEntryType) { + $EventLogArguments.Add('EntryType', $IncludeEntryType); + } + if ($null -ne $IncludeMessage) { + $EventLogArguments.Add('Message', $IncludeMessage); + } + if ($null -ne $After) { + $EventLogArguments.Add('After', $After); + } + if ($null -ne $Before) { + $EventLogArguments.Add('Before', $Before); + } + + $events = Get-EventLog @EventLogArguments; + + if ($null -ne $ExcludeEventId -Or $null -ne $ExcludeUsername -Or $null -ne $ExcludeEntryType -Or $null -ne $ExcludeMessage) { + Write-Host 'Filtering started!' + $filteredEvents = @(); + foreach ($event in $events) { + # Filter out excluded event IDs + if ($event.InstanceID -contains $ExcludeEventId) { + continue; + } + + # Filter out excluded event IDs + if ($event.UserName -contains $ExcludeUsername) { + continue; + } + + # Filter out excluded event IDs + if ($event.EntryType -contains $ExcludeEntryType) { + continue; + } + + [bool]$skip = $FALSE; + foreach ($exMessage in $ExcludeMessage) { + # Filter out excluded event IDs + if ([string]$event.Message -like [string]$exMessage) { + $skip = $TRUE; + break; + } + } + + if ($skip) { + continue; + } + + $filteredEvents += $event; + } + + $events = $filteredEvents; + } + + $groupedEvents = @{ + 'eventlog' = @{}; + 'events' = @{}; + }; + + foreach ($event in $events) { + [string]$EventIdentifier = [string]::Format('{0}-{1}', + $event.InstanceID, + $event.Message + ); + + [string]$EventHash = Get-StringSha1 $EventIdentifier; + + if ($groupedEvents.eventlog.ContainsKey($EventHash) -eq $FALSE) { + $groupedEvents.eventlog.Add( + $EventHash, + @{ + NewestEntry = $event.TimeGenerated; + OldestEntry = $event.TimeGenerated; + EventId = $event.InstanceID; + Message = $event.Message; + Severity = $event.EntryType; + Count = 1; + } + ); + } else { + $groupedEvents.eventlog[$EventHash].OldestEntry = $event.TimeGenerated; + $groupedEvents.eventlog[$EventHash].Count += 1; + } + + if ($groupedEvents.events.ContainsKey($event.InstanceID) -eq $FALSE) { + $groupedEvents.events.Add($event.InstanceID, 1); + } else { + $groupedEvents.events[$event.InstanceID] += 1; + } + } + + return $groupedEvents; +} From 0d7954617c33b4bb240b391dce526b1df10a32a3 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 17 Sep 2019 17:56:56 +0200 Subject: [PATCH 098/259] Added proper exception handling for Cache write failures --- lib/core/cache/Set-IcingaCacheData.psm1 | 7 ++++++- lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 | 1 + 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/lib/core/cache/Set-IcingaCacheData.psm1 b/lib/core/cache/Set-IcingaCacheData.psm1 index 7595410..8c66a88 100644 --- a/lib/core/cache/Set-IcingaCacheData.psm1 +++ b/lib/core/cache/Set-IcingaCacheData.psm1 @@ -28,5 +28,10 @@ function Set-IcingaCacheData() } } - Set-Content -Path $CacheFile -Value (ConvertTo-Json -InputObject $cacheData -Depth 100) | Out-Null; + try { + Set-Content -Path $CacheFile -Value (ConvertTo-Json -InputObject $cacheData -Depth 100) | Out-Null; + } catch { + Exit-IcingaThrowException -InputString $_.Exception -CustomMessage (Get-IcingaCacheDir) -StringPattern 'System.UnauthorizedAccessException' -ExceptionType 'Permission' -ExceptionThrown $IcingaExceptions.Permission.CacheFolder; + Exit-IcingaThrowException -CustomMessage $_.Exception -ExceptionType 'Unhandled' -Force; + } } diff --git a/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 b/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 index ea508dd..ae8c890 100644 --- a/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 +++ b/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 @@ -6,6 +6,7 @@ [hashtable]$Permission = @{ PerformanceCounter = 'A Plugin failed to fetch Performance Counter information. This may be caused when the used Service User is not permitted to access these information. To fix this, please add the User the Icinga Agent is running on into the "Performance Log Users" group and restart the service.'; + CacheFolder = "A plugin failed to write new data into the configured cache directory. Please update the permissions of this folder to allow write access for the user the Icinga Service is running with or use another folder as cache directory."; }; [hashtable]$Inputs = @{ From ac459d7fda2348852bb93276cb711dbf5fac9d16 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 18 Sep 2019 12:42:20 +0200 Subject: [PATCH 099/259] Added additional exception handling for EventLog Check --- lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 | 3 ++- lib/provider/eventlog/Get-IcingaEventLog.psm1 | 9 +++++++-- 2 files changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 b/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 index ae8c890..41b8cbb 100644 --- a/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 +++ b/lib/icinga/exception/Icinga_IcingaExceptionEnums.psm1 @@ -11,7 +11,8 @@ [hashtable]$Inputs = @{ PerformanceCounter = 'A plugin failed to fetch Performance Counter information. Please ensure the counter is written properly and available on your system.'; - EventLog = 'Failed to fetch EventLog information. Please specify a LogName.'; + EventLogLogName = 'Failed to fetch EventLog information. Please specify a valid LogName.'; + EventLog = 'Failed to fetch EventLog information. Please check your inputs for EntryTypes and other categories and try again.'; }; <# diff --git a/lib/provider/eventlog/Get-IcingaEventLog.psm1 b/lib/provider/eventlog/Get-IcingaEventLog.psm1 index 487d759..87f734e 100644 --- a/lib/provider/eventlog/Get-IcingaEventLog.psm1 +++ b/lib/provider/eventlog/Get-IcingaEventLog.psm1 @@ -56,10 +56,15 @@ function Get-IcingaEventLog() $EventLogArguments.Add('Before', $Before); } - $events = Get-EventLog @EventLogArguments; + try { + $events = Get-EventLog @EventLogArguments; + } catch { + Exit-IcingaThrowException -InputString $_.Exception -StringPattern 'ParameterBindingValidationException' -ExceptionType 'Input' -ExceptionThrown $IcingaExceptions.Inputs.EventLog; + Exit-IcingaThrowException -InputString $_.Exception -StringPattern 'System.InvalidOperationException' -CustomMessage (-Join $LogName) -ExceptionType 'Input' -ExceptionThrown $IcingaExceptions.Inputs.EventLogLogName; + Exit-IcingaThrowException -InputString $_.Exception -ExceptionType 'Unhandled' -Force; + } if ($null -ne $ExcludeEventId -Or $null -ne $ExcludeUsername -Or $null -ne $ExcludeEntryType -Or $null -ne $ExcludeMessage) { - Write-Host 'Filtering started!' $filteredEvents = @(); foreach ($event in $events) { # Filter out excluded event IDs From 0d9948fcef55b93cb42e50e1a91dd481b7d07767 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 19 Sep 2019 11:40:58 +0200 Subject: [PATCH 100/259] Fixed include message filtering on EventLog --- lib/provider/eventlog/Get-IcingaEventLog.psm1 | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/lib/provider/eventlog/Get-IcingaEventLog.psm1 b/lib/provider/eventlog/Get-IcingaEventLog.psm1 index 87f734e..5a284d5 100644 --- a/lib/provider/eventlog/Get-IcingaEventLog.psm1 +++ b/lib/provider/eventlog/Get-IcingaEventLog.psm1 @@ -46,9 +46,6 @@ function Get-IcingaEventLog() if ($null -ne $IncludeEntryType) { $EventLogArguments.Add('EntryType', $IncludeEntryType); } - if ($null -ne $IncludeMessage) { - $EventLogArguments.Add('Message', $IncludeMessage); - } if ($null -ne $After) { $EventLogArguments.Add('After', $After); } @@ -64,21 +61,21 @@ function Get-IcingaEventLog() Exit-IcingaThrowException -InputString $_.Exception -ExceptionType 'Unhandled' -Force; } - if ($null -ne $ExcludeEventId -Or $null -ne $ExcludeUsername -Or $null -ne $ExcludeEntryType -Or $null -ne $ExcludeMessage) { + if ($null -ne $ExcludeEventId -Or $null -ne $ExcludeUsername -Or $null -ne $ExcludeEntryType -Or $null -ne $ExcludeMessage -Or $null -ne $IncludeMessage) { $filteredEvents = @(); foreach ($event in $events) { # Filter out excluded event IDs - if ($event.InstanceID -contains $ExcludeEventId) { + if ($ExcludeEventId.Count -ne 0 -And $event.InstanceID -contains $ExcludeEventId) { continue; } # Filter out excluded event IDs - if ($event.UserName -contains $ExcludeUsername) { + if ($ExcludeUsername.Count -ne 0 -And $event.UserName -contains $ExcludeUsername) { continue; } # Filter out excluded event IDs - if ($event.EntryType -contains $ExcludeEntryType) { + if ($ExcludeEntryType.Count -ne 0 -And $event.EntryType -contains $ExcludeEntryType) { continue; } @@ -95,6 +92,20 @@ function Get-IcingaEventLog() continue; } + [bool]$skip = $TRUE; + + foreach ($inMessage in $IncludeMessage) { + # Filter for specific message content + if ([string]$event.Message -like [string]$inMessage) { + $skip = $FALSE; + break; + } + } + + if ($skip) { + continue; + } + $filteredEvents += $event; } From df6604b2df96080eee322d7a3d3dcfd64be53c86 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 19 Sep 2019 11:55:39 +0200 Subject: [PATCH 101/259] Added support to hide CheckPackage check output but keep perf data --- lib/icinga/plugin/New-IcingaCheckPackage.psm1 | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 index 01204e9..18c6c1b 100644 --- a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 +++ b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 @@ -11,13 +11,15 @@ function New-IcingaCheckPackage() [int]$OperatorMin = -1, [int]$OperatorMax = -1, [array]$Checks = @(), - [int]$Verbose = 0 + [int]$Verbose = 0, + [switch]$Hidden = $FALSE ); $Check = New-Object -TypeName PSObject; $Check | Add-Member -membertype NoteProperty -name 'name' -value $Name; $Check | Add-Member -membertype NoteProperty -name 'exitcode' -value -1; $Check | Add-Member -membertype NoteProperty -name 'verbose' -value $Verbose; + $Check | Add-Member -membertype NoteProperty -name 'hidden' -value $Hidden; $Check | Add-Member -membertype NoteProperty -name 'checks' -value $Checks; $Check | Add-Member -membertype NoteProperty -name 'opand' -value $OperatorAnd; $Check | Add-Member -membertype NoteProperty -name 'opor' -value $OperatorOr; @@ -207,6 +209,10 @@ function New-IcingaCheckPackage() } $Check | Add-Member -membertype ScriptMethod -name 'WriteAllOutput' -value { + if ($this.hidden) { + return; + } + [hashtable]$MessageOrdering = @{}; foreach ($check in $this.checks) { $MessageOrdering.Add($check.name, $check); @@ -254,6 +260,10 @@ function New-IcingaCheckPackage() } $Check | Add-Member -membertype ScriptMethod -name 'WritePackageOutputStatus' -value { + if ($this.hidden) { + return; + } + [string]$outputMessage = '{0}{1}: Check package "{2}" is {1}'; if ($this.verbose -ne 0) { $outputMessage += ' ({3})'; From 74a72c844ceb38f9a9e01e9060679cd4aa650a5f Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 19 Sep 2019 11:56:06 +0200 Subject: [PATCH 102/259] Fixed a crash on checks with identical naming --- lib/icinga/plugin/New-IcingaCheckPackage.psm1 | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 index 18c6c1b..8cf4a08 100644 --- a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 +++ b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 @@ -215,7 +215,19 @@ function New-IcingaCheckPackage() [hashtable]$MessageOrdering = @{}; foreach ($check in $this.checks) { - $MessageOrdering.Add($check.name, $check); + if ($MessageOrdering.ContainsKey($check.Name) -eq $FALSE) { + $MessageOrdering.Add($check.name, $check); + } else { + [int]$DuplicateKeyIndex = 1; + while ($TRUE) { + $newCheckName = [string]::Format('{0}[{1}]', $check.Name, $DuplicateKeyIndex); + if ($MessageOrdering.ContainsKey($newCheckName) -eq $FALSE) { + $MessageOrdering.Add($newCheckName, $check); + break; + } + $DuplicateKeyIndex += 1; + } + } } $SortedArray = $MessageOrdering.GetEnumerator() | Sort-Object name; From ee642050a75e46f5a1dbd1c4285d5786f2764754 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 19 Sep 2019 11:56:32 +0200 Subject: [PATCH 103/259] Improved EventLog output --- lib/plugins/Invoke-IcingaCheckEventlog.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 index dd150b8..599ef04 100644 --- a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 +++ b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 @@ -29,7 +29,7 @@ function Invoke-IcingaCheckEventlog() if ($EventLogData.eventlog.Count -ne 0) { foreach ($event in $EventLogData.eventlog.Keys) { $eventEntry = $EventLogData.eventlog[$event]; - $EventLogEntryPackage = New-IcingaCheckPackage -Name ([string]::Format('Between: {0}-{1} there occured {2} event(s). Message: "{3}" {4}', $eventEntry.OldestEntry, $eventEntry.NewestEntry, $eventEntry.Count, $eventEntry.Severity, $eventEntry.Message)) -OperatorAnd -Verbose $Verbose; + $EventLogEntryPackage = New-IcingaCheckPackage -Name ([string]::Format('Between: [{0}] - [{1}] there occured {2} event(s).', $eventEntry.OldestEntry, $eventEntry.NewestEntry, $eventEntry.Count)) -OperatorAnd -Verbose $Verbose; $IcingaCheck = New-IcingaCheck -Name ([string]::Format('EventId {0}', $EventLogData.eventlog[$event].EventId)) -NoPerfData; $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; $EventLogEntryPackage.AddCheck($IcingaCheck); @@ -37,7 +37,7 @@ function Invoke-IcingaCheckEventlog() $EventLogPackage.AddCheck($EventLogEntryPackage); } - $EventLogCountPackage = New-IcingaCheckPackage -Name 'EventLog Count' -OperatorAnd -Verbose $Verbose; + $EventLogCountPackage = New-IcingaCheckPackage -Name 'EventLog Count' -OperatorAnd -Verbose $Verbose -Hidden; foreach ($event in $EventLogData.events.Keys) { $IcingaCheck = New-IcingaCheck -Name ([string]::Format('EventId {0}', $event)) -Value $EventLogData.events[$event] -Unit 'c'; From 18e6c6574472c8eb5f637fa942c6c55089250b99 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 19 Sep 2019 12:08:01 +0200 Subject: [PATCH 104/259] Fixed missing EventLog Check input for count on value --- lib/plugins/Invoke-IcingaCheckEventlog.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 index 599ef04..522c4db 100644 --- a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 +++ b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 @@ -30,7 +30,7 @@ function Invoke-IcingaCheckEventlog() foreach ($event in $EventLogData.eventlog.Keys) { $eventEntry = $EventLogData.eventlog[$event]; $EventLogEntryPackage = New-IcingaCheckPackage -Name ([string]::Format('Between: [{0}] - [{1}] there occured {2} event(s).', $eventEntry.OldestEntry, $eventEntry.NewestEntry, $eventEntry.Count)) -OperatorAnd -Verbose $Verbose; - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('EventId {0}', $EventLogData.eventlog[$event].EventId)) -NoPerfData; + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('EventId {0}', $EventLogData.eventlog[$event].EventId)) -Value $eventEntry.Count -NoPerfData; $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; $EventLogEntryPackage.AddCheck($IcingaCheck); From d3d1a9d238606746b3596bd654a8f2ee14b0c550 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 19 Sep 2019 12:26:48 +0200 Subject: [PATCH 105/259] Added exception handling on creating cache files --- lib/core/cache/Set-IcingaCacheData.psm1 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/core/cache/Set-IcingaCacheData.psm1 b/lib/core/cache/Set-IcingaCacheData.psm1 index 8c66a88..bdf3a36 100644 --- a/lib/core/cache/Set-IcingaCacheData.psm1 +++ b/lib/core/cache/Set-IcingaCacheData.psm1 @@ -13,7 +13,12 @@ function Set-IcingaCacheData() if ((Test-Path $CacheFile)) { $cacheData = Get-IcingaCacheData -Space $Space -CacheStore $CacheStore; } else { - New-Item -Path $CacheFile -Force | Out-Null; + try { + New-Item -Path $CacheFile -Force | Out-Null; + } catch { + Exit-IcingaThrowException -InputString $_.Exception -CustomMessage (Get-IcingaCacheDir) -StringPattern 'NewItemUnauthorizedAccessError' -ExceptionType 'Permission' -ExceptionThrown $IcingaExceptions.Permission.CacheFolder; + Exit-IcingaThrowException -CustomMessage $_.Exception -ExceptionType 'Unhandled' -Force; + } } if ($null -eq $cacheData -or $cacheData.Count -eq 0) { From 90d9eed8ef19895c0dee9c8d5cca1ae0fc4da831 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 19 Sep 2019 16:22:05 +0200 Subject: [PATCH 106/259] Fixed issue on opening new check commands with default Editor --- lib/core/tools/New-IcingaCheckCommand.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/tools/New-IcingaCheckCommand.psm1 b/lib/core/tools/New-IcingaCheckCommand.psm1 index 3f4070d..2790c92 100644 --- a/lib/core/tools/New-IcingaCheckCommand.psm1 +++ b/lib/core/tools/New-IcingaCheckCommand.psm1 @@ -78,7 +78,7 @@ function New-IcingaCheckCommand() # Try to open the default Editor for the new Cmdlet $DefaultEditor = (Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.psm1\OpenWithList' -Name a).a; - #$DefaultEditor = $DefaultEditor.Replace('.exe', ''); + $DefaultEditor = $DefaultEditor.Replace('.exe', ''); Write-Host ([string]::IsNullOrEmpty($DefaultEditor)); Write-Host ((Get-Command $DefaultEditor -ErrorAction SilentlyContinue)); From 1c75a4d25f2f27757efe7881c4968f7925f9115b Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 23 Sep 2019 17:48:33 +0200 Subject: [PATCH 107/259] Removed accidentaly added cache file --- ...01841216379518196991491710121821213111390108.lastcheck.json | 3 --- 1 file changed, 3 deletions(-) delete mode 100644 cache/provider/eventlog/1781451901841216379518196991491710121821213111390108.lastcheck.json diff --git a/cache/provider/eventlog/1781451901841216379518196991491710121821213111390108.lastcheck.json b/cache/provider/eventlog/1781451901841216379518196991491710121821213111390108.lastcheck.json deleted file mode 100644 index 599898a..0000000 --- a/cache/provider/eventlog/1781451901841216379518196991491710121821213111390108.lastcheck.json +++ /dev/null @@ -1,3 +0,0 @@ -{ - "1781451901841216379518196991491710121821213111390108.lastcheck": 132132048543175098 -} From 5e6f4e5c7f853d9956e8854c557b4930fffc33b2 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 25 Sep 2019 19:17:42 +0200 Subject: [PATCH 108/259] Fixed argument type of DisableTimeCache for EventLog check --- lib/plugins/Invoke-IcingaCheckEventlog.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 index 522c4db..a3e7037 100644 --- a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 +++ b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 @@ -16,7 +16,7 @@ function Invoke-IcingaCheckEventlog() [array]$ExcludeMessage, $After = $null, $Before = $null, - [bool]$DisableTimeCache, + [switch]$DisableTimeCache = $FALSE, [switch]$NoPerfData, $Verbose ); From 289b1a1ed5fdcc32aecc28415ee2fcbe631db522 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 25 Sep 2019 19:30:02 +0200 Subject: [PATCH 109/259] Ensured custom_vars Variable Part is always identical --- lib/core/tools/Get-IcingaCheckCommandConfig.psm1 | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 index 4c0a485..4854b5e 100644 --- a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 +++ b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 @@ -162,7 +162,7 @@ function Get-IcingaCheckCommandConfig() [string]$Order = 99 } - $IcingaCustomVariable = [string]::Format('$PowerShell_{0}_{1}$', $parameter.type.name, $parameter.Name); + $IcingaCustomVariable = [string]::Format('$PowerShell_{0}_{1}$', (Get-Culture).TextInfo.ToTitleCase($parameter.type.name), $parameter.Name); # Todo: Should we improve this? Actually the handling would be identical, we just need to assign # the proper field for this @@ -222,7 +222,7 @@ function Get-IcingaCheckCommandConfig() $Required = 'n'; } - $IcingaCustomVariable = [string]::Format('PowerShell_{0}_{1}', $parameter.type.name, $parameter.Name); + $IcingaCustomVariable = [string]::Format('PowerShell_{0}_{1}', (Get-Culture).TextInfo.ToTitleCase($parameter.type.name), $parameter.Name); # Todo: Should we improve this? Actually the handling would be identical, we just need to assign # the proper field for this @@ -263,7 +263,7 @@ function Get-IcingaCheckCommandConfig() if($Basket.Datafield.ContainsKey('0') -eq $FALSE){ $Basket.Datafield.Add( '0', @{ - 'varname' = 'PowerShell_switch_NoPerfData'; + 'varname' = 'PowerShell_Switch_NoPerfData'; 'caption' = 'Ignore Performance Data'; 'description' = 'Specifies if the plugin will return performance data output or not'; 'datatype' = 'Icinga\Module\Director\DataType\DataTypeBoolean'; @@ -372,12 +372,12 @@ function Get-IcingaCheckCommandConfig() if ($Basket.Command[$Data.Name].arguments.ContainsKey('-NoPerfData') -eq $FALSE) { $Basket.Command[$Data.Name].arguments.Add( '-NoPerfData', @{ - 'set_if' = '$PowerShell_switch_NoPerfData$'; + 'set_if' = '$PowerShell_Switch_NoPerfData$'; 'set_if_format' = 'string'; 'order' = '99'; } ); - $Basket.Command[$Data.Name].vars.Add('PowerShell_switch_NoPerfData', $FALSE); + $Basket.Command[$Data.Name].vars.Add('PowerShell_Switch_NoPerfData', $FALSE); } } @@ -386,8 +386,8 @@ function Get-IcingaCheckCommandConfig() $Data = (Get-Help $check) - foreach ($parameter in $Data.parameters.parameter){ - $IcingaCustomVariable = [string]::Format('PowerShell_{0}_{1}', $parameter.type.name, $parameter.Name); + foreach ($parameter in $Data.parameters.parameter) { + $IcingaCustomVariable = [string]::Format('PowerShell_{0}_{1}', (Get-Culture).TextInfo.ToTitleCase($parameter.type.name), $parameter.Name); # Todo: Should we improve this? Actually the handling would be identical, we just need to assign # the proper field for this From dbbb440eac55bcfa50ffd57cc6064bfc820de17d Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 25 Sep 2019 19:55:27 +0200 Subject: [PATCH 110/259] Removed debug output for New-CheckCommand Cmdlet --- lib/core/tools/New-IcingaCheckCommand.psm1 | 4 ---- 1 file changed, 4 deletions(-) diff --git a/lib/core/tools/New-IcingaCheckCommand.psm1 b/lib/core/tools/New-IcingaCheckCommand.psm1 index 2790c92..8fea58e 100644 --- a/lib/core/tools/New-IcingaCheckCommand.psm1 +++ b/lib/core/tools/New-IcingaCheckCommand.psm1 @@ -80,10 +80,6 @@ function New-IcingaCheckCommand() $DefaultEditor = (Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.psm1\OpenWithList' -Name a).a; $DefaultEditor = $DefaultEditor.Replace('.exe', ''); - Write-Host ([string]::IsNullOrEmpty($DefaultEditor)); - Write-Host ((Get-Command $DefaultEditor -ErrorAction SilentlyContinue)); - Write-Host ((Test-Path $DefaultEditor)); - if ([string]::IsNullOrEmpty($DefaultEditor) -eq $FALSE -And ((Get-Command $DefaultEditor -ErrorAction SilentlyContinue) -eq $null) -And ((Test-Path $DefaultEditor) -eq $FALSE)) { Write-Host 'No default editor for .psm1 files found. Specify a default editor to automaticly open the newly generated check plugin.'; return; From 9d4254158ac7ea24cdfa42479dea2f94f07ff451 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 25 Sep 2019 19:56:05 +0200 Subject: [PATCH 111/259] Improved Check-Command config by adding a Base Command --- .../tools/Get-IcingaCheckCommandConfig.psm1 | 35 +++++++++++++------ 1 file changed, 24 insertions(+), 11 deletions(-) diff --git a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 index 4854b5e..6d1afdf 100644 --- a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 +++ b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 @@ -82,6 +82,25 @@ function Get-IcingaCheckCommandConfig() $Basket.Add('DataList', @{}); $Basket.Add('Command', @{}); + # At first generate a base Check-Command we can use as import source for all other commands + $Basket.Command.Add( + 'PowerShell Base', + @{ + 'arguments' = @{}; + 'command' = 'C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe'; + 'disabled' = $FALSE; + 'fields' = @(); + 'imports' = @(); + 'is_string' = $NULL; + 'methods_execute' = 'PluginCheck'; + 'object_name' = 'PowerShell Base'; + 'object_type' = 'object'; + 'timeout' = '180'; + 'vars' = @{}; + 'zone' = $NULL; + } + ); + # "Verbose" gets added to all Checks build and exported no matter what, so we add it from the start if ($Basket.DataList.ContainsKey('PowerShell Verbose') -eq $FALSE) { $Basket.DataList.Add( @@ -128,24 +147,18 @@ function Get-IcingaCheckCommandConfig() # Add command Structure $Basket.Command.Add( $Data.Name, @{ - 'arguments'= @{ - # Gets set for every command as default + 'arguments' = @{ + # Set the Command handling for every check command '-C' = @{ 'value' = [string]::Format('Use-Icinga; {0}', $Data.Name); 'order' = '0'; } } - 'command' = "C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe"; - 'disabled' = $FALSE; - 'fields' = @(); - 'imports' = @(); - 'is_string' = $NULL; - 'methods_execute' = 'PluginCheck'; + 'fields' = @(); + 'imports' = @( 'PowerShell Base' ); 'object_name' = $Data.Name; 'object_type' = 'object'; - 'timeout' = '180'; - 'vars' = @{}; - 'zone' = $NULL; + 'vars' = @{}; } ); From 00102cb9e1ccc3131d9b3d4a75d3ba361321b8b8 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 25 Sep 2019 19:57:19 +0200 Subject: [PATCH 112/259] Check Commands will now return their Exit Code instead of exiting --- lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 | 2 +- lib/plugins/Invoke-IcingaCheckCPU.psm1 | 2 +- lib/plugins/Invoke-IcingaCheckEventlog.psm1 | 2 +- lib/plugins/Invoke-IcingaCheckProcessCount.psm1 | 2 +- lib/plugins/Invoke-IcingaCheckService.psm1 | 2 +- lib/plugins/Invoke-IcingaCheckUpdates.psm1 | 2 +- lib/plugins/Invoke-IcingaCheckUptime.psm1 | 2 +- lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 | 2 +- lib/plugins/Invoke-IcingaCheckUsers.psm1 | 2 +- 9 files changed, 9 insertions(+), 9 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 b/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 index 0517022..8f71fb7 100644 --- a/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 +++ b/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 @@ -4,5 +4,5 @@ function Invoke-IcingaCheckBiosSerial() { $Bios = Get-IcingaBiosSerialNumber; $BiosCheck = New-IcingaCheck -Name $Bios.Name -Value $Bios.Value -NoPerfData; - exit (New-IcingaCheckresult -Check $BiosCheck -NoPerfData $TRUE -Compile); + return (New-IcingaCheckresult -Check $BiosCheck -NoPerfData $TRUE -Compile); } diff --git a/lib/plugins/Invoke-IcingaCheckCPU.psm1 b/lib/plugins/Invoke-IcingaCheckCPU.psm1 index 189649b..da6fc66 100644 --- a/lib/plugins/Invoke-IcingaCheckCPU.psm1 +++ b/lib/plugins/Invoke-IcingaCheckCPU.psm1 @@ -28,5 +28,5 @@ function Invoke-IcingaCheckCPU() $CpuPackage.AddCheck($IcingaCheck); } - exit (New-IcingaCheckResult -Name 'CPU Load' -Check $CpuPackage -NoPerfData $NoPerfData -Compile); + return (New-IcingaCheckResult -Name 'CPU Load' -Check $CpuPackage -NoPerfData $NoPerfData -Compile); } diff --git a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 index a3e7037..09c1fc6 100644 --- a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 +++ b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 @@ -50,5 +50,5 @@ function Invoke-IcingaCheckEventlog() $EventLogPackage.AddCheck($IcingaCheck); } - exit (New-IcingaCheckResult -Name 'EventLog' -Check $EventLogPackage -NoPerfData $NoPerfData -Compile); + return (New-IcingaCheckResult -Name 'EventLog' -Check $EventLogPackage -NoPerfData $NoPerfData -Compile); } diff --git a/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 b/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 index 0efd0f0..fba2d26 100644 --- a/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 +++ b/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 @@ -30,5 +30,5 @@ function Invoke-IcingaCheckProcessCount() } - exit (New-IcingaCheckResult -Check $ProcessPackage -NoPerfData $NoPerfData -Compile); + return (New-IcingaCheckResult -Check $ProcessPackage -NoPerfData $NoPerfData -Compile); } diff --git a/lib/plugins/Invoke-IcingaCheckService.psm1 b/lib/plugins/Invoke-IcingaCheckService.psm1 index 3b2c323..4c4fcd4 100644 --- a/lib/plugins/Invoke-IcingaCheckService.psm1 +++ b/lib/plugins/Invoke-IcingaCheckService.psm1 @@ -75,5 +75,5 @@ function Invoke-IcingaCheckService() $ServicesPackage.AddCheck($IcingaCheck); } - exit (New-IcingaCheckResult -Name 'Services' -Check $ServicesPackage -NoPerfData $TRUE -Compile); + return (New-IcingaCheckResult -Name 'Services' -Check $ServicesPackage -NoPerfData $TRUE -Compile); } diff --git a/lib/plugins/Invoke-IcingaCheckUpdates.psm1 b/lib/plugins/Invoke-IcingaCheckUpdates.psm1 index 4b2fbc4..50f1e0b 100644 --- a/lib/plugins/Invoke-IcingaCheckUpdates.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUpdates.psm1 @@ -54,5 +54,5 @@ function Invoke-IcingaCheckUpdates() $UpdatePackage.AddCheck($UpdateList); } - exit (New-IcingaCheckResult -Name 'Pending Updates' -Check $UpdatePackage -NoPerfData $NoPerfData -Compile); + return (New-IcingaCheckResult -Name 'Pending Updates' -Check $UpdatePackage -NoPerfData $NoPerfData -Compile); } diff --git a/lib/plugins/Invoke-IcingaCheckUptime.psm1 b/lib/plugins/Invoke-IcingaCheckUptime.psm1 index 78f685e..ace81c8 100644 --- a/lib/plugins/Invoke-IcingaCheckUptime.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUptime.psm1 @@ -23,5 +23,5 @@ function Invoke-IcingaCheckUptime() $CheckPackage = New-IcingaCheckPackage -Name $Name -OperatorAnd -Checks $IcingaCheck -Verbose $Verbose; - exit (New-IcingaCheckresult -Check $CheckPackage -NoPerfData $NoPerfData -Compile); + return (New-IcingaCheckresult -Check $CheckPackage -NoPerfData $NoPerfData -Compile); } diff --git a/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 b/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 index 5c05c86..baed4c8 100644 --- a/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 @@ -36,5 +36,5 @@ function Invoke-IcingaCheckUsedPartitionSpace() $DiskPackage.AddCheck($IcingaCheck); } - exit (New-IcingaCheckResult -Check $DiskPackage -NoPerfData $NoPerfData -Compile); + return (New-IcingaCheckResult -Check $DiskPackage -NoPerfData $NoPerfData -Compile); } diff --git a/lib/plugins/Invoke-IcingaCheckUsers.psm1 b/lib/plugins/Invoke-IcingaCheckUsers.psm1 index 1b43dcc..370f9c9 100644 --- a/lib/plugins/Invoke-IcingaCheckUsers.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUsers.psm1 @@ -38,5 +38,5 @@ function Invoke-IcingaCheckUsers() $UsersPackage.AddCheck($IcingaCheck) } - exit (New-IcingaCheckResult -Name 'Users' -Check $UsersPackage -NoPerfData $NoPerfData -Compile); + return (New-IcingaCheckResult -Name 'Users' -Check $UsersPackage -NoPerfData $NoPerfData -Compile); } From 753659f4d1b0d60317c74d2b7cb0b884b88d1b17 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 25 Sep 2019 19:57:31 +0200 Subject: [PATCH 113/259] Fixed code styling --- lib/provider/eventlog/Get-IcingaEventLog.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/provider/eventlog/Get-IcingaEventLog.psm1 b/lib/provider/eventlog/Get-IcingaEventLog.psm1 index 5a284d5..d4fb878 100644 --- a/lib/provider/eventlog/Get-IcingaEventLog.psm1 +++ b/lib/provider/eventlog/Get-IcingaEventLog.psm1 @@ -54,7 +54,7 @@ function Get-IcingaEventLog() } try { - $events = Get-EventLog @EventLogArguments; + $events = Get-EventLog @EventLogArguments; } catch { Exit-IcingaThrowException -InputString $_.Exception -StringPattern 'ParameterBindingValidationException' -ExceptionType 'Input' -ExceptionThrown $IcingaExceptions.Inputs.EventLog; Exit-IcingaThrowException -InputString $_.Exception -StringPattern 'System.InvalidOperationException' -CustomMessage (-Join $LogName) -ExceptionType 'Input' -ExceptionThrown $IcingaExceptions.Inputs.EventLogLogName; From 77d182bbdaa5102490dba013b156138b54c41055 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 25 Sep 2019 19:58:37 +0200 Subject: [PATCH 114/259] Added Service User to Service provider for each service --- .../services/Icinga_ProviderServices.psm1 | 44 ++++++++++++++----- 1 file changed, 32 insertions(+), 12 deletions(-) diff --git a/lib/provider/services/Icinga_ProviderServices.psm1 b/lib/provider/services/Icinga_ProviderServices.psm1 index 8774868..74d66a4 100644 --- a/lib/provider/services/Icinga_ProviderServices.psm1 +++ b/lib/provider/services/Icinga_ProviderServices.psm1 @@ -5,6 +5,13 @@ function Get-IcingaServices() ) $ServiceInformation = Get-Service -Name $Service -ErrorAction SilentlyContinue; + $ServiceWmiInfo = $null; + + if ($Service.Count -eq 0) { + $ServiceWmiInfo = Get-WmiObject Win32_Service; + } else { + $ServiceWmiInfo = Get-WmiObject -Class Win32_Service | Where-Object { $Service -Contains $_.Name } | Select-Object StartName, Name; + } if ($null -eq $ServiceInformation) { return $null; @@ -14,20 +21,32 @@ function Get-IcingaServices() foreach ($service in $ServiceInformation) { - [array]$DependentServices = $null; - [array]$DependingServices = $null; + [array]$DependentServices = $null; + [array]$DependingServices = $null; + [string]$ServiceUser = ''; - #Dependent / Child - foreach ($dependency in $service.DependentServices) { - if ($null -eq $DependentServices) { $DependentServices = @(); } - $DependentServices += $dependency.Name; - } - - #Depends / Parent - foreach ($dependency in $service.ServicesDependedOn) { - if ($null -eq $DependingServices) { $DependingServices = @(); } + foreach ($wmiService in $ServiceWmiInfo) { + if ($wmiService.Name -eq $service.ServiceName) { + $ServiceUser = $wmiService.StartName; + break; + } + } + + #Dependent / Child + foreach ($dependency in $service.DependentServices) { + if ($null -eq $DependentServices) { + $DependentServices = @(); + } + $DependentServices += $dependency.Name; + } + + #Depends / Parent + foreach ($dependency in $service.ServicesDependedOn) { + if ($null -eq $DependingServices) { + $DependingServices = @(); + } $DependingServices += $dependency.Name; - } + } $ServiceData.Add( $service.Name, @{ @@ -57,6 +76,7 @@ function Get-IcingaServices() 'raw' = [int]$service.StartType; 'value' = $service.StartType; }; + 'ServiceUser' = $ServiceUser; } } ); From 089ad30171de6f464c3306e1af9e3230bca87f9b Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 25 Sep 2019 20:02:42 +0200 Subject: [PATCH 115/259] Added exit statement for command execution --- lib/core/tools/Get-IcingaCheckCommandConfig.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 index 6d1afdf..bbfedcd 100644 --- a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 +++ b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 @@ -150,7 +150,7 @@ function Get-IcingaCheckCommandConfig() 'arguments' = @{ # Set the Command handling for every check command '-C' = @{ - 'value' = [string]::Format('Use-Icinga; {0}', $Data.Name); + 'value' = [string]::Format('Use-Icinga; exit {0}', $Data.Name); 'order' = '0'; } } From 3ec2f44fedb4e0fe844bd7e9bb4b2739d8e8c623 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 25 Sep 2019 20:18:27 +0200 Subject: [PATCH 116/259] Added more details for new Check Plugin Command as starting point --- lib/core/tools/New-IcingaCheckCommand.psm1 | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/lib/core/tools/New-IcingaCheckCommand.psm1 b/lib/core/tools/New-IcingaCheckCommand.psm1 index 8fea58e..56c8a92 100644 --- a/lib/core/tools/New-IcingaCheckCommand.psm1 +++ b/lib/core/tools/New-IcingaCheckCommand.psm1 @@ -6,7 +6,7 @@ function New-IcingaCheckCommand() 'Warning', 'Critical', '[switch]NoPerfData', - 'Verbose' + '[int]Verbose' ), [array]$ImportLib = @() ); @@ -72,6 +72,14 @@ function New-IcingaCheckCommand() } Add-Content -Path $ScriptFile -Value ""; + Add-Content -Path $ScriptFile -Value ' <# Icinga Basic Check-Plugin Template. Below you will find an example structure. #>'; + Add-Content -Path $ScriptFile -Value ([string]::Format(' $CheckPackage = New-IcingaCheckPackage -Name {0}New Package{0} -OperatorAnd -Verbose $Verbose;', "'")); + Add-Content -Path $ScriptFile -Value ([string]::Format(' $IcingaCheck = New-IcingaCheck -Name {0}New Check{0} -Value 10 -Unit {0}%{0}', "'")); + Add-Content -Path $ScriptFile -Value ([string]::Format(' $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null;', "'")); + Add-Content -Path $ScriptFile -Value ([string]::Format(' $CheckPackage.AddCheck($IcingaCheck);', "'")); + Add-Content -Path $ScriptFile -Value ""; + Add-Content -Path $ScriptFile -Value ([string]::Format(' return (New-IcingaCheckresult -Check $CheckPackage -NoPerfData $NoPerfData -Compile);', "'")); + Add-Content -Path $ScriptFile -Value "}"; Write-Host ([string]::Format('The Check-Command "{0}" was successfully added.', $CommandName)); @@ -80,6 +88,8 @@ function New-IcingaCheckCommand() $DefaultEditor = (Get-ItemProperty -Path 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FileExts\.psm1\OpenWithList' -Name a).a; $DefaultEditor = $DefaultEditor.Replace('.exe', ''); + Import-Module $ScriptFile -Global; + if ([string]::IsNullOrEmpty($DefaultEditor) -eq $FALSE -And ((Get-Command $DefaultEditor -ErrorAction SilentlyContinue) -eq $null) -And ((Test-Path $DefaultEditor) -eq $FALSE)) { Write-Host 'No default editor for .psm1 files found. Specify a default editor to automaticly open the newly generated check plugin.'; return; From e345c61cdc172bcd776110ce70ca1fd4c13c8e8b Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 25 Sep 2019 20:22:44 +0200 Subject: [PATCH 117/259] Improved framework loading speed and overhead --- icinga-module-windows.psm1 | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/icinga-module-windows.psm1 b/icinga-module-windows.psm1 index 7de4f52..a03a454 100644 --- a/icinga-module-windows.psm1 +++ b/icinga-module-windows.psm1 @@ -13,6 +13,7 @@ function Use-Icinga() { # This function will allow us to load this entire module including possible # actions, making it available within our shell environment + Import-IcingaLib '\' -Init; } function Import-IcingaLib() @@ -27,9 +28,16 @@ function Import-IcingaLib() [String]$Lib, # The Force Reload will remove the module in case it's loaded and reload it to track # possible development changes without having to create new PowerShell environments - [Switch]$ForceReload + [Switch]$ForceReload, + [switch]$Init ); + # This is just to only allow a global loading of the module. Import-IcingaLib is ignored on every other + # location. It is just there to give a basic idea within commands, of which functions are used + if ($Init -eq $FALSE) { + return; + } + [string]$directory = Join-Path -Path $PSScriptRoot -ChildPath 'lib\'; [string]$module = Join-Path -Path $directory -ChildPath $Lib; [string]$moduleName = ''; @@ -38,6 +46,7 @@ function Import-IcingaLib() # Load modules from directory if ((Test-Path $module -PathType Container)) { + Get-ChildItem -Path $module -Recurse -Filter *.psm1 | ForEach-Object { [string]$modulePath = $_.FullName; @@ -344,9 +353,6 @@ function Get-Icinga-Object() return $Icinga2; } -# Automaticly load all library modules -Import-IcingaLib '\'; - # Initialise base configuration for our module <# $Icinga2 = & (Join-Path -Path $PSScriptRoot -ChildPath '\core\init.ps1') ` From cde7748368c4238a248c440c8acd575aae700214 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 28 Sep 2019 21:45:59 +0200 Subject: [PATCH 118/259] Prepared check plugin and perf-data output for daemon integration --- lib/icinga/plugin/New-IcingaCheck.psm1 | 20 ++++++-- lib/icinga/plugin/New-IcingaCheckPackage.psm1 | 50 ++++++++++++------- lib/icinga/plugin/New-IcingaCheckResult.psm1 | 5 +- .../plugin/Write-IcingaPluginOutput.psm1 | 8 +++ .../plugin/Write-IcingaPluginPerfData.psm1 | 32 ++++++++++++ 5 files changed, 92 insertions(+), 23 deletions(-) create mode 100644 lib/icinga/plugin/Write-IcingaPluginOutput.psm1 create mode 100644 lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 diff --git a/lib/icinga/plugin/New-IcingaCheck.psm1 b/lib/icinga/plugin/New-IcingaCheck.psm1 index 590ca32..35be1e5 100644 --- a/lib/icinga/plugin/New-IcingaCheck.psm1 +++ b/lib/icinga/plugin/New-IcingaCheck.psm1 @@ -36,11 +36,18 @@ function New-IcingaCheck() $Check | Add-Member -membertype NoteProperty -name 'translation' -value $Translation; $Check | Add-Member -membertype NoteProperty -name 'checks' -value $null; $Check | Add-Member -membertype NoteProperty -name 'completed' -value $FALSE; + $Check | Add-Member -membertype NoteProperty -name 'checkcommand' -value ''; $Check | Add-Member -membertype ScriptMethod -name 'AddSpacing' -value { $this.spacing += 1; } + $Check | Add-Member -membertype ScriptMethod -name 'AssignCheckCommand' -value { + param($CheckCommand); + + $this.checkcommand = $CheckCommand; + } + $Check | Add-Member -membertype ScriptMethod -name 'WarnOutOfRange' -value { param($warning); @@ -525,7 +532,7 @@ function New-IcingaCheck() param($msgArray, [string]$spaces); foreach ($msg in $msgArray) { - Write-Host ([string]::Format('{0}{1}', $spaces, $msg)); + Write-IcingaPluginOutput ([string]::Format('{0}{1}', $spaces, $msg)); } } @@ -651,8 +658,8 @@ function New-IcingaCheck() [string]$LabelName = (Format-IcingaPerfDataLabel $this.name); return @{ - 'label' = $LabelName; - 'perfdata' = [string]::Format( + 'label' = $LabelName; + 'perfdata' = [string]::Format( "'{0}'={1}{2};{3};{4}{5}{6} ", $LabelName, (Format-IcingaPerfDataValue $this.value), @@ -662,6 +669,13 @@ function New-IcingaCheck() (Format-IcingaPerfDataValue $this.minimum), (Format-IcingaPerfDataValue $this.maximum) ); + 'unit' = $this.unit; + 'value' = (Format-IcingaPerfDataValue $this.value); + 'warning' = (Format-IcingaPerfDataValue $this.warning); + 'critical' = (Format-IcingaPerfDataValue $this.critical); + 'minimum' = (Format-IcingaPerfDataValue ($this.minimum).Replace(';', '')); + 'maximum' = (Format-IcingaPerfDataValue ($this.maximum).Replace(';', '')); + 'package' = $FALSE; }; } diff --git a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 index 8cf4a08..9c2b33e 100644 --- a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 +++ b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 @@ -16,19 +16,20 @@ function New-IcingaCheckPackage() ); $Check = New-Object -TypeName PSObject; - $Check | Add-Member -membertype NoteProperty -name 'name' -value $Name; - $Check | Add-Member -membertype NoteProperty -name 'exitcode' -value -1; - $Check | Add-Member -membertype NoteProperty -name 'verbose' -value $Verbose; - $Check | Add-Member -membertype NoteProperty -name 'hidden' -value $Hidden; - $Check | Add-Member -membertype NoteProperty -name 'checks' -value $Checks; - $Check | Add-Member -membertype NoteProperty -name 'opand' -value $OperatorAnd; - $Check | Add-Member -membertype NoteProperty -name 'opor' -value $OperatorOr; - $Check | Add-Member -membertype NoteProperty -name 'opnone' -value $OperatorNone; - $Check | Add-Member -membertype NoteProperty -name 'opmin' -value $OperatorMin; - $Check | Add-Member -membertype NoteProperty -name 'opmax' -value $OperatorMax; - $Check | Add-Member -membertype NoteProperty -name 'spacing' -value 0; - $Check | Add-Member -membertype NoteProperty -name 'compiled' -value $FALSE; - $Check | Add-Member -membertype NoteProperty -name 'perfdata' -value $FALSE; + $Check | Add-Member -membertype NoteProperty -name 'name' -value $Name; + $Check | Add-Member -membertype NoteProperty -name 'exitcode' -value -1; + $Check | Add-Member -membertype NoteProperty -name 'verbose' -value $Verbose; + $Check | Add-Member -membertype NoteProperty -name 'hidden' -value $Hidden; + $Check | Add-Member -membertype NoteProperty -name 'checks' -value $Checks; + $Check | Add-Member -membertype NoteProperty -name 'opand' -value $OperatorAnd; + $Check | Add-Member -membertype NoteProperty -name 'opor' -value $OperatorOr; + $Check | Add-Member -membertype NoteProperty -name 'opnone' -value $OperatorNone; + $Check | Add-Member -membertype NoteProperty -name 'opmin' -value $OperatorMin; + $Check | Add-Member -membertype NoteProperty -name 'opmax' -value $OperatorMax; + $Check | Add-Member -membertype NoteProperty -name 'spacing' -value 0; + $Check | Add-Member -membertype NoteProperty -name 'compiled' -value $FALSE; + $Check | Add-Member -membertype NoteProperty -name 'perfdata' -value $FALSE; + $Check | Add-Member -membertype NoteProperty -name 'checkcommand' -value ''; $Check | Add-Member -membertype ScriptMethod -name 'Initialise' -value { foreach ($check in $this.checks) { @@ -67,6 +68,16 @@ function New-IcingaCheckPackage() $this.checks += $check; } + $Check | Add-Member -membertype ScriptMethod -name 'AssignCheckCommand' -value { + param($CheckCommand); + + $this.checkcommand = $CheckCommand; + + foreach ($check in $this.checks) { + $check.AssignCheckCommand($CheckCommand); + } + } + $Check | Add-Member -membertype ScriptMethod -name 'Compile' -value { param([bool]$Verbose); @@ -137,7 +148,7 @@ function New-IcingaCheckPackage() $Check | Add-Member -membertype ScriptMethod -name 'CheckMinimumOk' -value { if ($this.opmin -gt $this.checks.Count) { - Write-Host ([string]::Format( + Write-IcingaPluginOutput ([string]::Format( 'Unknown: The minimum argument ({0}) is exceeding the amount of assigned checks ({1}) to this package "{2}"', $this.opmin, $this.checks.Count, $this.name )); @@ -156,7 +167,7 @@ function New-IcingaCheckPackage() $Check | Add-Member -membertype ScriptMethod -name 'CheckMaximumOk' -value { if ($this.opmax -gt $this.checks.Count) { - Write-Host ([string]::Format( + Write-IcingaPluginOutput ([string]::Format( 'Unknown: The maximum argument ({0}) is exceeding the amount of assigned checks ({1}) to this package "{2}"', $this.opmax, $this.checks.Count, $this.name )); @@ -259,7 +270,7 @@ function New-IcingaCheckPackage() $Check | Add-Member -membertype ScriptMethod -name 'PrintNoChecksConfigured' -value { if ($this.checks.Count -eq 0) { - Write-Host ( + Write-IcingaPluginOutput ( [string]::Format( '{0}{1}: No checks configured for package "{2}"', (New-StringTree ($this.spacing + 1)), @@ -281,7 +292,7 @@ function New-IcingaCheckPackage() $outputMessage += ' ({3})'; } - Write-Host ( + Write-IcingaPluginOutput ( [string]::Format( $outputMessage, (New-StringTree $this.spacing), @@ -350,7 +361,7 @@ function New-IcingaCheckPackage() continue; } - $CollectedPerfData.Add($data.label, $data.perfdata); + $CollectedPerfData.Add($data.label, $data); } # Now sort the label output by name @@ -363,7 +374,8 @@ function New-IcingaCheckPackage() return @{ 'label' = $this.name; - 'perfdata' = $perfData; + 'perfdata' = $CollectedPerfData; + 'package' = $TRUE; } } diff --git a/lib/icinga/plugin/New-IcingaCheckResult.psm1 b/lib/icinga/plugin/New-IcingaCheckResult.psm1 index 5e07112..e7bc075 100644 --- a/lib/icinga/plugin/New-IcingaCheckResult.psm1 +++ b/lib/icinga/plugin/New-IcingaCheckResult.psm1 @@ -17,11 +17,14 @@ function New-IcingaCheckresult() return $IcingaEnums.IcingaExitCode.Unknown; } + $CheckCommand = (Get-PSCallStack)[1].Command; + # Compile the check / package if not already done + $this.check.AssignCheckCommand($CheckCommand); $this.check.Compile($TRUE) | Out-Null; if ([int]$this.check.exitcode -ne [int]$IcingaEnums.IcingaExitCode.Unknown -And -Not $this.noperfdata) { - Write-Host ([string]::Format('| {0}', $this.check.GetPerfData().perfdata)); + Write-IcingaPluginPerfData ($this.check.GetPerfData().perfdata); } return $this.check.exitcode; diff --git a/lib/icinga/plugin/Write-IcingaPluginOutput.psm1 b/lib/icinga/plugin/Write-IcingaPluginOutput.psm1 new file mode 100644 index 0000000..e698671 --- /dev/null +++ b/lib/icinga/plugin/Write-IcingaPluginOutput.psm1 @@ -0,0 +1,8 @@ +function Write-IcingaPluginOutput() +{ + param( + $Output + ); + + Write-Host $Output; +} diff --git a/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 b/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 new file mode 100644 index 0000000..caab482 --- /dev/null +++ b/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 @@ -0,0 +1,32 @@ +function Write-IcingaPluginPerfData() +{ + param( + $PerformanceData + ); + + [string]$PerfDataOutput = (Get-IcingaPluginPerfDataContent -PerfData $PerformanceData); + Write-Host ([string]::Format('| {0}', $PerfDataOutput)); +} + +function Get-IcingaPluginPerfDataContent() +{ + param( + $PerfData, + [bool]$AsObject = $FALSE + ); + + [string]$PerfDataOutput = ''; + + foreach ($package in $PerfData.Keys) { + $data = $PerfData[$package]; + if ($data.package) { + $PerfDataOutput += (Get-IcingaPluginPerfDataContent -PerfData $data.perfdata -AsObject $AsObject); + } else { + $PerfDataOutput += $data.perfdata; + } + } + + return $PerfDataOutput; +} + +Export-ModuleMember -Function @( 'Write-IcingaPluginPerfData' ); From 64a505410806ff9fcb3126cb8ead6f126eb20dc3 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 28 Sep 2019 21:47:44 +0200 Subject: [PATCH 119/259] Added tool function to get Unix Time --- lib/core/tools/Get-IcingaUnixTime.psm1 | 4 ++++ 1 file changed, 4 insertions(+) create mode 100644 lib/core/tools/Get-IcingaUnixTime.psm1 diff --git a/lib/core/tools/Get-IcingaUnixTime.psm1 b/lib/core/tools/Get-IcingaUnixTime.psm1 new file mode 100644 index 0000000..dd61e8c --- /dev/null +++ b/lib/core/tools/Get-IcingaUnixTime.psm1 @@ -0,0 +1,4 @@ +function Get-IcingaUnixTime() +{ + return [int][double]::Parse((Get-Date -UFormat %s)) +} From 3b9f66d67962cccf4f1d359c5892cf79d2c9e7a6 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 29 Sep 2019 18:18:31 +0200 Subject: [PATCH 120/259] Added tool function to split IP and Port from strings --- lib/core/tools/Get-IPConfigFromString.psm1 | 37 ++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 lib/core/tools/Get-IPConfigFromString.psm1 diff --git a/lib/core/tools/Get-IPConfigFromString.psm1 b/lib/core/tools/Get-IPConfigFromString.psm1 new file mode 100644 index 0000000..8ef5e19 --- /dev/null +++ b/lib/core/tools/Get-IPConfigFromString.psm1 @@ -0,0 +1,37 @@ +function Get-IPConfigFromString() +{ + param( + [string]$IPConfig + ); + + if ($IPConfig.Contains(':') -and ($IPConfig.Contains('[') -eq $FALSE -And $IPConfig.Contains(']') -eq $FALSE)) { + throw 'Invalid IP-Address format. For IPv6 and/or port configuration, the syntax must be like [ip]:port'; + } + + if ($IPConfig.Contains('[') -eq $FALSE) { + return @{ + 'address' = $IPConfig; + 'port' = $null + }; + } + + if ($IPConfig.Contains('[') -eq $FALSE -or $IPConfig.Contains(']') -eq $FALSE) { + throw 'Invalid IP-Address format. It must match the following [ip]:port'; + } + + $StartBracket = $IPConfig.IndexOf('[') + 1; + $EndBracket = $IPConfig.IndexOf(']') - 1; + $PortDelimeter = $IPConfig.LastIndexOf(':') + 1; + + $Port = ''; + $IP = $IPConfig.Substring($StartBracket, $EndBracket); + + if ($PortDelimeter -ne 0 -And $PortDelimeter -ge $EndBracket) { + $Port = $IPConfig.Substring($PortDelimeter, $IPConfig.Length - $PortDelimeter); + } + + return @{ + 'address' = $IP; + 'port' = $Port + }; +} From c209e2fb6e6591883682338ab28ec45540e30710 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 29 Sep 2019 18:25:40 +0200 Subject: [PATCH 121/259] Added Icinga Agent management Cmdlets --- .../getters/Get-IcingaAgentArchitecture.psm1 | 6 + .../getters/Get-IcingaAgentBinary.psm1 | 11 + .../Get-IcingaAgentConfigDirectory.psm1 | 4 + .../getters/Get-IcingaAgentFeatures.psm1 | 20 ++ .../getters/Get-IcingaAgentInstallation.psm1 | 40 ++++ .../getters/Get-IcingaAgentLogDirectory.psm1 | 4 + .../getters/Get-IcingaAgentMSIPackage.psm1 | 73 ++++++ .../getters/Get-IcingaAgentRootDirectory.psm1 | 9 + .../getters/Get-IcingaAgentVersion.psm1 | 6 + .../getters/Get-IcingaHostname.psm1 | 27 +++ .../getters/Get-IcingaServiceUser.psm1 | 11 + .../installer/Install-IcingaAgent.psm1 | 78 ++++++ .../Install-IcingaAgentBaseFeatures.psm1 | 5 + .../Install-IcingaAgentCertificates.psm1 | 224 ++++++++++++++++++ .../installer/Uninstall-IcingaAgent.psm1 | 21 ++ .../misc/Compare-IcingaVersions.psm1 | 33 +++ .../misc/Disable-IcingaAgentFeature.psm1 | 24 ++ .../misc/Enable-IcingaAgentFeature.psm1 | 24 ++ .../misc/Move-IcingaAgentDefaultConfig.psm1 | 23 ++ .../misc/Show-IcingaAgentObjects.psm1 | 12 + .../icingaagent/misc/Split-IcingaVersion.psm1 | 31 +++ .../readers/Read-IcingaAgentDebugLogFile.psm1 | 10 + .../readers/Read-IcingaAgentLogFile.psm1 | 10 + .../icingaagent/setters/Set-IcingaAcl.psm1 | 24 ++ .../setters/Set-IcingaAgentNodeName.psm1 | 35 +++ .../icingaagent/tests/Test-IcingaAcl.psm1 | 45 ++++ .../icingaagent/tests/Test-IcingaAgent.psm1 | 17 ++ .../tests/Test-IcingaAgentConfig.psm1 | 20 ++ .../tests/Test-IcingaAgentFeatureEnabled.psm1 | 14 ++ .../writers/Write-IcingaAgentApiConfig.psm1 | 20 ++ .../writers/Write-IcingaAgentZonesConfig.psm1 | 78 ++++++ .../writers/Write-IcingaTestOutput.psm1 | 29 +++ 32 files changed, 988 insertions(+) create mode 100644 lib/core/icingaagent/getters/Get-IcingaAgentArchitecture.psm1 create mode 100644 lib/core/icingaagent/getters/Get-IcingaAgentBinary.psm1 create mode 100644 lib/core/icingaagent/getters/Get-IcingaAgentConfigDirectory.psm1 create mode 100644 lib/core/icingaagent/getters/Get-IcingaAgentFeatures.psm1 create mode 100644 lib/core/icingaagent/getters/Get-IcingaAgentInstallation.psm1 create mode 100644 lib/core/icingaagent/getters/Get-IcingaAgentLogDirectory.psm1 create mode 100644 lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 create mode 100644 lib/core/icingaagent/getters/Get-IcingaAgentRootDirectory.psm1 create mode 100644 lib/core/icingaagent/getters/Get-IcingaAgentVersion.psm1 create mode 100644 lib/core/icingaagent/getters/Get-IcingaHostname.psm1 create mode 100644 lib/core/icingaagent/getters/Get-IcingaServiceUser.psm1 create mode 100644 lib/core/icingaagent/installer/Install-IcingaAgent.psm1 create mode 100644 lib/core/icingaagent/installer/Install-IcingaAgentBaseFeatures.psm1 create mode 100644 lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 create mode 100644 lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 create mode 100644 lib/core/icingaagent/misc/Compare-IcingaVersions.psm1 create mode 100644 lib/core/icingaagent/misc/Disable-IcingaAgentFeature.psm1 create mode 100644 lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 create mode 100644 lib/core/icingaagent/misc/Move-IcingaAgentDefaultConfig.psm1 create mode 100644 lib/core/icingaagent/misc/Show-IcingaAgentObjects.psm1 create mode 100644 lib/core/icingaagent/misc/Split-IcingaVersion.psm1 create mode 100644 lib/core/icingaagent/readers/Read-IcingaAgentDebugLogFile.psm1 create mode 100644 lib/core/icingaagent/readers/Read-IcingaAgentLogFile.psm1 create mode 100644 lib/core/icingaagent/setters/Set-IcingaAcl.psm1 create mode 100644 lib/core/icingaagent/setters/Set-IcingaAgentNodeName.psm1 create mode 100644 lib/core/icingaagent/tests/Test-IcingaAcl.psm1 create mode 100644 lib/core/icingaagent/tests/Test-IcingaAgent.psm1 create mode 100644 lib/core/icingaagent/tests/Test-IcingaAgentConfig.psm1 create mode 100644 lib/core/icingaagent/tests/Test-IcingaAgentFeatureEnabled.psm1 create mode 100644 lib/core/icingaagent/writers/Write-IcingaAgentApiConfig.psm1 create mode 100644 lib/core/icingaagent/writers/Write-IcingaAgentZonesConfig.psm1 create mode 100644 lib/core/icingaagent/writers/Write-IcingaTestOutput.psm1 diff --git a/lib/core/icingaagent/getters/Get-IcingaAgentArchitecture.psm1 b/lib/core/icingaagent/getters/Get-IcingaAgentArchitecture.psm1 new file mode 100644 index 0000000..59d382e --- /dev/null +++ b/lib/core/icingaagent/getters/Get-IcingaAgentArchitecture.psm1 @@ -0,0 +1,6 @@ +function Get-IcingaAgentArchitecture() +{ + $IcingaAgent = Get-IcingaAgentInstallation; + + return $IcingaAgent.Architecture; +} diff --git a/lib/core/icingaagent/getters/Get-IcingaAgentBinary.psm1 b/lib/core/icingaagent/getters/Get-IcingaAgentBinary.psm1 new file mode 100644 index 0000000..4c4853f --- /dev/null +++ b/lib/core/icingaagent/getters/Get-IcingaAgentBinary.psm1 @@ -0,0 +1,11 @@ +function Get-IcingaAgentBinary() +{ + $IcingaRootDir = Get-IcingaAgentRootDirectory; + $IcingaBinary = (Join-Path -Path $IcingaRootDir -ChildPath '\sbin\icinga2.exe'); + + if ((Test-Path $IcingaBinary) -eq $FALSE) { + throw 'Icinga Agent binary could not be found'; + } + + return $IcingaBinary; +} diff --git a/lib/core/icingaagent/getters/Get-IcingaAgentConfigDirectory.psm1 b/lib/core/icingaagent/getters/Get-IcingaAgentConfigDirectory.psm1 new file mode 100644 index 0000000..5162442 --- /dev/null +++ b/lib/core/icingaagent/getters/Get-IcingaAgentConfigDirectory.psm1 @@ -0,0 +1,4 @@ +function Get-IcingaAgentConfigDirectory() +{ + return (Join-Path -Path $Env:ProgramData -ChildPath 'icinga2\etc\icinga2\') +} diff --git a/lib/core/icingaagent/getters/Get-IcingaAgentFeatures.psm1 b/lib/core/icingaagent/getters/Get-IcingaAgentFeatures.psm1 new file mode 100644 index 0000000..a016a30 --- /dev/null +++ b/lib/core/icingaagent/getters/Get-IcingaAgentFeatures.psm1 @@ -0,0 +1,20 @@ +function Get-IcingaAgentFeatures() +{ + $Binary = Get-IcingaAgentBinary; + $ConfigResult = Start-IcingaProcess -Executable $Binary -Arguments 'feature list'; + + $DisabledFeatures = ($ConfigResult.Message.SubString( + 0, + $ConfigResult.Message.IndexOf('Enabled features') + )).Replace('Disabled features: ', '').Replace("`r`n", ''); + + $EnabledFeatures = ($ConfigResult.Message.SubString( + $ConfigResult.Message.IndexOf('Enabled features'), + $ConfigResult.Message.Length - $ConfigResult.Message.IndexOf('Enabled features') + )).Replace('Enabled features: ', '').Replace("`r`n", ''); + + return @{ + 'Enabled' = ($EnabledFeatures.Split(' ')); + 'Disabled' = ($DisabledFeatures.Split(' ')); + } +} diff --git a/lib/core/icingaagent/getters/Get-IcingaAgentInstallation.psm1 b/lib/core/icingaagent/getters/Get-IcingaAgentInstallation.psm1 new file mode 100644 index 0000000..375d0ef --- /dev/null +++ b/lib/core/icingaagent/getters/Get-IcingaAgentInstallation.psm1 @@ -0,0 +1,40 @@ +function Get-IcingaAgentInstallation() +{ + [string]$architecture = ''; + if ([IntPtr]::Size -eq 4) { + $architecture = "x86"; + $regPath = 'HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*'; + } else { + $architecture = "x86_64"; + $regPath = @('HKLM:\Software\Microsoft\Windows\CurrentVersion\Uninstall\*', 'HKLM:\Software\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*'); + } + + $RegistryData = Get-ItemProperty $regPath; + $IcingaData = $null; + foreach ($entry in $RegistryData) { + if ($entry.DisplayName -eq 'Icinga 2') { + $IcingaData = $entry; + break; + } + } + + if ($null -eq $IcingaData) { + return @{ + 'Installed' = $FALSE; + 'RootDir' = ''; + 'Version' = (Split-IcingaVersion); + 'Architecture' = $architecture; + 'Uninstaller' = ''; + 'InstallDate' = ''; + }; + } + + return @{ + 'Installed' = $TRUE; + 'RootDir' = $IcingaData.InstallLocation; + 'Version' = (Split-IcingaVersion $IcingaData.DisplayVersion); + 'Architecture' = $architecture; + 'Uninstaller' = $IcingaData.UninstallString.Replace("MsiExec.exe ", ""); + 'InstallDate' = $IcingaData.InstallDate; + }; +} diff --git a/lib/core/icingaagent/getters/Get-IcingaAgentLogDirectory.psm1 b/lib/core/icingaagent/getters/Get-IcingaAgentLogDirectory.psm1 new file mode 100644 index 0000000..2923414 --- /dev/null +++ b/lib/core/icingaagent/getters/Get-IcingaAgentLogDirectory.psm1 @@ -0,0 +1,4 @@ +function Get-IcingaAgentLogDirectory() +{ + return (Join-Path -Path $Env:ProgramData -ChildPath 'icinga2\var\log\icinga2\') +} diff --git a/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 b/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 new file mode 100644 index 0000000..9939742 --- /dev/null +++ b/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 @@ -0,0 +1,73 @@ +function Get-IcingaAgentMSIPackage() +{ + param( + [string]$Source, + [string]$Version, + [switch]$SkipDownload + ); + + if ([string]::IsNullOrEmpty($Version)) { + throw 'Please specify a valid version: "snapshot", "latest" or a specific version like "2.11.0"'; + } + + if ([string]::IsNullOrEmpty($Source)) { + throw 'Please specify a valid download URL, like "https://packages.icinga.com/windows/"'; + } + + # Disable the progress bar for the WebRequest + $ProgressPreference = "SilentlyContinue"; + $Architecture = Get-IcingaAgentArchitecture; + $LastUpdate = $null; + + if ($Version -eq 'snapshot' -Or $Version -eq 'latest') { + $Content = (Invoke-WebRequest -Uri $Source -UseBasicParsing).RawContent.Split("`r`n"); + $UsePackage = $null; + + foreach ($line in $Content) { + if ($line -like '*.msi*' -And $line -like "*$Architecture*") { + #Write-Host '#####' $line + $MSIPackage = $line.SubString( + $line.IndexOf('Icinga2-'), + $line.IndexOf('.msi') - $line.IndexOf('Icinga2-') + ); + $LastUpdate = $line.SubString( + $line.IndexOf('indexcollastmod">') + 17, + $line.Length - $line.IndexOf('indexcollastmod">') - 17 + ); + $LastUpdate = $LastUpdate.SubString(0, $LastUpdate.IndexOf(' ')); + $LastUpdate = $LastUpdate.Replace('-', ''); + $MSIPackage = [string]::Format('{0}.msi', $MSIPackage); + if ($Version -eq 'snapshot') { + if ($line -like '*snapshot*') { + $UsePackage = $MSIPackage; + break; + } + } elseif ($Version -eq 'latest') { + if ($line -like '*snapshot*') { + continue; + } + $UsePackage = $MSIPackage; + break; + } + } + } + } else { + $UsePackage = [string]::Format('Icinga2-v{0}-{1}.msi', $Version, $Architecture); + } + + if ($null -eq $UsePackage) { + throw 'No Icinga installation MSI package for your architecture could be found for the provided version and source'; + } + + if ($SkipDownload -eq $FALSE) { + $DownloadPath = Join-Path $Env:TEMP -ChildPath $UsePackage; + Write-Host ([string]::Format('Download Icinga 2 Agent installer "{0}" into temp directory "{1}"', $UsePackage, $DownloadPath)); + Invoke-WebRequest -Uri ([string]::Format('{0}/{1}', $Source, $UsePackage)) -OutFile $DownloadPath; + } + + return @{ + 'InstallerPath' = $DownloadPath; + 'Version' = ($UsePackage).Replace('Icinga2-v', '').Replace($Architecture, '').Replace('.msi', '').Replace('-', ''); + 'LastUpdate' = $LastUpdate; + } +} diff --git a/lib/core/icingaagent/getters/Get-IcingaAgentRootDirectory.psm1 b/lib/core/icingaagent/getters/Get-IcingaAgentRootDirectory.psm1 new file mode 100644 index 0000000..4ed842b --- /dev/null +++ b/lib/core/icingaagent/getters/Get-IcingaAgentRootDirectory.psm1 @@ -0,0 +1,9 @@ +function Get-IcingaAgentRootDirectory() +{ + $IcingaAgent = Get-IcingaAgentInstallation; + if ($IcingaAgent.Installed -eq $FALSE) { + return ''; + } + + return $IcingaAgent.RootDir; +} diff --git a/lib/core/icingaagent/getters/Get-IcingaAgentVersion.psm1 b/lib/core/icingaagent/getters/Get-IcingaAgentVersion.psm1 new file mode 100644 index 0000000..65992f5 --- /dev/null +++ b/lib/core/icingaagent/getters/Get-IcingaAgentVersion.psm1 @@ -0,0 +1,6 @@ +function Get-IcingaAgentVersion() +{ + $IcingaAgent = Get-IcingaAgentInstallation; + + return $IcingaAgent.Version; +} diff --git a/lib/core/icingaagent/getters/Get-IcingaHostname.psm1 b/lib/core/icingaagent/getters/Get-IcingaHostname.psm1 new file mode 100644 index 0000000..55cc269 --- /dev/null +++ b/lib/core/icingaagent/getters/Get-IcingaHostname.psm1 @@ -0,0 +1,27 @@ +function Get-IcingaHostname() +{ + param( + [string]$Hostname, + [bool]$AutoUseFQDN = $FALSE, + [bool]$AutoUseHostname = $FALSE, + [bool]$UpperCase = $FALSE, + [bool]$LowerCase = $FALSE + ); + + [string]$UseHostname = ''; + if ([string]::IsNullOrEmpty($Hostname) -eq $FALSE) { + $UseHostname = $Hostname; + } elseif ($AutoUseFQDN) { + $UseHostname = [System.Net.Dns]::GetHostEntry("localhost").HostName; + } else { + $UseHostname = [System.Net.Dns]::GetHostName(); + } + + if ($UpperCase) { + $UseHostname = $UseHostname.ToUpper(); + } elseif ($LowerCase) { + $UseHostname = $UseHostname.ToLower(); + } + + return $UseHostname; +} diff --git a/lib/core/icingaagent/getters/Get-IcingaServiceUser.psm1 b/lib/core/icingaagent/getters/Get-IcingaServiceUser.psm1 new file mode 100644 index 0000000..cb3e2b8 --- /dev/null +++ b/lib/core/icingaagent/getters/Get-IcingaServiceUser.psm1 @@ -0,0 +1,11 @@ +function Get-IcingaServiceUser() +{ + $Services = Get-IcingaServices -Service 'icinga2'; + + if ($null -eq $Services) { + throw 'Icinga Service not installed'; + } + + $Services = $Services.GetEnumerator() | Select-Object -First 1; + return ($Services.Value.configuration.ServiceUser).Replace('.\', ''); +} diff --git a/lib/core/icingaagent/installer/Install-IcingaAgent.psm1 b/lib/core/icingaagent/installer/Install-IcingaAgent.psm1 new file mode 100644 index 0000000..b869a1a --- /dev/null +++ b/lib/core/icingaagent/installer/Install-IcingaAgent.psm1 @@ -0,0 +1,78 @@ +function Install-IcingaAgent() +{ + param( + [string]$Version, + [string]$Source = 'https://packages.icinga.com/windows/', + [string]$InstallDir = '', + [switch]$AllowUpdates + ); + + $IcingaData = Get-IcingaAgentInstallation; + $InstalledVersion = Get-IcingaAgentVersion; + $IcingaInstaller = Get-IcingaAgentMSIPackage -Source $Source -Version $Version -SkipDownload; + $InstallTarget = $IcingaData.RootDir; + + if ($IcingaData.Installed -eq $TRUE -and $AllowUpdates -eq $FALSE) { + Write-Host 'The Icinga Agent is already installed on this system. To perform updates or downgrades, please add the "-AllowUpdates" argument'; + return $FALSE; + } + + if ($Version -eq 'snapshot') { + if ($IcingaData.InstallDate -ge $IcingaInstaller.LastUpdate -And [string]::IsNullOrEmpty($InstalledVersion.Snapshot) -eq $FALSE) { + Write-Host 'There is no new snapshot package available which requires to be installed.' + return $FALSE; + } + $IcingaInstaller.Version = 'snapshot'; + } elseif ($IcingaInstaller.Version -eq $InstalledVersion.Full) { + Write-Host ([string]::Format( + 'No installation required. Your installed version [{0}] is matching the online version [{1}]', + $InstalledVersion.Full, + $IcingaInstaller.Version + )); + return $FALSE; + } + + $IcingaInstaller = Get-IcingaAgentMSIPackage -Source $Source -Version $IcingaInstaller.Version; + + if ((Test-Path $IcingaInstaller.InstallerPath) -eq $FALSE) { + throw 'Failed to locate Icinga Agent installer file'; + } + + if ([string]::IsNullOrEmpty($InstallDir) -eq $FALSE) { + if ((Test-Path $InstallDir) -eq $FALSE) { + New-Item -Path $InstallDir -Force | Out-Null; + $InstallTarget = $InstallDir; + } + } + + [string]$InstallFolderMsg = $InstallTarget; + + if ([string]::IsNullOrEmpty($InstallTarget) -eq $FALSE) { + $InstallTarget = [string]::Format(' INSTALL_ROOT="{0}"', $InstallTarget); + } else { + $InstallTarget = ''; + if ($IcingaData.Architecture -eq 'x86') { + $InstallFolderMsg = Join-Path -Path ${env:ProgramFiles(x86)} -ChildPath 'ICINGA2'; + } else { + $InstallFolderMsg = Join-Path -Path $env:ProgramFiles -ChildPath 'ICINGA2'; + } + } + + Write-Host ([string]::Format('Installing new Icinga Agent version into "{0}"', $InstallFolderMsg)); + + if ($IcingaData.Installed) { + if ((Uninstall-IcingaAgent) -eq $FALSE) { + return $FALSE; + } + } + + $InstallProcess = Start-IcingaProcess -Executable 'MsiExec.exe' -Arguments ([string]::Format('/quiet /i "{0}" {1}', $IcingaInstaller.InstallerPath, $InstallTarget)) -FlushNewLines; + + if ($InstallProcess.ExitCode -ne 0) { + Write-Host ([string]::Format('Failed to install Icinga 2 Agent: {0}{1}', $InstallProcess.Message, $InstallProcess.Error)); + return $FALSE; + } + + Write-Host 'Icinga Agent was successfully installed'; + return $TRUE; +} diff --git a/lib/core/icingaagent/installer/Install-IcingaAgentBaseFeatures.psm1 b/lib/core/icingaagent/installer/Install-IcingaAgentBaseFeatures.psm1 new file mode 100644 index 0000000..1251664 --- /dev/null +++ b/lib/core/icingaagent/installer/Install-IcingaAgentBaseFeatures.psm1 @@ -0,0 +1,5 @@ +function Install-IcingaAgentBaseFeatures() +{ + Disable-IcingaAgentFeature -Feature 'checker'; + Enable-IcingaAgentFeature -Feature 'api'; +} diff --git a/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 b/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 new file mode 100644 index 0000000..eeb16c5 --- /dev/null +++ b/lib/core/icingaagent/installer/Install-IcingaAgentCertificates.psm1 @@ -0,0 +1,224 @@ +function Install-IcingaAgentCertificates() +{ + param( + [string]$Hostname, + [string]$Endpoint, + [int]$Port = 5665, + [string]$CACert, + [string]$Ticket, + [switch]$Force = $FALSE + ); + + if ([string]::IsNullOrEmpty($Hostname)) { + throw 'Failed to install Icinga Agent certificates. Please provide a hostname'; + } + + # Default for Icinga 2.8.0 and above + [string]$NewCertificateDirectory = (Join-Path -Path $Env:ProgramData -ChildPath 'icinga2\var\lib\icinga2\certs\'); + [string]$OldCertificateDirectory = (Join-Path -Path $Env:ProgramData -ChildPath 'icinga2\etc\icinga2\pki\'); + [string]$CertificateDirectory = $NewCertificateDirectory; + if ((Compare-IcingaVersions -RequiredVersion '2.8.0') -eq $FALSE) { + # Certificate path for versions older than 2.8.0 + $CertificateDirectory = $OldCertificateDirectory; + Move-IcingaAgentCertificates -Source $NewCertificateDirectory -Destination $OldCertificateDirectory; + } else { + Move-IcingaAgentCertificates -Source $OldCertificateDirectory -Destination $NewCertificateDirectory; + } + + if (-Not (Test-IcingaAgentCertificates -CertDirectory $CertificateDirectory -Hostname $Hostname -Force $Force)) { + Write-Host ([string]::Format('Generating host certificates for host "{0}"', $Hostname)); + + $arguments = [string]::Format('pki new-cert --cn {0} --key {1}{0}.key --cert {1}{0}.crt', + $Hostname, + $CertificateDirectory + ); + + if ((Start-IcingaAgentCertificateProcess -Arguments $arguments) -eq $FALSE) { + throw 'Failed to generate host certificate'; + } + } + + if ([string]::IsNullOrEmpty($Endpoint) -And [string]::IsNullOrEmpty($CACert)) { + Write-Host 'Your host certificates have been generated successfully. Please either specify an endpoint to connect to or provide the path to a valid ca.crt.'; + return $TRUE; + } + + if (-Not [string]::IsNullOrEmpty($Endpoint)) { + if (-Not (Test-IcingaAgentCertificates -CertDirectory $CertificateDirectory -Hostname $Hostname -TestTrustedParent -Force $Force)) { + + Write-Host ([string]::Format('Fetching trusted master certificate from "{0}"', $Endpoint)); + + $arguments = [string]::Format('pki save-cert --key {0}{1}.key --trustedcert {0}trusted-parent.crt --host {2}', + $CertificateDirectory, + $Hostname, + $Endpoint + ); + + if ((Start-IcingaAgentCertificateProcess -Arguments $arguments) -eq $FALSE) { + Write-Host 'Unable to connect to your provided Icinga CA. Please verify the entered configuration is correct.' ` + 'If you are not able to connect to your Icinga CA from this machine, you will have to provide the path' ` + 'to your Icinga ca.crt and use the CA-Proxy certificate handling.'; + return $TRUE; + } + } + + if (-Not (Test-IcingaAgentCertificates -CertDirectory $CertificateDirectory -Hostname $Hostname -TestCACert -Force $Force)) { + [string]$PKIRequest = 'pki request --host {0} --port {1} --ticket {4} --key {2}{3}.key --cert {2}{3}.crt --trustedcert {2}trusted-parent.crt --ca {2}ca.crt'; + + if ([string]::IsNullOrEmpty($Ticket)) { + $PKIRequest = 'pki request --host {0} --port {1} --key {2}{3}.key --cert {2}{3}.crt --trustedcert {2}trusted-parent.crt --ca {2}ca.crt'; + } + + $arguments = [string]::Format($PKIRequest, + $Endpoint, + $Port, + $CertificateDirectory, + $Hostname, + $Ticket + ); + + if ((Start-IcingaAgentCertificateProcess -Arguments $arguments) -eq $FALSE) { + throw 'Failed to sign Icinga certificate'; + } + + if ([string]::IsNullOrEmpty($Ticket)) { + Write-Host 'Your certificates were generated successfully. Please sign the certificate now on your Icinga CA master. You can lookup open requests with "icinga2 ca list"'; + } else { + Write-Host 'Icinga certificates successfully installed'; + } + } + + return $TRUE; + } elseif (-Not [string]::IsNullOrEmpty($CACert)) { + if (-Not (Copy-IcingaAgentCACertificate -CAPath $CACert -Desination $CertificateDirectory)) { + return $FALSE; + } + Write-Host 'Host-Certificates and ca.crt are present. Please start your Icinga Agent now and manually sign your certificate request on your CA master. You can lookup open requests with "icinga2 ca list"'; + } + + return $TRUE; +} + +function Start-IcingaAgentCertificateProcess() +{ + param( + $Arguments + ); + + $Binary = Get-IcingaAgentBinary; + $Process = Start-IcingaProcess -Executable $Binary -Arguments $Arguments; + + if ($Process.ExitCode -ne 0) { + Write-Host ([string]::Format('Failed to create certificate.{0}Arguments: {1}{0}Error:{2} {3}', "`r`n", $Arguments, $Process.Message, $Process.Error)); + return $FALSE; + } + + Write-Host $Process.Message; + return $TRUE; +} + +function Move-IcingaAgentCertificates() +{ + param( + [string]$Source, + [string]$Destination + ); + + $SourceDir = Join-Path -Path $Source -ChildPath '\*'; + $TargetDir = Join-Path -Path $Destination -ChildPath '\'; + + Move-Item -Path $SourceDir -Destination $TargetDir; +} + +function Test-IcingaAgentCertificates() +{ + param( + [string]$CertDirectory, + [string]$Hostname, + [switch]$TestCACert, + [switch]$TestTrustedParent, + [bool]$Force + ); + + if ($Force) { + return $FALSE; + } + + if ($TestCACert) { + if (Test-Path (Join-Path -Path $CertDirectory -ChildPath 'ca.crt')) { + Write-Host 'Your ca.crt is present. No generation or fetching required'; + return $TRUE; + } else { + Write-Host 'Your ca.crt is not present. Manuall copy or fetching from your Icinga CA is required.'; + return $FALSE; + } + } + + if ($TestTrustedParent) { + if (Test-Path (Join-Path -Path $CertDirectory -ChildPath 'trusted-parent.crt')) { + Write-Host 'Your trusted-parent.crt is present. No fetching or generation required'; + return $TRUE; + } else { + Write-Host 'Your trusted master certificate is not present. Fetching from your CA server is required'; + return $FALSE; + } + } + + if ((-Not (Test-Path ((Join-Path -Path $CertDirectory -ChildPath $Hostname) + '.key'))) ` + -Or -Not (Test-Path ((Join-Path -Path $CertDirectory -ChildPath $Hostname) + '.crt'))) { + return $FALSE; + } + + [string]$hostCRT = [string]::Format('{0}.crt', $Hostname); + [string]$hostKEY = [string]::Format('{0}.key', $Hostname); + + $certificates = Get-ChildItem -Path $CertDirectory; + # Now loop each file and match their name with our hostname + foreach ($cert in $certificates) { + if ($cert.Name.toLower() -eq $hostCRT.toLower() -Or $cert.Name.toLower() -eq $hostKEY.toLower()) { + $file = $cert.Name.Replace('.key', '').Replace('.crt', ''); + if (-Not ($file -clike $Hostname)) { + Write-Host ([string]::Format('Certificate file {0} is not matching the hostname {1}. Certificate generation is required.', $cert.Name, $Hostname)); + return $FALSE; + } + } + } + + Write-Host 'Icinga host certificates are present and valid. No generation required.'; + + return $TRUE; +} + +function Copy-IcingaAgentCACertificate() +{ + param( + [string]$CAPath, + [string]$Desination + ); + + # Copy ca.crt from local path or network share to certificate path + if ((Test-Path $CAPath)) { + Copy-Item -Path $CAPath -Destination (Join-Path -Path $Desination -ChildPath 'ca.crt') | Out-Null; + Write-Host ([string]::Format('Copied ca.crt from "{0}" to "{1}', $CAPath, $Desination)); + } else { + # It could also be a web ressource + try { + $response = Invoke-WebRequest $CAPath -UseBasicParsing; + [int]$Index = $response.RawContent.IndexOf("`r`n`r`n") + 4; + + [string]$CAContent = $response.RawContent.SubString( + $Index, + $response.RawContent.Length - $Index + ); + Set-Content -Path (Join-Path $Desination -ChildPath 'ca.crt') -Value $CAContent; + Write-Host ([string]::Format('Downloaded ca.crt from "{0}" to "{1}', $CAPath, $Desination)) + } catch { + Write-Host 'Failed to load any provided ca.crt ressource'; + return $FALSE; + } + } + + return $TRUE; +} + +Export-ModuleMember -Function @('Install-IcingaAgentCertificates'); diff --git a/lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 b/lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 new file mode 100644 index 0000000..4afea1b --- /dev/null +++ b/lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 @@ -0,0 +1,21 @@ +function Uninstall-IcingaAgent() +{ + $IcingaData = Get-IcingaAgentInstallation; + + if ($IcingaData.Installed -eq $FALSE) { + Write-Host 'Unable to uninstall the Icinga Agent. The Agent is not installed'; + return; + } + + Write-Host 'Removing current installed Icinga Agent'; + + $Uninstaller = Start-IcingaProcess -Executable 'MsiExec.exe' -Arguments ([string]::Format('{0} /q', $IcingaData.Uninstaller)) -FlushNewLine; + + if ($Uninstaller.ExitCode -ne 0) { + Write-Host ([string]::Format('Failed to remove Icinga 2 Agent: {0}{1}', $Uninstaller.Message, $Uninstaller.Error)); + return $FALSE; + } + + Write-Host 'Icinga Agent was successfully removed'; + return $TRUE; +} diff --git a/lib/core/icingaagent/misc/Compare-IcingaVersions.psm1 b/lib/core/icingaagent/misc/Compare-IcingaVersions.psm1 new file mode 100644 index 0000000..686a2bd --- /dev/null +++ b/lib/core/icingaagent/misc/Compare-IcingaVersions.psm1 @@ -0,0 +1,33 @@ +function Compare-IcingaVersions() +{ + param( + $CurrentVersion, + $RequiredVersion + ); + + if ([string]::IsNullOrEmpty($RequiredVersion)) { + return $FALSE; + } + + $RequiredVersion = Split-IcingaVersion -Version $RequiredVersion; + + if ([string]::IsNullOrEmpty($CurrentVersion) -eq $FALSE) { + $CurrentVersion = Split-IcingaVersion -Version $CurrentVersion; + } else { + $CurrentVersion = Get-IcingaAgentVersion; + } + + if ($requiredVersion.Mayor -gt $currentVersion.Mayor) { + return $FALSE; + } + + if ($requiredVersion.Minor -gt $currentVersion.Minor) { + return $FALSE; + } + + if ($requiredVersion.Minor -ge $currentVersion.Minor -And $requiredVersion.Fixes -gt $currentVersion.Fixes) { + return $FALSE; + } + + return $TRUE; +} diff --git a/lib/core/icingaagent/misc/Disable-IcingaAgentFeature.psm1 b/lib/core/icingaagent/misc/Disable-IcingaAgentFeature.psm1 new file mode 100644 index 0000000..d3ca9b8 --- /dev/null +++ b/lib/core/icingaagent/misc/Disable-IcingaAgentFeature.psm1 @@ -0,0 +1,24 @@ +function Disable-IcingaAgentFeature() +{ + param( + [string]$Feature + ); + + if ([string]::IsNullOrEmpty($Feature)) { + throw 'Please specify a valid feature'; + } + + if ((Test-IcingaAgentFeatureEnabled -Feature $Feature) -eq $FALSE) { + Write-Host 'This feature is already disabled.' + return; + } + + $Binary = Get-IcingaAGentBinary; + $Process = Start-IcingaProcess -Executable $Binary -Arguments ([string]::Format('feature disable {0}', $Feature)); + + if ($Process.ExitCode -ne 0) { + throw ([string]::Format('Failed to disable Icinga Feature: {0}', $Process.Message)); + } + + Write-Host ([string]::Format('Feature "{0}" was successfully disabled', $Feature)); +} diff --git a/lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 b/lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 new file mode 100644 index 0000000..e1caf07 --- /dev/null +++ b/lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 @@ -0,0 +1,24 @@ +function Enable-IcingaAgentFeature() +{ + param( + [string]$Feature + ); + + if ([string]::IsNullOrEmpty($Feature)) { + throw 'Please specify a valid feature'; + } + + if ((Test-IcingaAgentFeatureEnabled -Feature $Feature)) { + Write-Host 'This feature is already enabled.' + return; + } + + $Binary = Get-IcingaAGentBinary; + $Process = Start-IcingaProcess -Executable $Binary -Arguments ([string]::Format('feature enable {0}', $Feature)); + + if ($Process.ExitCode -ne 0) { + throw ([string]::Format('Failed to enable Icinga Feature: {0}', $Process.Message)); + } + + Write-Host ([string]::Format('Feature "{0}" was successfully enabled', $Feature)); +} diff --git a/lib/core/icingaagent/misc/Move-IcingaAgentDefaultConfig.psm1 b/lib/core/icingaagent/misc/Move-IcingaAgentDefaultConfig.psm1 new file mode 100644 index 0000000..076761a --- /dev/null +++ b/lib/core/icingaagent/misc/Move-IcingaAgentDefaultConfig.psm1 @@ -0,0 +1,23 @@ +function Move-IcingaAgentDefaultConfig() +{ + $ConfigDir = Get-IcingaAgentConfigDirectory; + $BackupFile = Join-Path -Path $ConfigDir -ChildPath 'ps_backup\backup_executed.key'; + + if ((Test-Path $BackupFile)) { + Write-Host 'A backup of your default configuration is not required. A backup was already made.'; + return; + } + + New-Item (Join-Path -Path $ConfigDir -ChildPath 'ps_backup') -ItemType Directory | Out-Null; + + Move-Item -Path (Join-Path -Path $ConfigDir -ChildPath 'conf.d') -Destination (Join-Path -Path $ConfigDir -ChildPath 'ps_backup\conf.d'); + Move-Item -Path (Join-Path -Path $ConfigDir -ChildPath 'zones.conf') -Destination (Join-Path -Path $ConfigDir -ChildPath 'ps_backup\zones.conf'); + Copy-Item -Path (Join-Path -Path $ConfigDir -ChildPath 'constants.conf') -Destination (Join-Path -Path $ConfigDir -ChildPath 'ps_backup\constants.conf'); + Copy-Item -Path (Join-Path -Path $ConfigDir -ChildPath 'features-available') -Destination (Join-Path -Path $ConfigDir -ChildPath 'ps_backup\features-available'); + + New-Item (Join-Path -Path $ConfigDir -ChildPath 'conf.d') -ItemType Directory | Out-Null; + New-Item (Join-Path -Path $ConfigDir -ChildPath 'zones.conf') -ItemType File | Out-Null; + New-Item -Path $BackupFile -ItemType File | Out-Null; + + Write-Host 'Successfully backed up Icinga 2 Agent default config'; +} diff --git a/lib/core/icingaagent/misc/Show-IcingaAgentObjects.psm1 b/lib/core/icingaagent/misc/Show-IcingaAgentObjects.psm1 new file mode 100644 index 0000000..07f4aae --- /dev/null +++ b/lib/core/icingaagent/misc/Show-IcingaAgentObjects.psm1 @@ -0,0 +1,12 @@ +function Show-IcingaAgentObjects() +{ + $Binary = Get-IcingaAgentBinary; + $Output = Start-IcingaProcess -Executable $Binary -Arguments 'object list'; + + if ($Output.ExitCode -ne 0) { + Write-Host ([string]::Format('Failed to fetch Icinga Agent objects list: {0}{1}', $Output.Message, $Output.Error)); + return $null; + } + + return $Output.Message; +} diff --git a/lib/core/icingaagent/misc/Split-IcingaVersion.psm1 b/lib/core/icingaagent/misc/Split-IcingaVersion.psm1 new file mode 100644 index 0000000..ffe21f6 --- /dev/null +++ b/lib/core/icingaagent/misc/Split-IcingaVersion.psm1 @@ -0,0 +1,31 @@ +function Split-IcingaVersion() +{ + param( + [string]$Version + ); + + if ([string]::IsNullOrEmpty($Version)) { + return @{ + 'Full' = ''; + 'Mayor' = $null; + 'Minor' = $null; + 'Fixes' = $null; + 'Snapshot' = $null; + } + } + + [array]$IcingaVersion = $Version.Split('.'); + $Snapshot = $null; + + if ([string]::IsNullOrEmpty($IcingaVersion[3]) -eq $FALSE) { + $Snapshot = [int]$IcingaVersion[3]; + } + + return @{ + 'Full' = $Version; + 'Mayor' = [int]$IcingaVersion[0]; + 'Minor' = [int]$IcingaVersion[1]; + 'Fixes' = [int]$IcingaVersion[2]; + 'Snapshot' = $Snapshot; + } +} diff --git a/lib/core/icingaagent/readers/Read-IcingaAgentDebugLogFile.psm1 b/lib/core/icingaagent/readers/Read-IcingaAgentDebugLogFile.psm1 new file mode 100644 index 0000000..311ed75 --- /dev/null +++ b/lib/core/icingaagent/readers/Read-IcingaAgentDebugLogFile.psm1 @@ -0,0 +1,10 @@ +function Read-IcingaAgentDebugLogFile() +{ + $Logfile = Join-Path -Path (Get-IcingaAgentLogDirectory) -ChildPath 'debug.log'; + if ((Test-Path $Logfile) -eq $FALSE) { + Write-Host 'Icinga 2 debug logfile not present. Unable to load it'; + return; + } + + Get-Content -Path $Logfile -Wait; +} diff --git a/lib/core/icingaagent/readers/Read-IcingaAgentLogFile.psm1 b/lib/core/icingaagent/readers/Read-IcingaAgentLogFile.psm1 new file mode 100644 index 0000000..f80a059 --- /dev/null +++ b/lib/core/icingaagent/readers/Read-IcingaAgentLogFile.psm1 @@ -0,0 +1,10 @@ +function Read-IcingaAgentLogFile() +{ + $Logfile = Join-Path -Path (Get-IcingaAgentLogDirectory) -ChildPath 'icinga2.log'; + if ((Test-Path $Logfile) -eq $FALSE) { + Write-Host 'Icinga 2 logfile not present. Unable to load it'; + return; + } + + Get-Content -Path $Logfile -Wait; +} diff --git a/lib/core/icingaagent/setters/Set-IcingaAcl.psm1 b/lib/core/icingaagent/setters/Set-IcingaAcl.psm1 new file mode 100644 index 0000000..a720b19 --- /dev/null +++ b/lib/core/icingaagent/setters/Set-IcingaAcl.psm1 @@ -0,0 +1,24 @@ +function Set-IcingaAcl() +{ + param( + [string]$Directory + ); + + if (-Not (Test-Path $Directory)) { + throw 'Failed to set Acl for directory. Directory does not exist'; + return; + } + + $DirectoryAcl = Get-Acl -Path $Directory; + $DirectoryAccessRule = New-Object System.Security.AccessControl.FileSystemAccessRule( + (Get-IcingaServiceUser), + 'Modify', + 'ContainerInherit,ObjectInherit', + 'None', + 'Allow' + ); + + $DirectoryAcl.SetAccessRule($DirectoryAccessRule); + Set-Acl -Path $Directory -AclObject $DirectoryAcl; + Test-IcingaAcl -Directory $Directory -WriteOutput | Out-Null; +} diff --git a/lib/core/icingaagent/setters/Set-IcingaAgentNodeName.psm1 b/lib/core/icingaagent/setters/Set-IcingaAgentNodeName.psm1 new file mode 100644 index 0000000..4956b41 --- /dev/null +++ b/lib/core/icingaagent/setters/Set-IcingaAgentNodeName.psm1 @@ -0,0 +1,35 @@ +function Set-IcingaAgentNodeName() +{ + param( + $Hostname + ); + + if ([string]::IsNullOrEmpty($Hostname)) { + throw 'You have to specify a hostname in order to change the Icinga Agent NodeName'; + } + + $ConfigDir = Get-IcingaAgentConfigDirectory; + $ConstantsConf = Join-Path -Path $ConfigDir -ChildPath 'constants.conf'; + + $ConfigContent = Get-Content -Path $ConstantsConf; + + if ($ConfigContent.Contains('//const NodeName = "localhost"')) { + $ConfigContent = $ConfigContent.Replace( + '//const NodeName = "localhost"', + [string]::Format('const NodeName = "{0}"', $Hostname) + ); + } else { + [string]$NewConfigContent = ''; + foreach ($line in $ConfigContent) { + if ($line.Contains('const NodeName =')) { + $line = [string]::Format('const NodeName = "{0}"', $Hostname); + } + $NewConfigContent = [string]::Format('{0}{1}{2}', $NewConfigContent, $line, "`r`n"); + } + $ConfigContent = $NewConfigContent; + } + + Set-Content -Path $ConstantsConf -Value $ConfigContent; + + Write-Host ([string]::Format('Your hostname was successfully changed to "{0}"', $Hostname)); +} diff --git a/lib/core/icingaagent/tests/Test-IcingaAcl.psm1 b/lib/core/icingaagent/tests/Test-IcingaAcl.psm1 new file mode 100644 index 0000000..2914a04 --- /dev/null +++ b/lib/core/icingaagent/tests/Test-IcingaAcl.psm1 @@ -0,0 +1,45 @@ +function Test-IcingaAcl() +{ + param( + [string]$Directory, + [switch]$WriteOutput + ); + + if (-Not (Test-Path $Directory)) { + throw 'The specified directory was not found'; + } + + $FolderACL = Get-Acl $Directory; + $ServiceUser = Get-IcingaServiceUser; + $UserFound = $FALSE; + $HasAccess = $FALSE; + + foreach ($user in $FolderACL.Access) { + # Not only check here for the exact name but also for included strings like NT AU or NT-AU or even further later on + # As the Get-Acl Cmdlet will translate usernames into the own language, resultng in 'NT AUTHORITY\NetworkService' being translated + # to 'NT-AUTORITÄT\Netzwerkdienst' for example + if ($user.IdentityReference -like "*$ServiceUser" -Or ($ServiceUser -Like '*NT AU*' -And ($user.IdentityReference -Like '*NT AU*' -Or $user.IdentityReference -Like '*NT-AU*'))) { + $UserFound = $TRUE; + if ($user.FileSystemRights -Like '*Modify*' -And $user.FileSystemRights -Like '*Synchronize*') { + $HasAccess = $TRUE; + } + } + } + + if ($WriteOutput) { + [string]$messageFormat = 'Directory "{0}" {1} by the Icinga Service User "{2}"'; + if ($UserFound) { + if ($HasAccess) { + Write-IcingaTestOutput -Severity 'PASSED' -Message ([string]::Format($messageFormat, $Directory, 'is accessable and writeable', $ServiceUser)); + } else { + Write-IcingaTestOutput -Severity 'FAILED' -Message ([string]::Format($messageFormat, $Directory, 'is accessable but NOT writeable', $ServiceUser)); + Write-Host "\_ Please run the following command to fix this issue: Set-IcingaAcl -Directory '$Directory'"; + } + } else { + Write-IcingaTestOutput -Severity 'FAILED' -Message ([string]::Format($messageFormat, $Directory, 'is not accessable', $ServiceUser)); + Write-Host "\_ Please run the following command to fix this issue: Set-IcingaAcl -Directory '$Directory'"; + } + } + + return $UserFound; +} diff --git a/lib/core/icingaagent/tests/Test-IcingaAgent.psm1 b/lib/core/icingaagent/tests/Test-IcingaAgent.psm1 new file mode 100644 index 0000000..e0b5173 --- /dev/null +++ b/lib/core/icingaagent/tests/Test-IcingaAgent.psm1 @@ -0,0 +1,17 @@ +function Test-IcingaAgent() +{ + if (Get-Service 'icinga2' -ErrorAction SilentlyContinue) { + Write-IcingaTestOutput -Severity 'PASSED' -Message 'Icinga Agent Service is installed'; + Test-IcingaAcl "$Env:ProgramData\icinga2\etc" -WriteOutput | Out-Null; + Test-IcingaAcl "$Env:ProgramData\icinga2\var" -WriteOutput | Out-Null; + Test-IcingaAcl (Get-IcingaCacheDir) -WriteOutput | Out-Null; + Test-IcingaAgentConfig | Out-Null; + if (Test-IcingaAgentFeatureEnabled -Feature 'debuglog') { + Write-IcingaTestOutput -Severity 'WARNING' -Message 'The Debug-Log of the Icinga Agent is enabled. Please keep in mind to disable it once testing is done, as a huge amount of data is generated.' + } else { + Write-IcingaTestOutput -Severity 'PASSED' -Message 'Icinga Agent Debug-Log is disabled.' + } + } else { + Write-IcingaTestOutput -Severity 'FAILED' -Message 'Icinga Agent Service is not installed'; + } +} diff --git a/lib/core/icingaagent/tests/Test-IcingaAgentConfig.psm1 b/lib/core/icingaagent/tests/Test-IcingaAgentConfig.psm1 new file mode 100644 index 0000000..42b78a6 --- /dev/null +++ b/lib/core/icingaagent/tests/Test-IcingaAgentConfig.psm1 @@ -0,0 +1,20 @@ +function Test-IcingaAgentConfig() +{ + param ( + [switch]$WriteStackTrace + ); + + $Binary = Get-IcingaAgentBinary; + $ConfigResult = Start-IcingaProcess -Executable $Binary -Arguments 'daemon -C'; + + if ($ConfigResult.ExitCode -eq 0) { + Write-IcingaTestOutput -Severity 'PASSED' -Message 'Icinga Agent configuration is valid'; + return $TRUE; + } else { + Write-IcingaTestOutput -Severity 'FAILED' -Message 'Icinga Agent configuration is containing errors. Run this command for getting a detailed error report: "Test-IcingaAgentConfig -WriteStackTrace | Out-Null"'; + if ($WriteStackTrace) { + Write-Host $ConfigResult.Message; + } + return $FALSE; + } +} diff --git a/lib/core/icingaagent/tests/Test-IcingaAgentFeatureEnabled.psm1 b/lib/core/icingaagent/tests/Test-IcingaAgentFeatureEnabled.psm1 new file mode 100644 index 0000000..a0f622c --- /dev/null +++ b/lib/core/icingaagent/tests/Test-IcingaAgentFeatureEnabled.psm1 @@ -0,0 +1,14 @@ +function Test-IcingaAgentFeatureEnabled() +{ + param( + [string]$Feature + ); + + $Features = Get-IcingaAgentFeatures; + + if ($Features.Enabled -Contains $Feature) { + return $TRUE; + } + + return $FALSE; +} diff --git a/lib/core/icingaagent/writers/Write-IcingaAgentApiConfig.psm1 b/lib/core/icingaagent/writers/Write-IcingaAgentApiConfig.psm1 new file mode 100644 index 0000000..50a235f --- /dev/null +++ b/lib/core/icingaagent/writers/Write-IcingaAgentApiConfig.psm1 @@ -0,0 +1,20 @@ +function Write-IcingaAgentApiConfig() +{ + param( + [int]$Port = 5665 + ); + + [string]$ApiConf = ''; + + $ApiConf = [string]::Format('{0}object ApiListener "api" {1}{2}', $ApiConf, '{', "`r`n"); + $ApiConf = [string]::Format('{0} accept_commands = true;{1}', $ApiConf, "`r`n"); + $ApiConf = [string]::Format('{0} accept_config = true;{1}', $ApiConf, "`r`n"); + $ApiConf = [string]::Format('{0} bind_host = "::";{1}', $ApiConf, "`r`n"); + $ApiConf = [string]::Format('{0} bind_port = {1};{2}', $ApiConf, $Port, "`r`n"); + $ApiConf = [string]::Format('{0}{1}{2}{2}', $ApiConf, '}', "`r`n"); + + $ApiConf = $ApiConf.Substring(0, $ApiConf.Length - 4); + + Set-Content -Path (Join-Path -Path (Get-IcingaAgentConfigDirectory) -ChildPath 'features-available\api.conf') -Value $ApiConf; + Write-Host 'Api configuration has been written successfully'; +} diff --git a/lib/core/icingaagent/writers/Write-IcingaAgentZonesConfig.psm1 b/lib/core/icingaagent/writers/Write-IcingaAgentZonesConfig.psm1 new file mode 100644 index 0000000..4729226 --- /dev/null +++ b/lib/core/icingaagent/writers/Write-IcingaAgentZonesConfig.psm1 @@ -0,0 +1,78 @@ +function Write-IcingaAgentZonesConfig() +{ + param( + [array]$Endpoints = @(), + [array]$EndpointConnections = @(), + [string]$ParentZone = '', + [array]$GlobalZones = @(), + [string]$Hostname = '' + ); + + if ($Endpoints.Count -eq 0) { + throw 'Please properly specify your endpoint names'; + } + + if ([string]::IsNullOrEmpty($ParentZone)) { + throw 'Please specify a parent zone this agent shall connect to / receives connections from'; + } + + if ([string]::IsNullOrEmpty($Hostname)) { + throw 'Please specify hostname for this agent configuration'; + } + + [int]$Index = 0; + [string]$ZonesConf = ''; + + $ZonesConf = [string]::Format('{0}object Endpoint "{1}" {2}{3}', $ZonesConf, $Hostname, '{', "`r`n"); + $ZonesConf = [string]::Format('{0}{1}{2}{2}', $ZonesConf, '}', "`r`n"); + + foreach ($endpoint in $Endpoints) { + $ZonesConf = [string]::Format('{0}object Endpoint "{1}" {2}{3}', $ZonesConf, $endpoint, '{', "`r`n"); + if ($EndpointConnections.Count -ne 0) { + $ConnectionConfig = Get-IPConfigFromString -IPConfig ($EndpointConnections[$Index]); + $ZonesConf = [string]::Format('{0} host = "{1}";{2}', $ZonesConf, $ConnectionConfig.address, "`r`n"); + if ([string]::IsNullOrEmpty($ConnectionConfig.port) -eq $FALSE) { + $ZonesConf = [string]::Format('{0} port = "{1}";{2}', $ZonesConf, $ConnectionConfig.port, "`r`n"); + } + } + $ZonesConf = [string]::Format('{0}{1}{2}{2}', $ZonesConf, '}', "`r`n"); + $Index += 1; + } + + [string]$EndpointString = ''; + foreach ($endpoint in $Endpoints) { + $EndpointString = [string]::Format( + '{0}"{1}", ', + $EndpointString, + $endpoint + ); + } + $EndpointString = $EndpointString.Substring(0, $EndpointString.Length - 2); + + $ZonesConf = [string]::Format('{0}object Zone "{1}" {2}{3}', $ZonesConf, $ParentZone, '{', "`r`n"); + $ZonesConf = [string]::Format('{0} endpoints = [ {1} ];{2}', $ZonesConf, $EndpointString, "`r`n"); + $ZonesConf = [string]::Format('{0}{1}{2}{2}', $ZonesConf, '}', "`r`n"); + + $ZonesConf = [string]::Format('{0}object Zone "{1}" {2}{3}', $ZonesConf, $Hostname, '{', "`r`n"); + $ZonesConf = [string]::Format('{0} parent = "{1}";{2}', $ZonesConf, $ParentZone, "`r`n"); + $ZonesConf = [string]::Format('{0} endpoints = [ "{1}" ];{2}', $ZonesConf, $Hostname, "`r`n"); + $ZonesConf = [string]::Format('{0}{1}{2}{2}', $ZonesConf, '}', "`r`n"); + + if ($GlobalZones.Contains('director-global') -eq $FALSE) { + $GlobalZones += 'director-global'; + } + if ($GlobalZones.Contains('global-templates') -eq $FALSE) { + $GlobalZones += 'global-templates'; + } + + foreach ($zone in $GlobalZones) { + $ZonesConf = [string]::Format('{0}object Zone "{1}" {2}{3}', $ZonesConf, $zone, '{', "`r`n"); + $ZonesConf = [string]::Format('{0} global = true;{1}', $ZonesConf, "`r`n"); + $ZonesConf = [string]::Format('{0}{1}{2}{2}', $ZonesConf, '}', "`r`n"); + } + + $ZonesConf = $ZonesConf.Substring(0, $ZonesConf.Length - 4); + + Set-Content -Path (Join-Path -Path (Get-IcingaAgentConfigDirectory) -ChildPath 'zones.conf') -Value $ZonesConf; + Write-Host 'Icinga Agent zones.conf has been written successfully'; +} diff --git a/lib/core/icingaagent/writers/Write-IcingaTestOutput.psm1 b/lib/core/icingaagent/writers/Write-IcingaTestOutput.psm1 new file mode 100644 index 0000000..bfb8110 --- /dev/null +++ b/lib/core/icingaagent/writers/Write-IcingaTestOutput.psm1 @@ -0,0 +1,29 @@ +function Write-IcingaTestOutput() +{ + param( + [ValidateSet('PASSED', 'WARNING', 'FAILED')] + $Severity, + $Message + ); + + $Color = 'Green'; + + Switch ($Severity) { + 'PASSED' { + $Color = 'Green'; + break; + }; + 'WARNING' { + $Color = 'Yellow'; + break; + }; + 'FAILED' { + $Color = 'Red'; + break; + }; + } + + Write-Host '[' -NoNewline; + Write-Host $Severity -ForegroundColor $Color -NoNewline; + Write-Host ']:' $Message; +} From eac6ba1cf37f9f28d0174ea98fbaa4fda87bc21c Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 29 Sep 2019 23:02:00 +0200 Subject: [PATCH 122/259] Fixed code styling --- lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 b/lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 index e1caf07..91f90f5 100644 --- a/lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 +++ b/lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 @@ -13,7 +13,7 @@ function Enable-IcingaAgentFeature() return; } - $Binary = Get-IcingaAGentBinary; + $Binary = Get-IcingaAgentBinary; $Process = Start-IcingaProcess -Executable $Binary -Arguments ([string]::Format('feature enable {0}', $Feature)); if ($Process.ExitCode -ne 0) { From e9c37bd0420fd0b1b114c270d47eee77f3d1f4de Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 30 Sep 2019 00:32:45 +0200 Subject: [PATCH 123/259] Changed AllowUpdate type for easier programmable use on Agent installation --- lib/core/icingaagent/installer/Install-IcingaAgent.psm1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/core/icingaagent/installer/Install-IcingaAgent.psm1 b/lib/core/icingaagent/installer/Install-IcingaAgent.psm1 index b869a1a..44eac5f 100644 --- a/lib/core/icingaagent/installer/Install-IcingaAgent.psm1 +++ b/lib/core/icingaagent/installer/Install-IcingaAgent.psm1 @@ -2,9 +2,9 @@ function Install-IcingaAgent() { param( [string]$Version, - [string]$Source = 'https://packages.icinga.com/windows/', - [string]$InstallDir = '', - [switch]$AllowUpdates + [string]$Source = 'https://packages.icinga.com/windows/', + [string]$InstallDir = '', + [bool]$AllowUpdates = $FALSE ); $IcingaData = Get-IcingaAgentInstallation; From 079b64aff1685b4814e3aa9c5e0c7c7d7241c07b Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 30 Sep 2019 00:33:17 +0200 Subject: [PATCH 124/259] Improved output while trying to enable/disable features --- lib/core/icingaagent/misc/Disable-IcingaAgentFeature.psm1 | 2 +- lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/core/icingaagent/misc/Disable-IcingaAgentFeature.psm1 b/lib/core/icingaagent/misc/Disable-IcingaAgentFeature.psm1 index d3ca9b8..983c340 100644 --- a/lib/core/icingaagent/misc/Disable-IcingaAgentFeature.psm1 +++ b/lib/core/icingaagent/misc/Disable-IcingaAgentFeature.psm1 @@ -9,7 +9,7 @@ function Disable-IcingaAgentFeature() } if ((Test-IcingaAgentFeatureEnabled -Feature $Feature) -eq $FALSE) { - Write-Host 'This feature is already disabled.' + Write-Host ([string]::Format('This feature is already disabled [{0}]', $Feature)); return; } diff --git a/lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 b/lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 index 91f90f5..6721a61 100644 --- a/lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 +++ b/lib/core/icingaagent/misc/Enable-IcingaAgentFeature.psm1 @@ -9,7 +9,7 @@ function Enable-IcingaAgentFeature() } if ((Test-IcingaAgentFeatureEnabled -Feature $Feature)) { - Write-Host 'This feature is already enabled.' + Write-Host ([string]::Format('This feature is already enabled [{0}]', $Feature)); return; } From b3ac481904759e8e5600b4df698a66d3abb2df0a Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 30 Sep 2019 00:34:01 +0200 Subject: [PATCH 125/259] Added missing tool function to start processes --- lib/core/tools/Start-IcingaProcess.psm1 | 37 +++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 lib/core/tools/Start-IcingaProcess.psm1 diff --git a/lib/core/tools/Start-IcingaProcess.psm1 b/lib/core/tools/Start-IcingaProcess.psm1 new file mode 100644 index 0000000..4ee2a06 --- /dev/null +++ b/lib/core/tools/Start-IcingaProcess.psm1 @@ -0,0 +1,37 @@ +function Start-IcingaProcess() +{ + param( + [string]$Executable, + [string]$Arguments, + [switch]$FlushNewLines + ); + + $processData = New-Object System.Diagnostics.ProcessStartInfo; + $processData.FileName = $Executable; + $processData.RedirectStandardError = $true; + $processData.RedirectStandardOutput = $true; + $processData.UseShellExecute = $false; + $processData.Arguments = $Arguments; + + $process = New-Object System.Diagnostics.Process; + $process.StartInfo = $processData; + $process.Start() | Out-Null; + + $stdout = $process.StandardOutput.ReadToEnd(); + $stderr = $process.StandardError.ReadToEnd(); + $process.WaitForExit(); + + if ($flushNewLines) { + $stdout = $stdout.Replace("`n", '').Replace("`r", ''); + $stderr = $stderr.Replace("`n", '').Replace("`r", ''); + } else { + if ($stdout.Contains("`n")) { + $stdout = $stdout.Substring(0, $stdout.LastIndexOf("`n")); + } + } + return @{ + 'Message' = $stdout; + 'Error' = $stderr; + 'ExitCode' = $process.ExitCode; + }; +} From 5190851b96376c5d41d841da9c4961270a68b634 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 30 Sep 2019 00:35:29 +0200 Subject: [PATCH 126/259] Added first beta for CLI guided install wizard for the Agent --- .../misc/Start-IcingaAgentInstallWizard.psm1 | 282 ++++++++++++++++++ 1 file changed, 282 insertions(+) create mode 100644 lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 new file mode 100644 index 0000000..f551460 --- /dev/null +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -0,0 +1,282 @@ +function Start-IcingaAgentInstallWizard() +{ + param( + [string]$Hostname, + [switch]$AutoUseFQDN = $FALSE, + [switch]$AutoUseHostname = $FALSE, + [switch]$LowerCase = $FALSE, + [switch]$UpperCase = $FALSE, + [string]$PackageSource, + [string]$AgentVersion, + [switch]$AllowVersionChanges = $FALSE, + $UpdateAgent = $null, + $AcceptConnections = $null, + [array]$Endpoints = @(), + [array]$EndpointConnections = @(), + [string]$ParentZone, + [array]$GlobalZones = $null, + [string]$CAEndpoint, + $CAPort = $null, + [string]$Ticket, + [string]$CAFile, + [switch]$RunInstaller, + [switch]$Reconfigure + ); + + [array]$InstallerArguments = @(); + + if ([string]::IsNullOrEmpty($Hostname) -And $AutoUseFQDN -eq $FALSE -And $AutoUseHostname -eq $FALSE) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to manually specify a hostname?' -Default 'n').result -eq 1) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to automatically fetch the hostname with its FQDN?' -Default 'y').result -eq 1) { + $InstallerArguments += '-AutoUseFQDN'; + $AutoUseFQDN = $TRUE; + } else { + $InstallerArguments += '-AutoUseHostname'; + $AutoUseHostname = $TRUE; + } + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to modify the hostname to only include lower case characters?' -Default 'y').result -eq 1) { + $InstallerArguments += '-LowerCase'; + $LowerCase = $TRUE; + } else { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to modify the hostname to only include upper case characters?' -Default 'n').result -eq 0) { + $InstallerArguments += '-UpperCase'; + $UpperCase = $TRUE; + } + } + $Hostname = Get-IcingaHostname -AutoUseFQDN $AutoUseFQDN -AutoUseHostname $AutoUseHostname -LowerCase $LowerCase -UpperCase $UpperCase; + } else { + $Hostname = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the hostname to use' -Default 'v').answer; + } + } else { + if ($AutoUseFQDN -Or $AutoUseHostname) { + $Hostname = Get-IcingaHostname -AutoUseFQDN $AutoUseFQDN -AutoUseHostname $AutoUseHostname -LowerCase $LowerCase -UpperCase $UpperCase; + } + } + + Write-Host ([string]::Format('Using hostname "{0}" for the Icinga 2 Agent configuration', $Hostname)); + + $IcingaAgent = Get-IcingaAgentInstallation; + if ($IcingaAgent.Installed -eq $FALSE) { + if ([string]::IsNullOrEmpty($PackageSource)) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to install the Icinga Agent now?' -Default 'y').result -eq 1) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to use a different package source then "https://packages.icinga.com/windows/" ?' -Default 'n').result -eq 0) { + $PackageSource = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify your package source' -Default 'v').answer; + $InstallerArguments += "-PackageSource '$PackageSource'"; + } else { + $PackageSource = 'https://packages.icinga.com/windows/' + $InstallerArguments += "-PackageSource '$PackageSource'"; + } + + Write-Host ([string]::Format('Using package source "{0}" for the Icinga 2 Agent package', $PackageSource)); + } + + if ([string]::IsNullOrEmpty($AgentVersion)) { + $AgentVersion = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the version you wish to install ("latest", "snapshot", or a version like "2.11.0")' -Default 'v').answer; + $InstallerArguments += "-AgentVersion '$AgentVersion'"; + + Write-Host ([string]::Format('Installing Icinga Version: "{0}"', $AgentVersion)); + } + } + } else { + if ($null -eq $UpdateAgent) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'The Icinga 2 Agent is already installed. Would you like to update it?' -Default 'y').result -eq 1) { + $UpdateAgent = 1; + } else { + $UpdateAgent = 0; + } + $InstallerArguments += "-UpdateAgent $UpdateAgent"; + } + + if ($UpdateAgent -eq 1) { + if ([string]::IsNullOrEmpty($AgentVersion)) { + $AgentVersion = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the version you wish to install ("latest", "snapshot", or a version like "2.11.0")' -Default 'v').answer; + $AllowVersionChanges = $TRUE; + $InstallerArguments += "-AgentVersion '$AgentVersion'"; + $InstallerArguments += '-AllowVersionChanges'; + + Write-Host ([string]::Format('Updating/Downgrading Icinga 2 Agent to version: "{0}"', $AgentVersion)); + } + + if ([string]::IsNullOrEmpty($PackageSource)) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to use a different package source then "https://packages.icinga.com/windows/" ?' -Default 'n').result -eq 0) { + $PackageSource = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify your package source' -Default 'v').answer; + $InstallerArguments += "-PackageSource '$PackageSource'"; + } else { + $PackageSource = 'https://packages.icinga.com/windows/' + $InstallerArguments += "-PackageSource '$PackageSource'"; + } + } + } + } + + if ($null -eq $AcceptConnections) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Will this Agent connect to its parent endpoint(s)?' -Default 'y').result -eq 1) { + $InstallerArguments += "-AcceptConnections 1"; + $AcceptConnections = 1; + } else { + $InstallerArguments += "-AcceptConnections 0"; + $AcceptConnections = 0; + } + } + + if ($Endpoints.Count -eq 0) { + $ArrayString = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify all endpoints this Agent will report to (separated by ",")' -Default 'v').answer; + $Endpoints = ($ArrayString.Replace(' ', '')).Split(','); + $InstallerArguments += ("-Endpoints " + ([string]::Join(',', $Endpoints))); + } + + if ($EndpointConnections.Count -eq 0 -And $AcceptConnections -eq 1) { + $ArrayString = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the network destinations this agent will connect to ("," separated, like: "[127.0.0.1], [127.0.0.2]")' -Default 'v').answer; + $EndpointConnections = ($ArrayString.Replace(' ', '')).Split(','); + $InstallerArguments += ("-EndpointConnections " + ([string]::Join(',', $EndpointConnections))); + } + + if ([string]::IsNullOrEmpty($ParentZone)) { + $ParentZone = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the parent zone this agent will connect to' -Default 'v').answer; + $InstallerArguments += "-ParentZone $ParentZone"; + } + + if ($null -eq $GlobalZones) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to add additional global zones, besides "director-global" and "global-templates"?' -Default 'n').result -eq 0) { + $ArrayString = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify your additional zones seperated by ","' -Default 'v').answer; + $GlobalZones = ($ArrayString.Replace(' ', '')).Split(','); + $InstallerArguments += ("-GlobalZones " + ([string]::Join(',', $GlobalZones))); + } else { + $GlobalZones = @(); + } + } + + [bool]$CanConnectToParent = $FALSE; + + if ($AcceptConnections -eq 0) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Is this Agent able to connect to its parent node for certificate generation?' -Default 'y').result -eq 1) { + $CanConnectToParent = $TRUE; + } + } else { + $CanConnectToParent = $TRUE; + } + + if ($CanConnectToParent) { + if ([string]::IsNullOrEmpty($CAEndpoint)) { + $CAEndpoint = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the FQDN for either ONE of your Icinga parent node/nodes or your Icinga 2 CA master (if you can connect to it)' -Default 'v').answer; + $InstallerArguments += "-CAEndpoint $CAEndpoint"; + } + if ($null -eq $CAPort) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Are you using a different port then 5665 for Icinga communications?' -Default 'n').result -eq 0) { + $CAPort = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter your port to communicate with the Icinga 2 CA' -Default 'v').answer; + $InstallerArguments += "-CAPort $CAPort"; + } else { + $InstallerArguments += "-CAPort 5665"; + $CAPort = 5665; + } + } + if ([string]::IsNullOrEmpty($Ticket)) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you have a Icinga Ticket available to sign your certificate?' -Default 'y').result -eq 1) { + $Ticket = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter your Icinga Ticket' -Default 'v').answer; + $InstallerArguments += "-Ticket $Ticket"; + } + } + } else { + if ([string]::IsNullOrEmpty($CAFile)) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Is your public Icinga 2 CA (ca.crt) available on a local, network or web share?' -Default 'y').result -eq 1) { + $CAFile = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please provide the full path to your ca.crt file' -Default 'v').answer; + $InstallerArguments += "-CAFile $CAFile"; + } + } + } + + if ($InstallerArguments.Count -ne 0) { + $InstallerArguments += "-RunInstaller"; + Write-Host 'The wizard is complete. These are the configured settings:'; + Write-Host ($InstallerArguments | Out-String); + + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Is this configuration correct?' -Default 'y').result -eq 1) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to run the installer now? (Otherwise only the configration command will be printed)' -Default 'y').result -eq 1) { + Write-Host 'To execute your Icinga Agent installation based on your answers again on this or another machine, simply run this command:' + + $RunInstaller = $TRUE; + } else { + Write-Host 'To execute your Icinga Agent installation based on your answers, simply run this command:' + } + } else { + Write-Host 'Please run the wizard again to modify your answers or modify the command below:' + } + Get-IcingaAgentInstallCommand -InstallerArguments $InstallerArguments -PrintConsole; + } + + if ($RunInstaller) { + if ((Install-IcingaAgent -Version $AgentVersion -Source $PackageSource -AllowUpdates $AllowVersionChanges) -Or $Reconfigure) { + Move-IcingaAgentDefaultConfig; + Install-IcingaAgentBaseFeatures; + Install-IcingaAgentCertificates -Hostname $Hostname -Endpoint $CAEndpoint -Port $CAPort -CACert $CAFile -Ticket $Ticket | Out-Null; + Write-IcingaAgentApiConfig -Port $CAPort; + Write-IcingaAgentZonesConfig -Endpoints $Endpoints -EndpointConnections $EndpointConnections -ParentZone $ParentZone -GlobalZones $GlobalZones -Hostname $Hostname; + Test-IcingaAgent; + Restart-Service icinga2; + } + } +} + +function Get-IcingaAgentInstallCommand() +{ + param( + $InstallerArguments, + [switch]$PrintConsole + ); + + [string]$Installer = ( + [string]::Format( + 'Start-IcingaAgentInstallWizard {0}', + ([string]::Join(' ', $InstallerArguments)) + ) + ); + + if ($PrintConsole) { + Write-Host '####' + Write-Host $Installer -ForegroundColor ([System.ConsoleColor]::Cyan); + Write-Host '####' + } else { + return $Installer; + } +} + +function Get-IcingaAgentInstallerAnswerInput() +{ + param( + $Prompt, + [ValidateSet("y","n","v")] + $Default + ); + + $DefaultAnswer = ''; + + if ($Default -eq 'y') { + $DefaultAnswer = ' (Y/n)'; + } elseif ($Default -eq 'n') { + $DefaultAnswer = ' (y/N)'; + } + + $answer = Read-Host -Prompt ([string]::Format('{0}{1}', $Prompt, $DefaultAnswer)); + $answer = $answer.ToLower(); + + if ($Default -ne 'v') { + $returnValue = 0; + if ([string]::IsNullOrEmpty($answer) -Or $answer -eq $Default) { + $returnValue = 1; + } else { + $returnValue = 0; + } + + return @{ + 'result' = $returnValue; + 'answer' = ''; + } + } + + return @{ + 'result' = 2; + 'answer' = $answer; + } +} + +Export-ModuleMember -Function @( 'Start-IcingaAgentInstallWizard' ); From a1f7adc89ae4318cae68645b45e2b8ff312a0cb6 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 5 Oct 2019 21:50:13 +0200 Subject: [PATCH 127/259] Improved constructing of Performance Data --- lib/icinga/plugin/New-IcingaCheck.psm1 | 28 +++--------- lib/icinga/plugin/New-IcingaCheckResult.psm1 | 2 +- .../New-IcingaPerformanceDataEntry.psm1 | 43 +++++++++++++++++++ .../plugin/Write-IcingaPluginPerfData.psm1 | 25 +++++++++-- 4 files changed, 73 insertions(+), 25 deletions(-) create mode 100644 lib/icinga/plugin/New-IcingaPerformanceDataEntry.psm1 diff --git a/lib/icinga/plugin/New-IcingaCheck.psm1 b/lib/icinga/plugin/New-IcingaCheck.psm1 index 35be1e5..d949508 100644 --- a/lib/icinga/plugin/New-IcingaCheck.psm1 +++ b/lib/icinga/plugin/New-IcingaCheck.psm1 @@ -647,36 +647,22 @@ function New-IcingaCheck() $this.AutodiscoverMinMax(); - if ([string]::IsNullOrEmpty($this.minimum) -eq $FALSE) { - $this.minimum = [string]::Format(';{0}', $this.minimum); - } - if ([string]::IsNullOrEmpty($this.maximum) -eq $FALSE) { - $this.maximum = [string]::Format(';{0}', $this.maximum); - } - $this.completed = $TRUE; [string]$LabelName = (Format-IcingaPerfDataLabel $this.name); - return @{ - 'label' = $LabelName; - 'perfdata' = [string]::Format( - "'{0}'={1}{2};{3};{4}{5}{6} ", - $LabelName, - (Format-IcingaPerfDataValue $this.value), - $this.unit, - (Format-IcingaPerfDataValue $this.warning), - (Format-IcingaPerfDataValue $this.critical), - (Format-IcingaPerfDataValue $this.minimum), - (Format-IcingaPerfDataValue $this.maximum) - ); + $perfdata = @{ + 'label' = $LabelName; + 'perfdata' = ''; 'unit' = $this.unit; 'value' = (Format-IcingaPerfDataValue $this.value); 'warning' = (Format-IcingaPerfDataValue $this.warning); 'critical' = (Format-IcingaPerfDataValue $this.critical); - 'minimum' = (Format-IcingaPerfDataValue ($this.minimum).Replace(';', '')); - 'maximum' = (Format-IcingaPerfDataValue ($this.maximum).Replace(';', '')); + 'minimum' = (Format-IcingaPerfDataValue $this.minimum); + 'maximum' = (Format-IcingaPerfDataValue $this.maximum); 'package' = $FALSE; }; + + return $perfdata; } $Check | Add-Member -membertype ScriptMethod -name 'AutodiscoverMinMax' -value { diff --git a/lib/icinga/plugin/New-IcingaCheckResult.psm1 b/lib/icinga/plugin/New-IcingaCheckResult.psm1 index e7bc075..9db2518 100644 --- a/lib/icinga/plugin/New-IcingaCheckResult.psm1 +++ b/lib/icinga/plugin/New-IcingaCheckResult.psm1 @@ -24,7 +24,7 @@ function New-IcingaCheckresult() $this.check.Compile($TRUE) | Out-Null; if ([int]$this.check.exitcode -ne [int]$IcingaEnums.IcingaExitCode.Unknown -And -Not $this.noperfdata) { - Write-IcingaPluginPerfData ($this.check.GetPerfData().perfdata); + Write-IcingaPluginPerfData -PerformanceData ($this.check.GetPerfData().perfdata) -CheckCommand $CheckCommand; } return $this.check.exitcode; diff --git a/lib/icinga/plugin/New-IcingaPerformanceDataEntry.psm1 b/lib/icinga/plugin/New-IcingaPerformanceDataEntry.psm1 new file mode 100644 index 0000000..f0eeb74 --- /dev/null +++ b/lib/icinga/plugin/New-IcingaPerformanceDataEntry.psm1 @@ -0,0 +1,43 @@ +function New-IcingaPerformanceDataEntry() +{ + param ( + $PerfDataObject, + $Label = $null, + $Value = $null + ); + + if ($null -eq $PerfDataObject) { + return ''; + } + + [string]$LabelName = $PerfDataObject.label; + [string]$PerfValue = $PerfDataObject.value; + + if ([string]::IsNullOrEmpty($Label) -eq $FALSE) { + $LabelName = $Label; + } + if ([string]::IsNullOrEmpty($Value) -eq $FALSE) { + $PerfValue = $Value; + } + + $minimum = ''; + $maximum = ''; + + if ([string]::IsNullOrEmpty($PerfDataObject.minimum) -eq $FALSE) { + $minimum = [string]::Format(';{0}', $PerfDataObject.minimum); + } + if ([string]::IsNullOrEmpty($PerfDataObject.maximum) -eq $FALSE) { + $maximum = [string]::Format(';{0}', $PerfDataObject.maximum); + } + + return ([string]::Format( + "'{0}'={1}{2};{3};{4}{5}{6} ", + $LabelName, + (Format-IcingaPerfDataValue $PerfValue), + $PerfDataObject.unit, + (Format-IcingaPerfDataValue $PerfDataObject.warning), + (Format-IcingaPerfDataValue $PerfDataObject.critical), + (Format-IcingaPerfDataValue $minimum), + (Format-IcingaPerfDataValue $maximum) + )); +} diff --git a/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 b/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 index caab482..2199803 100644 --- a/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 +++ b/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 @@ -1,10 +1,12 @@ function Write-IcingaPluginPerfData() { param( - $PerformanceData + $PerformanceData, + $CheckCommand ); - [string]$PerfDataOutput = (Get-IcingaPluginPerfDataContent -PerfData $PerformanceData); + $CheckResultCache = Get-IcingaCacheData -Space 'sc_daemon' -CacheStore 'checkresult' -KeyName $CheckCommand; + [string]$PerfDataOutput = (Get-IcingaPluginPerfDataContent -PerfData $PerformanceData -CheckResultCache $CheckResultCache); Write-Host ([string]::Format('| {0}', $PerfDataOutput)); } @@ -12,6 +14,7 @@ function Get-IcingaPluginPerfDataContent() { param( $PerfData, + $CheckResultCache, [bool]$AsObject = $FALSE ); @@ -21,8 +24,24 @@ function Get-IcingaPluginPerfDataContent() $data = $PerfData[$package]; if ($data.package) { $PerfDataOutput += (Get-IcingaPluginPerfDataContent -PerfData $data.perfdata -AsObject $AsObject); + $PerfDataOutput += (Get-IcingaPluginPerfDataContent -PerfData $data.perfdata -CheckResultCache $CheckResultCache -AsObject $AsObject); } else { - $PerfDataOutput += $data.perfdata; + foreach ($checkresult in $CheckResultCache.PSobject.Properties) { + $SearchPattern = [string]::Format('{0}_', $data.label); + $SearchEntry = $checkresult.Name; + if ($SearchEntry -like "$SearchPattern*") { + $cachedresult = (New-IcingaPerformanceDataEntry -PerfDataObject $data -Label $SearchEntry -Value $checkresult.Value); + + if ($AsObject) { + $global:IcingaThreadContent['Scheduler']['PluginPerfData'] += $cachedresult; + } + $PerfDataOutput += $cachedresult; + } + } + + $compiledPerfData = (New-IcingaPerformanceDataEntry $data); + + $PerfDataOutput += $compiledPerfData; } } From bb62fb247d8089b8ef6c06432c5d71c08c157b3f Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 5 Oct 2019 21:50:49 +0200 Subject: [PATCH 128/259] Fixed duplicate Performance Data output --- lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 | 1 - 1 file changed, 1 deletion(-) diff --git a/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 b/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 index 2199803..4cc86cf 100644 --- a/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 +++ b/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 @@ -23,7 +23,6 @@ function Get-IcingaPluginPerfDataContent() foreach ($package in $PerfData.Keys) { $data = $PerfData[$package]; if ($data.package) { - $PerfDataOutput += (Get-IcingaPluginPerfDataContent -PerfData $data.perfdata -AsObject $AsObject); $PerfDataOutput += (Get-IcingaPluginPerfDataContent -PerfData $data.perfdata -CheckResultCache $CheckResultCache -AsObject $AsObject); } else { foreach ($checkresult in $CheckResultCache.PSobject.Properties) { From 887c5511d5ed05798bc3bdf35cd51acf9e1b250e Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 5 Oct 2019 21:51:39 +0200 Subject: [PATCH 129/259] Added helper functions for Arrays and Hashtables --- lib/core/tools/Add-IcingaHashtableItem.psm1 | 24 +++++++++++++++++++ lib/core/tools/Pop-IcingaArrayListItem.psm1 | 19 +++++++++++++++ .../tools/Remove-IcingaHashtableItem.psm1 | 15 ++++++++++++ 3 files changed, 58 insertions(+) create mode 100644 lib/core/tools/Add-IcingaHashtableItem.psm1 create mode 100644 lib/core/tools/Pop-IcingaArrayListItem.psm1 create mode 100644 lib/core/tools/Remove-IcingaHashtableItem.psm1 diff --git a/lib/core/tools/Add-IcingaHashtableItem.psm1 b/lib/core/tools/Add-IcingaHashtableItem.psm1 new file mode 100644 index 0000000..49a2b0e --- /dev/null +++ b/lib/core/tools/Add-IcingaHashtableItem.psm1 @@ -0,0 +1,24 @@ +function Add-IcingaHashtableItem() +{ + param( + $Hashtable, + $Key, + $Value, + [switch]$Override + ); + + if ($null -eq $Hashtable) { + return $FALSE; + } + + if ($Hashtable.ContainsKey($Key) -eq $FALSE) { + $Hashtable.Add($Key, $Value); + return $TRUE; + } else { + if ($Override) { + $Hashtable[$Key] = $Value; + return $TRUE; + } + } + return $FALSE; +} diff --git a/lib/core/tools/Pop-IcingaArrayListItem.psm1 b/lib/core/tools/Pop-IcingaArrayListItem.psm1 new file mode 100644 index 0000000..b6ed815 --- /dev/null +++ b/lib/core/tools/Pop-IcingaArrayListItem.psm1 @@ -0,0 +1,19 @@ +function Pop-IcingaArrayListItem() +{ + param( + [System.Collections.ArrayList]$Array + ); + + if ($null -eq $Array) { + return $null; + } + + if ($Array.Count -eq 0) { + return $null; + } + + $Content = $Array[0]; + $Array.RemoveAt(0); + + return $Content; +} diff --git a/lib/core/tools/Remove-IcingaHashtableItem.psm1 b/lib/core/tools/Remove-IcingaHashtableItem.psm1 new file mode 100644 index 0000000..8be4987 --- /dev/null +++ b/lib/core/tools/Remove-IcingaHashtableItem.psm1 @@ -0,0 +1,15 @@ +function Remove-IcingaHashtableItem() +{ + param( + $Hashtable, + $Key + ); + + if ($null -eq $Hashtable) { + return; + } + + if ($Hashtable.ContainsKey($Key)) { + $Hashtable.Remove($Key); + } +} From 27ec8613afc5edc5c9e4583599b147b41d05bf7b Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 5 Oct 2019 21:52:49 +0200 Subject: [PATCH 130/259] Added Cmdlet for fetching config directory --- core/init.ps1 | 1 + icinga-module-windows.psd1 | 2 +- icinga-module-windows.psm1 | 6 ++++++ 3 files changed, 8 insertions(+), 1 deletion(-) diff --git a/core/init.ps1 b/core/init.ps1 index f8e41da..ac4b829 100644 --- a/core/init.ps1 +++ b/core/init.ps1 @@ -11,6 +11,7 @@ Set-Variable -Name Icinga2 -Option Constant -Value @{ 'Import-IcingaLib', 'Get-IcingaPluginDir', 'Get-IcingaCacheDir', + 'Get-IcingaPowerShellConfigDir', 'Get-Icinga-Lib', 'Get-Icinga-Object', 'Get-Icinga-Service', diff --git a/icinga-module-windows.psd1 b/icinga-module-windows.psd1 index c1e1e85..3ae95d2 100644 --- a/icinga-module-windows.psd1 +++ b/icinga-module-windows.psd1 @@ -25,7 +25,7 @@ Description = 'Icinga 2 Windows Agent Module, which allows to entirely monitor t PowerShellVersion = '3.0' # Aus diesem Modul zu exportierende Funktionen. Um optimale Leistung zu erzielen, verwenden Sie keine Platzhalter und löschen den Eintrag nicht. Verwenden Sie ein leeres Array, wenn keine zu exportierenden Funktionen vorhanden sind. -FunctionsToExport = @( 'Use-Icinga', 'Import-IcingaLib', 'Get-IcingaPluginDir', 'Get-IcingaCacheDir', 'Start-Icinga-Checker', 'Stop-Icinga-Checker', 'Get-Icinga-Lib', 'Get-Icinga-Object', 'Get-Icinga-Service', 'Start-Icinga-Service', 'Stop-Icinga-Service', 'Restart-Icinga-Service', 'Install-Icinga-Service', 'Uninstall-Icinga-Service', 'Get-Icinga-Setup', 'Install-Icinga', 'Start-Icinga-Daemon', 'Stop-Icinga-Daemon', 'Icinga-Client', 'Get-Icinga-Command', 'New-Icinga-Monitoring', 'Get-Icinga-Counter', 'Get-Icinga-Config', 'Set-Icinga-Config', 'Remove-Icinga-Config', 'New-Icinga-Config' ) +FunctionsToExport = @( 'Use-Icinga', 'Import-IcingaLib', 'Get-IcingaPluginDir', 'Get-IcingaCacheDir', 'Get-IcingaPowerShellConfigDir', 'Start-Icinga-Checker', 'Stop-Icinga-Checker', 'Get-Icinga-Lib', 'Get-Icinga-Object', 'Get-Icinga-Service', 'Start-Icinga-Service', 'Stop-Icinga-Service', 'Restart-Icinga-Service', 'Install-Icinga-Service', 'Uninstall-Icinga-Service', 'Get-Icinga-Setup', 'Install-Icinga', 'Start-Icinga-Daemon', 'Stop-Icinga-Daemon', 'Icinga-Client', 'Get-Icinga-Command', 'New-Icinga-Monitoring', 'Get-Icinga-Counter', 'Get-Icinga-Config', 'Set-Icinga-Config', 'Remove-Icinga-Config', 'New-Icinga-Config' ) # Aus diesem Modul zu exportierende Cmdlets. Um optimale Leistung zu erzielen, verwenden Sie keine Plat'zhalter und löschen den Eintrag nicht. Verwenden Sie ein leeres Array, wenn keine zu exportierenden Cmdlets vorhanden sind. CmdletsToExport = @() diff --git a/icinga-module-windows.psm1 b/icinga-module-windows.psm1 index a03a454..be3c8e3 100644 --- a/icinga-module-windows.psm1 +++ b/icinga-module-windows.psm1 @@ -84,6 +84,12 @@ function Get-IcingaCacheDir() { return (Join-Path -Path $PSScriptRoot -ChildPath 'cache'); } + +function Get-IcingaPowerShellConfigDir() +{ + return (Join-Path -Path $PSScriptRoot -ChildPath 'config'); +} + function Install-Icinga() { [string]$command = Get-Icinga-Command('setup'); From 831bbd5ced0afd9bfa651ceb38e8cbeb9880f9f0 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 5 Oct 2019 21:54:24 +0200 Subject: [PATCH 131/259] Prepared module for running as daemon --- icinga-module-windows.psm1 | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/icinga-module-windows.psm1 b/icinga-module-windows.psm1 index be3c8e3..adfe97a 100644 --- a/icinga-module-windows.psm1 +++ b/icinga-module-windows.psm1 @@ -11,9 +11,28 @@ function Use-Icinga() { + param( + [switch]$LibOnly = $FALSE, + [switch]$Daemon = $FALSE + ); + # This function will allow us to load this entire module including possible # actions, making it available within our shell environment Import-IcingaLib '\' -Init; + + if ($LibOnly -eq $FALSE) { + $global:IcingaThreads = [hashtable]::Synchronized(@{}); + $global:IcingaThreadContent = [hashtable]::Synchronized(@{}); + $global:IcingaThreadPool = [hashtable]::Synchronized(@{}); + $global:IcingaDaemonData = [hashtable]::Synchronized( + @{ + 'IcingaThreads' = $global:IcingaThreads; + 'IcingaThreadContent' = $global:IcingaThreadContent; + 'IcingaThreadPool' = $global:IcingaThreadPool; + 'FrameworkRunningAsDaemon' = $Daemon; + } + ); + } } function Import-IcingaLib() From fa642e48e4d6f420cc3a7a5d59473c1bbd3f8091 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 5 Oct 2019 21:56:23 +0200 Subject: [PATCH 132/259] Added support to manage framework config --- lib/config/Get-IcingaConfigTreeCount.psm1 | 25 +++++++++++++++ lib/config/Get-IcingaPowerShellConfig.psm1 | 20 ++++++++++++ .../New-IcingaPowerShellConfigItem.psm1 | 14 ++++++++ lib/config/Read-IcingaPowerShellConfig.psm1 | 23 +++++++++++++ lib/config/Remove-IcingaPowerShellConfig.psm1 | 32 +++++++++++++++++++ lib/config/Set-IcingaPowerShellConfig.psm1 | 31 ++++++++++++++++++ .../Test-IcingaPowerShellConfigItem.psm1 | 9 ++++++ lib/config/Write-IcingaPowerShellConfig.psm1 | 23 +++++++++++++ 8 files changed, 177 insertions(+) create mode 100644 lib/config/Get-IcingaConfigTreeCount.psm1 create mode 100644 lib/config/Get-IcingaPowerShellConfig.psm1 create mode 100644 lib/config/New-IcingaPowerShellConfigItem.psm1 create mode 100644 lib/config/Read-IcingaPowerShellConfig.psm1 create mode 100644 lib/config/Remove-IcingaPowerShellConfig.psm1 create mode 100644 lib/config/Set-IcingaPowerShellConfig.psm1 create mode 100644 lib/config/Test-IcingaPowerShellConfigItem.psm1 create mode 100644 lib/config/Write-IcingaPowerShellConfig.psm1 diff --git a/lib/config/Get-IcingaConfigTreeCount.psm1 b/lib/config/Get-IcingaConfigTreeCount.psm1 new file mode 100644 index 0000000..a295d52 --- /dev/null +++ b/lib/config/Get-IcingaConfigTreeCount.psm1 @@ -0,0 +1,25 @@ +function Get-IcingaConfigTreeCount() +{ + param( + $Path = '' + ); + + $Config = Read-IcingaPowerShellConfig; + $PathArray = $Path.Split('.'); + $ConfigObject = $Config; + [int]$Count = 0; + + foreach ($entry in $PathArray) { + if (-Not (Test-IcingaPowerShellConfigItem -ConfigObject $ConfigObject -ConfigKey $entry)) { + continue; + } + + $ConfigObject = $ConfigObject.$entry; + } + + foreach ($config in $ConfigObject.PSObject.Properties) { + $Count += 1; + } + + return $Count; +} diff --git a/lib/config/Get-IcingaPowerShellConfig.psm1 b/lib/config/Get-IcingaPowerShellConfig.psm1 new file mode 100644 index 0000000..65abd70 --- /dev/null +++ b/lib/config/Get-IcingaPowerShellConfig.psm1 @@ -0,0 +1,20 @@ +function Get-IcingaPowerShellConfig() +{ + param( + $Path = '' + ); + + $Config = Read-IcingaPowerShellConfig; + $PathArray = $Path.Split('.'); + $ConfigObject = $Config; + + foreach ($entry in $PathArray) { + if (-Not (Test-IcingaPowerShellConfigItem -ConfigObject $ConfigObject -ConfigKey $entry)) { + return $null; + } + + $ConfigObject = $ConfigObject.$entry; + } + + return $ConfigObject; +} diff --git a/lib/config/New-IcingaPowerShellConfigItem.psm1 b/lib/config/New-IcingaPowerShellConfigItem.psm1 new file mode 100644 index 0000000..ddff776 --- /dev/null +++ b/lib/config/New-IcingaPowerShellConfigItem.psm1 @@ -0,0 +1,14 @@ +function New-IcingaPowerShellConfigItem() +{ + param( + $ConfigObject, + [string]$ConfigKey, + $ConfigValue = $null + ); + + if ($null -eq $ConfigValue) { + $ConfigValue = (New-Object -TypeName PSOBject); + } + + $ConfigObject | Add-Member -MemberType NoteProperty -Name $ConfigKey -Value $ConfigValue; +} diff --git a/lib/config/Read-IcingaPowerShellConfig.psm1 b/lib/config/Read-IcingaPowerShellConfig.psm1 new file mode 100644 index 0000000..cf989f2 --- /dev/null +++ b/lib/config/Read-IcingaPowerShellConfig.psm1 @@ -0,0 +1,23 @@ +function Read-IcingaPowerShellConfig() +{ + $ConfigDir = Get-IcingaPowerShellConfigDir; + $ConfigFile = Join-Path -Path $ConfigDir -ChildPath 'config.json'; + + if ($global:IcingaDaemonData.FrameworkRunningAsDaemon) { + if ($global:IcingaDaemonData.ContainsKey('Config')) { + return $global:IcingaDaemonData.Config; + } + } + + if (-Not (Test-Path $ConfigFile)) { + return (New-Object -TypeName PSOBject); + } + + [string]$Content = Get-Content -Path $ConfigFile; + + if ([string]::IsNullOrEmpty($Content)) { + return (New-Object -TypeName PSOBject); + } + + return (ConvertFrom-Json -InputObject $Content); +} diff --git a/lib/config/Remove-IcingaPowerShellConfig.psm1 b/lib/config/Remove-IcingaPowerShellConfig.psm1 new file mode 100644 index 0000000..a6c0dfd --- /dev/null +++ b/lib/config/Remove-IcingaPowerShellConfig.psm1 @@ -0,0 +1,32 @@ +function Remove-IcingaPowerShellConfig() +{ + param( + $Path = '' + ); + + if ([string]::IsNullOrEmpty($Path)) { + throw 'Please specify a valid path to an object'; + } + + $Config = Read-IcingaPowerShellConfig; + $PathArray = $Path.Split('.'); + $ConfigObject = $Config; + [int]$Index = $PathArray.Count; + + foreach ($entry in $PathArray) { + + if (-Not (Test-IcingaPowerShellConfigItem -ConfigObject $ConfigObject -ConfigKey $entry)) { + return $null; + } + + if ($index -eq 1) { + $ConfigObject.PSObject.Properties.Remove($entry); + break; + } + + $ConfigObject = $ConfigObject.$entry; + $Index -= 1; + } + + Write-IcingaPowerShellConfig $Config; +} diff --git a/lib/config/Set-IcingaPowerShellConfig.psm1 b/lib/config/Set-IcingaPowerShellConfig.psm1 new file mode 100644 index 0000000..195d6e1 --- /dev/null +++ b/lib/config/Set-IcingaPowerShellConfig.psm1 @@ -0,0 +1,31 @@ +function Set-IcingaPowerShellConfig() +{ + param( + $Path = '', + $Value = $null + ); + + $Config = Read-IcingaPowerShellConfig; + $PathArray = $Path.Split('.'); + $ConfigObject = $Config; + [int]$Index = $PathArray.Count; + $InputValue = $null; + foreach ($entry in $PathArray) { + if ($index -eq 1) { + $InputValue = $Value; + } + if (-Not (Test-IcingaPowerShellConfigItem -ConfigObject $ConfigObject -ConfigKey $entry)) { + New-IcingaPowerShellConfigItem -ConfigObject $ConfigObject -ConfigKey $entry -ConfigValue $InputValue; + } + + if ($index -eq 1) { + $ConfigObject.$entry = $Value; + break; + } + + $ConfigObject = $ConfigObject.$entry; + $index -= 1; + } + + Write-IcingaPowerShellConfig $Config; +} diff --git a/lib/config/Test-IcingaPowerShellConfigItem.psm1 b/lib/config/Test-IcingaPowerShellConfigItem.psm1 new file mode 100644 index 0000000..95c3fe4 --- /dev/null +++ b/lib/config/Test-IcingaPowerShellConfigItem.psm1 @@ -0,0 +1,9 @@ +function Test-IcingaPowerShellConfigItem() +{ + param( + $ConfigObject, + $ConfigKey + ); + + return ([bool]($ConfigObject.PSobject.Properties.Name -eq $ConfigKey) -eq $TRUE); +} diff --git a/lib/config/Write-IcingaPowerShellConfig.psm1 b/lib/config/Write-IcingaPowerShellConfig.psm1 new file mode 100644 index 0000000..3dfbdda --- /dev/null +++ b/lib/config/Write-IcingaPowerShellConfig.psm1 @@ -0,0 +1,23 @@ +function Write-IcingaPowerShellConfig() +{ + param( + $Config + ); + + $ConfigDir = Get-IcingaPowerShellConfigDir; + $ConfigFile = Join-Path -Path $ConfigDir -ChildPath 'config.json'; + + if (-Not (Test-Path $ConfigDir)) { + New-Item -Path $ConfigDir -ItemType Directory | Out-Null; + } + + $Content = ConvertTo-Json -InputObject $Config -Depth 100; + + Set-Content -Path $ConfigFile -Value $Content; + + if ($global:IcingaDaemonData.FrameworkRunningAsDaemon) { + if ($global:IcingaDaemonData.ContainsKey('Config')) { + $global:IcingaDaemonData.Config = $Config; + } + } +} From c0d7b4e7611fa75e2f5383279bfe5320de48e048 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 5 Oct 2019 21:59:03 +0200 Subject: [PATCH 133/259] Added support and management of threads --- lib/core/thread/New-IcingaThreadHash.psm1 | 14 +++++++ lib/core/thread/New-IcingaThreadInstance.psm1 | 40 +++++++++++++++++++ lib/core/thread/New-IcingaThreadPool.psm1 | 18 +++++++++ lib/core/thread/Remove-IcingaThread.psm1 | 17 ++++++++ lib/core/thread/Restart-IcingaThread.psm1 | 13 ++++++ lib/core/thread/Start-IcingaThread.psm1 | 17 ++++++++ lib/core/thread/Stop-IcingaThread.psm1 | 18 +++++++++ lib/core/thread/Test-IcingaThread.psm1 | 12 ++++++ 8 files changed, 149 insertions(+) create mode 100644 lib/core/thread/New-IcingaThreadHash.psm1 create mode 100644 lib/core/thread/New-IcingaThreadInstance.psm1 create mode 100644 lib/core/thread/New-IcingaThreadPool.psm1 create mode 100644 lib/core/thread/Remove-IcingaThread.psm1 create mode 100644 lib/core/thread/Restart-IcingaThread.psm1 create mode 100644 lib/core/thread/Start-IcingaThread.psm1 create mode 100644 lib/core/thread/Stop-IcingaThread.psm1 create mode 100644 lib/core/thread/Test-IcingaThread.psm1 diff --git a/lib/core/thread/New-IcingaThreadHash.psm1 b/lib/core/thread/New-IcingaThreadHash.psm1 new file mode 100644 index 0000000..56e765d --- /dev/null +++ b/lib/core/thread/New-IcingaThreadHash.psm1 @@ -0,0 +1,14 @@ +function New-IcingaThreadHash() +{ + param( + [ScriptBlock]$ShellScript, + [array]$Arguments + ); + + [string]$ScriptString = ''; + [string]$ArgString = ($Arguments | Out-String); + if ($null -ne $ShellScript) { + $ScriptString = $ShellScript.ToString(); + } + return (Get-StringSha1 -Content ($ScriptString + $ArgString + (Get-Date -Format "MM-dd-yyyy-HH-mm-ffff"))); +} diff --git a/lib/core/thread/New-IcingaThreadInstance.psm1 b/lib/core/thread/New-IcingaThreadInstance.psm1 new file mode 100644 index 0000000..6a2fa25 --- /dev/null +++ b/lib/core/thread/New-IcingaThreadInstance.psm1 @@ -0,0 +1,40 @@ +function New-IcingaThreadInstance() +{ + param( + [string]$Name, + $ThreadPool, + [ScriptBlock]$ScriptBlock, + [array]$Arguments, + [Switch]$Start + ); + + if ([string]::IsNullOrEmpty($Name)) { + $Name = New-IcingaThreadHash -ShellScript $ScriptBlock -Arguments $Arguments; + } + + $Shell = [PowerShell]::Create(); + $Shell.RunspacePool = $ThreadPool; + [void]$Shell.AddScript($ScriptBlock); + foreach ($argument in $Arguments) { + [void]$Shell.AddArgument($argument); + } + + $Thread = New-Object PSObject; + Add-Member -InputObject $Thread -MemberType NoteProperty -Name Shell -Value $Shell; + if ($Start) { + Add-Member -InputObject $Thread -MemberType NoteProperty -Name Handle -Value ($Shell.BeginInvoke()); + Add-Member -InputObject $Thread -MemberType NoteProperty -Name Started -Value $TRUE; + } else { + Add-Member -InputObject $Thread -MemberType NoteProperty -Name Handle -Value $null; + Add-Member -InputObject $Thread -MemberType NoteProperty -Name Started -Value $FALSE; + } + + if ($global:IcingaDaemonData.IcingaThreads.ContainsKey($Name) -eq $FALSE) { + $global:IcingaDaemonData.IcingaThreads.Add($Name, $Thread); + } else { + $global:IcingaDaemonData.IcingaThreads.Add( + (New-IcingaThreadHash -ShellScript $ScriptBlock -Arguments $Arguments), + $Thread + ); + } +} diff --git a/lib/core/thread/New-IcingaThreadPool.psm1 b/lib/core/thread/New-IcingaThreadPool.psm1 new file mode 100644 index 0000000..f0a8a2b --- /dev/null +++ b/lib/core/thread/New-IcingaThreadPool.psm1 @@ -0,0 +1,18 @@ +function New-IcingaThreadPool() +{ + param( + [int]$MinInstances = 1, + [int]$MaxInstances = 5 + ); + + $Runspaces = [RunspaceFactory]::CreateRunspacePool( + $MinInstances, + $MaxInstances, + [System.Management.Automation.Runspaces.InitialSessionState]::CreateDefault(), + $host + ) + + $Runspaces.Open(); + + return $Runspaces; +} diff --git a/lib/core/thread/Remove-IcingaThread.psm1 b/lib/core/thread/Remove-IcingaThread.psm1 new file mode 100644 index 0000000..60f48c5 --- /dev/null +++ b/lib/core/thread/Remove-IcingaThread.psm1 @@ -0,0 +1,17 @@ +function Remove-IcingaThread() +{ + param( + [string]$Thread + ); + + if ([string]::IsNullOrEmpty($Thread)) { + return; + } + + Stop-IcingaThread -Thread $Thread; + + if ($global:IcingaDaemonData.IcingaThreads.ContainsKey($Thread)) { + $global:IcingaDaemonData.IcingaThreads[$Thread].Shell.Dispose(); + $global:IcingaDaemonData.IcingaThreads.Remove($Thread); + } +} diff --git a/lib/core/thread/Restart-IcingaThread.psm1 b/lib/core/thread/Restart-IcingaThread.psm1 new file mode 100644 index 0000000..885de77 --- /dev/null +++ b/lib/core/thread/Restart-IcingaThread.psm1 @@ -0,0 +1,13 @@ +function Restart-IcingaThread() +{ + param( + [string]$Thread + ); + + if ([string]::IsNullOrEmpty($Thread)) { + return; + } + + Stop-IcingaThread $Thread; + Start-IcingaThread $Thread; +} diff --git a/lib/core/thread/Start-IcingaThread.psm1 b/lib/core/thread/Start-IcingaThread.psm1 new file mode 100644 index 0000000..09eb6ba --- /dev/null +++ b/lib/core/thread/Start-IcingaThread.psm1 @@ -0,0 +1,17 @@ +function Start-IcingaThread() +{ + param( + [string]$Thread + ); + + if ([string]::IsNullOrEmpty($Thread)) { + return; + } + + if ($global:IcingaDaemonData.IcingaThreads.ContainsKey($Thread)) { + if ($global:IcingaDaemonData.IcingaThreads[$Thread].Started -eq $FALSE) { + $global:IcingaDaemonData.IcingaThreads[$Thread].Handle = $global:IcingaDaemonData.IcingaThreads[$Thread].Shell.BeginInvoke(); + $global:IcingaDaemonData.IcingaThreads[$Thread].Started = $TRUE; + } + } +} diff --git a/lib/core/thread/Stop-IcingaThread.psm1 b/lib/core/thread/Stop-IcingaThread.psm1 new file mode 100644 index 0000000..e78f4a0 --- /dev/null +++ b/lib/core/thread/Stop-IcingaThread.psm1 @@ -0,0 +1,18 @@ +function Stop-IcingaThread() +{ + param( + [string]$Thread + ); + + if ([string]::IsNullOrEmpty($Thread)) { + return; + } + + if ($global:IcingaDaemonData.IcingaThreads.ContainsKey($Thread)) { + if ($global:IcingaDaemonData.IcingaThreads[$Thread].Started -eq $TRUE) { + $global:IcingaDaemonData.IcingaThreads[$Thread].Shell.Stop(); + $global:IcingaDaemonData.IcingaThreads[$Thread].Handle = $null; + $global:IcingaDaemonData.IcingaThreads[$Thread].Started = $FALSE; + } + } +} diff --git a/lib/core/thread/Test-IcingaThread.psm1 b/lib/core/thread/Test-IcingaThread.psm1 new file mode 100644 index 0000000..1ff7d23 --- /dev/null +++ b/lib/core/thread/Test-IcingaThread.psm1 @@ -0,0 +1,12 @@ +function Test-IcingaThread() +{ + param( + [string]$Thread + ); + + if ([string]::IsNullOrEmpty($Thread)) { + return $FALSE; + } + + return $global:IcingaDaemonData.IcingaThreads.ContainsKey($Thread); +} From 3924c0a5910acde69a4cdf865e8aeae6e9adf858 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 5 Oct 2019 21:59:37 +0200 Subject: [PATCH 134/259] Fixed CheckCommand callback to fetch executed command --- lib/icinga/plugin/New-IcingaCheckResult.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/icinga/plugin/New-IcingaCheckResult.psm1 b/lib/icinga/plugin/New-IcingaCheckResult.psm1 index 9db2518..5e2a9f6 100644 --- a/lib/icinga/plugin/New-IcingaCheckResult.psm1 +++ b/lib/icinga/plugin/New-IcingaCheckResult.psm1 @@ -17,7 +17,7 @@ function New-IcingaCheckresult() return $IcingaEnums.IcingaExitCode.Unknown; } - $CheckCommand = (Get-PSCallStack)[1].Command; + $CheckCommand = (Get-PSCallStack)[2].Command; # Compile the check / package if not already done $this.check.AssignCheckCommand($CheckCommand); From 7d6b9016e4574f5a17c9bd0045dfc78ca14e1258 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 5 Oct 2019 22:01:15 +0200 Subject: [PATCH 135/259] Added support for check output stored differently on daemon execution --- lib/icinga/exception/Exit-IcingaThrowException.psm1 | 6 ++++-- lib/icinga/plugin/Write-IcingaPluginOutput.psm1 | 4 ++++ lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 | 8 ++++++++ 3 files changed, 16 insertions(+), 2 deletions(-) diff --git a/lib/icinga/exception/Exit-IcingaThrowException.psm1 b/lib/icinga/exception/Exit-IcingaThrowException.psm1 index 2e2ae8f..b7a1304 100644 --- a/lib/icinga/exception/Exit-IcingaThrowException.psm1 +++ b/lib/icinga/exception/Exit-IcingaThrowException.psm1 @@ -70,6 +70,8 @@ function Exit-IcingaThrowException() $ExceptionTypeString ); - Write-Host $OutputMessage; - exit $IcingaEnums.IcingaExitCode.Unknown; + if ($global:IcingaDaemonData.FrameworkRunningAsDaemon -eq $FALSE) { + Write-Host $OutputMessage; + exit $IcingaEnums.IcingaExitCode.Unknown; + } } diff --git a/lib/icinga/plugin/Write-IcingaPluginOutput.psm1 b/lib/icinga/plugin/Write-IcingaPluginOutput.psm1 index e698671..78b396c 100644 --- a/lib/icinga/plugin/Write-IcingaPluginOutput.psm1 +++ b/lib/icinga/plugin/Write-IcingaPluginOutput.psm1 @@ -4,5 +4,9 @@ function Write-IcingaPluginOutput() $Output ); + if ($global:IcingaDaemonData.FrameworkRunningAsDaemon -eq $FALSE) { Write-Host $Output; + } else { + $IcingaThreadContent['Scheduler']['PluginCache'] += $Output; + } } diff --git a/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 b/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 index 4cc86cf..bdc474e 100644 --- a/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 +++ b/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 @@ -6,8 +6,13 @@ function Write-IcingaPluginPerfData() ); $CheckResultCache = Get-IcingaCacheData -Space 'sc_daemon' -CacheStore 'checkresult' -KeyName $CheckCommand; + + if ($global:IcingaDaemonData.FrameworkRunningAsDaemon -eq $FALSE) { [string]$PerfDataOutput = (Get-IcingaPluginPerfDataContent -PerfData $PerformanceData -CheckResultCache $CheckResultCache); Write-Host ([string]::Format('| {0}', $PerfDataOutput)); + } else { + [void](Get-IcingaPluginPerfDataContent -PerfData $PerformanceData -CheckResultCache $CheckResultCache -AsObject $TRUE); + } } function Get-IcingaPluginPerfDataContent() @@ -40,6 +45,9 @@ function Get-IcingaPluginPerfDataContent() $compiledPerfData = (New-IcingaPerformanceDataEntry $data); + if ($AsObject) { + $global:IcingaThreadContent['Scheduler']['PluginPerfData'] += $compiledPerfData; + } $PerfDataOutput += $compiledPerfData; } } From a59ae37b760b6fc6d71e48e048c678b23a210660 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 5 Oct 2019 22:02:17 +0200 Subject: [PATCH 136/259] Added support to register checks to run in background --- .../Get-IcingaRegisteredServiceChecks.psm1 | 19 +++++++++++++++ lib/daemon/Register-IcingaServiceCheck.psm1 | 23 +++++++++++++++++++ .../Show-IcingaRegisteredServiceChecks.psm1 | 11 +++++++++ 3 files changed, 53 insertions(+) create mode 100644 lib/daemon/Get-IcingaRegisteredServiceChecks.psm1 create mode 100644 lib/daemon/Register-IcingaServiceCheck.psm1 create mode 100644 lib/daemon/Show-IcingaRegisteredServiceChecks.psm1 diff --git a/lib/daemon/Get-IcingaRegisteredServiceChecks.psm1 b/lib/daemon/Get-IcingaRegisteredServiceChecks.psm1 new file mode 100644 index 0000000..c023153 --- /dev/null +++ b/lib/daemon/Get-IcingaRegisteredServiceChecks.psm1 @@ -0,0 +1,19 @@ +function Get-IcingaRegisteredServiceChecks() +{ + $Services = Get-IcingaPowerShellConfig -Path 'BackgroundDaemon.RegisteredServices'; + [hashtable]$Output = @{}; + + foreach ($service in $Services.PSObject.Properties) { + $Content = @{ + 'Id' = $service.Name; + 'CheckCommand' = $service.Value.CheckCommand; + 'Arguments' = $service.Value.Arguments; + 'Interval' = $service.Value.Interval; + 'TimeIndexes' = $service.Value.TimeIndexes; + }; + + $Output.Add($service.Name, $Content); + } + + return $Output; +} diff --git a/lib/daemon/Register-IcingaServiceCheck.psm1 b/lib/daemon/Register-IcingaServiceCheck.psm1 new file mode 100644 index 0000000..2492950 --- /dev/null +++ b/lib/daemon/Register-IcingaServiceCheck.psm1 @@ -0,0 +1,23 @@ +function Register-IcingaServiceCheck() +{ + param( + [string]$CheckCommand, + [hashtable]$Arguments, + [int]$Interval = 60, + [array]$TimeIndexes = @() + ); + + if ([string]::IsNullOrEmpty($CheckCommand)) { + throw 'Please specify a CheckCommand'; + } + + $Hash = Get-StringSha1 ([string]::Format('{0} {1}', $CheckCommand, ($Arguments | Out-String))); + $Path = [string]::Format('BackgroundDaemon.RegisteredServices.{0}', $Hash); + + Set-IcingaPowerShellConfig -Path ([string]::Format('{0}.CheckCommand', $Path)) -Value $CheckCommand; + Set-IcingaPowerShellConfig -Path ([string]::Format('{0}.Arguments', $Path)) -Value $Arguments; + Set-IcingaPowerShellConfig -Path ([string]::Format('{0}.Interval', $Path)) -Value $Interval; + Set-IcingaPowerShellConfig -Path ([string]::Format('{0}.TimeIndexes', $Path)) -Value $TimeIndexes; + + Write-Host 'Icinga Service Check has been configured'; +} diff --git a/lib/daemon/Show-IcingaRegisteredServiceChecks.psm1 b/lib/daemon/Show-IcingaRegisteredServiceChecks.psm1 new file mode 100644 index 0000000..69af178 --- /dev/null +++ b/lib/daemon/Show-IcingaRegisteredServiceChecks.psm1 @@ -0,0 +1,11 @@ +function Show-IcingaRegisteredServiceChecks() +{ + $Services = Get-IcingaRegisteredServiceChecks; + + foreach ($service in $Services.Keys) { + Write-Host ([string]::Format('Service Id: {0}', $service)); + Write-Host ( + $Services[$service] | Out-String + ); + } +} From 3b6b30a993e21db423250fe404548d9ded5afdc9 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 5 Oct 2019 22:06:10 +0200 Subject: [PATCH 137/259] Added support to remove registered service checks --- lib/daemon/Unregister-IcingaServiceCheck.psm1 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 lib/daemon/Unregister-IcingaServiceCheck.psm1 diff --git a/lib/daemon/Unregister-IcingaServiceCheck.psm1 b/lib/daemon/Unregister-IcingaServiceCheck.psm1 new file mode 100644 index 0000000..9285a11 --- /dev/null +++ b/lib/daemon/Unregister-IcingaServiceCheck.psm1 @@ -0,0 +1,16 @@ +function Unregister-IcingaServiceCheck() +{ + param( + [string]$ServiceId + ); + + if ([string]::IsNullOrEmpty($ServiceId)) { + throw 'Please specify a Service Id'; + } + + $Path = [string]::Format('BackgroundDaemon.RegisteredServices.{0}', $ServiceId); + + Remove-IcingaPowerShellConfig -Path $Path; + + Write-Host 'Icinga Service Check has been configured'; +} From d713555eaa6136b2d8bdd704b0e5ccd3a165b503 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 5 Oct 2019 22:07:02 +0200 Subject: [PATCH 138/259] Added support for background daemon and check execution --- lib/daemon/Start-IcingaPowerShellDaemon.psm1 | 27 +++++ .../Start-IcingaServiceCheckDaemon.psm1 | 107 ++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 lib/daemon/Start-IcingaPowerShellDaemon.psm1 create mode 100644 lib/daemons/Start-IcingaServiceCheckDaemon.psm1 diff --git a/lib/daemon/Start-IcingaPowerShellDaemon.psm1 b/lib/daemon/Start-IcingaPowerShellDaemon.psm1 new file mode 100644 index 0000000..fa8951d --- /dev/null +++ b/lib/daemon/Start-IcingaPowerShellDaemon.psm1 @@ -0,0 +1,27 @@ +function Start-IcingaPowerShellDaemon() +{ + $ScriptBlock = { + param($IcingaDaemonData); + + Use-Icinga -LibOnly -Daemon; + + try { + # Todo: Add dynamic loading of enabled background tasks + Start-IcingaServiceCheckDaemon; + } catch { + # Todo: Add exception handling + } + + while ($TRUE) { + Start-Sleep -Seconds 1; + } + }; + + $global:IcingaDaemonData.FrameworkRunningAsDaemon = $TRUE; + $global:IcingaDaemonData.Add('BackgroundDaemon', [hashtable]::Synchronized(@{})); + # Todo: Add config for active background tasks. Set it to 20 for the moment + $global:IcingaDaemonData.IcingaThreadPool.Add('BackgroundPool', (New-IcingaThreadPool -MaxInstances 20)); + $global:IcingaDaemonData.Add('Config', (Read-IcingaPowerShellConfig)); + + New-IcingaThreadInstance -Name "Icinga_PowerShell_Background_Daemon" -ThreadPool $IcingaDaemonData.IcingaThreadPool.BackgroundPool -ScriptBlock $ScriptBlock -Arguments @( $global:IcingaDaemonData ) -Start; +} diff --git a/lib/daemons/Start-IcingaServiceCheckDaemon.psm1 b/lib/daemons/Start-IcingaServiceCheckDaemon.psm1 new file mode 100644 index 0000000..5873cf8 --- /dev/null +++ b/lib/daemons/Start-IcingaServiceCheckDaemon.psm1 @@ -0,0 +1,107 @@ +function Start-IcingaServiceCheckDaemon() +{ + $ScriptBlock = { + param($IcingaDaemonData); + + Use-Icinga -LibOnly -Daemon; + + $IcingaDaemonData.BackgroundDaemon.Add('ServiceCheckScheduler', [hashtable]::Synchronized(@{})); + $IcingaDaemonData.IcingaThreadPool.Add('ServiceCheckPool', (New-IcingaThreadPool -MaxInstances (Get-IcingaConfigTreeCount -Path 'BackgroundDaemon.RegisteredServices'))); + + while ($TRUE) { + + $RegisteredServices = Get-IcingaRegisteredServiceChecks; + + foreach ($service in $RegisteredServices.Keys) { + [string]$ThreadName = [string]::Format('Icinga_Background_Service_Check_{0}', $service); + if ((Test-IcingaThread $ThreadName)) { + continue; + } + + Start-IcingaServiceCheckTask -CheckId $service -CheckCommand $RegisteredServices[$service].CheckCommand -Arguments $RegisteredServices[$service].Arguments -Interval $RegisteredServices[$service].Interval -TimeIndexes $RegisteredServices[$service].TimeIndexes; + } + Start-Sleep -Seconds 1; + } + }; + + New-IcingaThreadInstance -Name "Icinga_PowerShell_ServiceCheck_Scheduler" -ThreadPool $IcingaDaemonData.IcingaThreadPool.BackgroundPool -ScriptBlock $ScriptBlock -Arguments @( $global:IcingaDaemonData ) -Start; +} + +function Start-IcingaServiceCheckTask() +{ + param( + $CheckId, + $CheckCommand, + $Arguments, + $Interval, + $TimeIndexes + ); + + [string]$ThreadName = [string]::Format('Icinga_Background_Service_Check_{0}', $CheckId); + + $ScriptBlock = { + param($IcingaDaemonData, $CheckCommand, $Arguments, $Interval, $TimeIndexes, $CheckId); + + Use-Icinga -LibOnly -Daemon; + $PassedTime = 0; + + if (-Not ($IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler.ContainsKey($CheckCommand))) { + $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler.Add($CheckCommand, [hashtable]::Synchronized(@{})); + $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand].Add('results', [hashtable]::Synchronized(@{})); + $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand].Add('average', [hashtable]::Synchronized(@{})); + } + + while ($TRUE) { + if ($PassedTime -ge $Interval) { + & $CheckCommand @Arguments; + + $Results = $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand]['results']; + $UnixTime = Get-IcingaUnixTime; + $OldData = @{}; + + foreach ($result in $Results.Keys) { + $SortedResult = $Results[$result].GetEnumerator() | Sort-Object name -Descending; + Add-IcingaHashtableItem -Hashtable $OldData -Key $result -Value @{}; + + foreach ($index in $TimeIndexes) { + $ObjectCount = 0; + $ObjectValue = 0; + $TimeInSeconds = $index * 60; + + foreach ($timeEntry in $SortedResult) { + if (($UnixTime - $TimeInSeconds) -le [int]$timeEntry.Key) { + $ObjectCount += 1; + $ObjectValue += $timeEntry.Value; + Remove-IcingaHashtableItem -Hashtable $OldData[$result] -Key $timeEntry; + } else { + Add-IcingaHashtableItem -Hashtable $OldData[$result] -Key $timeEntry -Value $TRUE; + } + } + + $AvarageValue = ($ObjectValue / $ObjectCount); + $MetricName = [string]::Format('{0}_{1}', $result, $index); + + Add-IcingaHashtableItem ` + -Hashtable $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand]['average'] ` + -Key (Format-IcingaPerfDataLabel $MetricName) -Value $AvarageValue -Override; + } + } + + # Flush data we no longer require in our cache to free memory + foreach ($entry in $OldData.Keys) { + foreach ($key in $OldData[$entry].Keys) { + Remove-IcingaHashtableItem -Hashtable $Results[$entry] -Key $key + } + } + + Set-IcingaCacheData -Space 'sc_daemon' -CacheStore 'checkresult' -KeyName $CheckCommand -Value $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand]['average']; + + $PassedTime = 0; + } + $PassedTime += 1; + Start-Sleep -Seconds 1; + } + }; + + New-IcingaThreadInstance -Name $ThreadName -ThreadPool $IcingaDaemonData.IcingaThreadPool.ServiceCheckPool -ScriptBlock $ScriptBlock -Arguments @( $global:IcingaDaemonData, $CheckCommand, $Arguments, $Interval, $TimeIndexes, $CheckId ) -Start; +} From becc24a1b3201b052bd9ae190b1e50fea2046af1 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 5 Oct 2019 22:08:19 +0200 Subject: [PATCH 139/259] Executed checks will now store their value on daemon run within cache --- lib/icinga/plugin/New-IcingaCheck.psm1 | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/lib/icinga/plugin/New-IcingaCheck.psm1 b/lib/icinga/plugin/New-IcingaCheck.psm1 index d949508..6134729 100644 --- a/lib/icinga/plugin/New-IcingaCheck.psm1 +++ b/lib/icinga/plugin/New-IcingaCheck.psm1 @@ -38,6 +38,27 @@ function New-IcingaCheck() $Check | Add-Member -membertype NoteProperty -name 'completed' -value $FALSE; $Check | Add-Member -membertype NoteProperty -name 'checkcommand' -value ''; + $Check | Add-Member -membertype ScriptMethod -name 'HandleDaemon' -value { + # Only apply this once the checkcommand is set + + if ([string]::IsNullOrEmpty($this.checkcommand) -Or $global:IcingaDaemonData.FrameworkRunningAsDaemon -eq $FALSE) { + return; + } + + if ($global:IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler.ContainsKey($this.checkcommand)) { + if ($global:IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$this.checkcommand]['results'].ContainsKey($this.name) -eq $FALSE) { + $global:IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$this.checkcommand]['results'].Add( + $this.name, + [hashtable]::Synchronized(@{}) + ); + } + $global:IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$this.checkcommand]['results'][$this.name].Add( + (Get-IcingaUnixTime), + $this.value + ); + } + } + $Check | Add-Member -membertype ScriptMethod -name 'AddSpacing' -value { $this.spacing += 1; } @@ -46,6 +67,7 @@ function New-IcingaCheck() param($CheckCommand); $this.checkcommand = $CheckCommand; + $this.HandleDaemon(); } $Check | Add-Member -membertype ScriptMethod -name 'WarnOutOfRange' -value { @@ -683,6 +705,7 @@ function New-IcingaCheck() } $Check.ValidateUnit(); + $Check.HandleDaemon(); return $Check; } From 326165e8d8775a5d0fcbb436274553c22c2b5e48 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 5 Oct 2019 22:32:44 +0200 Subject: [PATCH 140/259] Fixed flushing of not required cached entries --- lib/daemons/Start-IcingaServiceCheckDaemon.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/daemons/Start-IcingaServiceCheckDaemon.psm1 b/lib/daemons/Start-IcingaServiceCheckDaemon.psm1 index 5873cf8..edfd838 100644 --- a/lib/daemons/Start-IcingaServiceCheckDaemon.psm1 +++ b/lib/daemons/Start-IcingaServiceCheckDaemon.psm1 @@ -90,7 +90,7 @@ function Start-IcingaServiceCheckTask() # Flush data we no longer require in our cache to free memory foreach ($entry in $OldData.Keys) { foreach ($key in $OldData[$entry].Keys) { - Remove-IcingaHashtableItem -Hashtable $Results[$entry] -Key $key + Remove-IcingaHashtableItem -Hashtable $Results[$entry] -Key $key.Name } } From ee138f0ea403517f11a3f2c93d21b5ac62db9b2d Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 6 Oct 2019 10:46:11 +0200 Subject: [PATCH 141/259] Fixed crash on check execution while running in daemon mode --- lib/icinga/plugin/New-IcingaCheck.psm1 | 9 ++++++++- lib/icinga/plugin/Write-IcingaPluginOutput.psm1 | 4 +++- lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 | 8 ++++++-- 3 files changed, 17 insertions(+), 4 deletions(-) diff --git a/lib/icinga/plugin/New-IcingaCheck.psm1 b/lib/icinga/plugin/New-IcingaCheck.psm1 index 6134729..2524d77 100644 --- a/lib/icinga/plugin/New-IcingaCheck.psm1 +++ b/lib/icinga/plugin/New-IcingaCheck.psm1 @@ -40,11 +40,18 @@ function New-IcingaCheck() $Check | Add-Member -membertype ScriptMethod -name 'HandleDaemon' -value { # Only apply this once the checkcommand is set - if ([string]::IsNullOrEmpty($this.checkcommand) -Or $global:IcingaDaemonData.FrameworkRunningAsDaemon -eq $FALSE) { return; } + if ($global:IcingaDaemonData.ContainsKey('BackgroundDaemon') -eq $FALSE) { + return; + } + + if ($global:IcingaDaemonData.BackgroundDaemon.ContainsKey('ServiceCheckScheduler') -eq $FALSE) { + return; + } + if ($global:IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler.ContainsKey($this.checkcommand)) { if ($global:IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$this.checkcommand]['results'].ContainsKey($this.name) -eq $FALSE) { $global:IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$this.checkcommand]['results'].Add( diff --git a/lib/icinga/plugin/Write-IcingaPluginOutput.psm1 b/lib/icinga/plugin/Write-IcingaPluginOutput.psm1 index 78b396c..c9a8746 100644 --- a/lib/icinga/plugin/Write-IcingaPluginOutput.psm1 +++ b/lib/icinga/plugin/Write-IcingaPluginOutput.psm1 @@ -7,6 +7,8 @@ function Write-IcingaPluginOutput() if ($global:IcingaDaemonData.FrameworkRunningAsDaemon -eq $FALSE) { Write-Host $Output; } else { - $IcingaThreadContent['Scheduler']['PluginCache'] += $Output; + if ($global:IcingaDaemonData.IcingaThreadContent.ContainsKey('Scheduler')) { + $global:IcingaDaemonData.IcingaThreadContent['Scheduler']['PluginCache'] += $Output; + } } } diff --git a/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 b/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 index bdc474e..dc1221c 100644 --- a/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 +++ b/lib/icinga/plugin/Write-IcingaPluginPerfData.psm1 @@ -37,7 +37,9 @@ function Get-IcingaPluginPerfDataContent() $cachedresult = (New-IcingaPerformanceDataEntry -PerfDataObject $data -Label $SearchEntry -Value $checkresult.Value); if ($AsObject) { - $global:IcingaThreadContent['Scheduler']['PluginPerfData'] += $cachedresult; + if ($global:IcingaDaemonData.IcingaThreadContent.ContainsKey('Scheduler')) { + $global:IcingaDaemonData.IcingaThreadContent['Scheduler']['PluginPerfData'] += $cachedresult; + } } $PerfDataOutput += $cachedresult; } @@ -46,7 +48,9 @@ function Get-IcingaPluginPerfDataContent() $compiledPerfData = (New-IcingaPerformanceDataEntry $data); if ($AsObject) { - $global:IcingaThreadContent['Scheduler']['PluginPerfData'] += $compiledPerfData; + if ($global:IcingaDaemonData.IcingaThreadContent.ContainsKey('Scheduler')) { + $global:IcingaDaemonData.IcingaThreadContent['Scheduler']['PluginPerfData'] += $compiledPerfData; + } } $PerfDataOutput += $compiledPerfData; } From 0171e9a0e9ee431c5ace203939c1a8d9501902f9 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 6 Oct 2019 10:48:12 +0200 Subject: [PATCH 142/259] Improved stability for service check execution daemon --- .../Start-IcingaServiceCheckDaemon.psm1 | 78 ++++++++++--------- 1 file changed, 42 insertions(+), 36 deletions(-) diff --git a/lib/daemons/Start-IcingaServiceCheckDaemon.psm1 b/lib/daemons/Start-IcingaServiceCheckDaemon.psm1 index edfd838..e9b6bba 100644 --- a/lib/daemons/Start-IcingaServiceCheckDaemon.psm1 +++ b/lib/daemons/Start-IcingaServiceCheckDaemon.psm1 @@ -43,7 +43,9 @@ function Start-IcingaServiceCheckTask() param($IcingaDaemonData, $CheckCommand, $Arguments, $Interval, $TimeIndexes, $CheckId); Use-Icinga -LibOnly -Daemon; - $PassedTime = 0; + $PassedTime = 0; + $SortedResult = $null; + $OldData = @{}; if (-Not ($IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler.ContainsKey($CheckCommand))) { $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler.Add($CheckCommand, [hashtable]::Synchronized(@{})); @@ -53,50 +55,54 @@ function Start-IcingaServiceCheckTask() while ($TRUE) { if ($PassedTime -ge $Interval) { - & $CheckCommand @Arguments; + try { + & $CheckCommand @Arguments | Out-Null; - $Results = $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand]['results']; - $UnixTime = Get-IcingaUnixTime; - $OldData = @{}; + $UnixTime = Get-IcingaUnixTime; - foreach ($result in $Results.Keys) { - $SortedResult = $Results[$result].GetEnumerator() | Sort-Object name -Descending; - Add-IcingaHashtableItem -Hashtable $OldData -Key $result -Value @{}; + foreach ($result in $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand]['results'].Keys) { + $SortedResult = $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand]['results'][$result].GetEnumerator() | Sort-Object name -Descending; + Add-IcingaHashtableItem -Hashtable $OldData -Key $result -Value @{}; - foreach ($index in $TimeIndexes) { - $ObjectCount = 0; - $ObjectValue = 0; - $TimeInSeconds = $index * 60; + foreach ($index in $TimeIndexes) { + $ObjectCount = 0; + $ObjectValue = 0; + $TimeInSeconds = $index * 60; - foreach ($timeEntry in $SortedResult) { - if (($UnixTime - $TimeInSeconds) -le [int]$timeEntry.Key) { - $ObjectCount += 1; - $ObjectValue += $timeEntry.Value; - Remove-IcingaHashtableItem -Hashtable $OldData[$result] -Key $timeEntry; - } else { - Add-IcingaHashtableItem -Hashtable $OldData[$result] -Key $timeEntry -Value $TRUE; + foreach ($timeEntry in $SortedResult) { + if (($UnixTime - $TimeInSeconds) -le [int]$timeEntry.Key) { + $ObjectCount += 1; + $ObjectValue += $timeEntry.Value; + Remove-IcingaHashtableItem -Hashtable $OldData[$result] -Key $timeEntry; + } else { + Add-IcingaHashtableItem -Hashtable $OldData[$result] -Key $timeEntry -Value $null; + } } + + $AvarageValue = ($ObjectValue / $ObjectCount); + $MetricName = [string]::Format('{0}_{1}', $result, $index); + + Add-IcingaHashtableItem ` + -Hashtable $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand]['average'] ` + -Key (Format-IcingaPerfDataLabel $MetricName) -Value $AvarageValue -Override; } - - $AvarageValue = ($ObjectValue / $ObjectCount); - $MetricName = [string]::Format('{0}_{1}', $result, $index); - - Add-IcingaHashtableItem ` - -Hashtable $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand]['average'] ` - -Key (Format-IcingaPerfDataLabel $MetricName) -Value $AvarageValue -Override; } + + # Flush data we no longer require in our cache to free memory + foreach ($entry in $OldData.Keys) { + foreach ($key in $OldData[$entry].Keys) { + Remove-IcingaHashtableItem -Hashtable $$IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand]['results'][$entry] -Key $key.Name + } + } + + Set-IcingaCacheData -Space 'sc_daemon' -CacheStore 'checkresult' -KeyName $CheckCommand -Value $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand]['average']; + } catch { + # Todo: Add error reporting / handling } - # Flush data we no longer require in our cache to free memory - foreach ($entry in $OldData.Keys) { - foreach ($key in $OldData[$entry].Keys) { - Remove-IcingaHashtableItem -Hashtable $Results[$entry] -Key $key.Name - } - } - - Set-IcingaCacheData -Space 'sc_daemon' -CacheStore 'checkresult' -KeyName $CheckCommand -Value $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand]['average']; - - $PassedTime = 0; + $PassedTime = 0; + $SortedResult = $null; + $OldData = @{}; } $PassedTime += 1; Start-Sleep -Seconds 1; From a363399608837c01ebb2dc858df00e8ec8fc1ffa Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 6 Oct 2019 16:07:12 +0200 Subject: [PATCH 143/259] Fixed error on removing hashtable cache content --- lib/daemons/Start-IcingaServiceCheckDaemon.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/daemons/Start-IcingaServiceCheckDaemon.psm1 b/lib/daemons/Start-IcingaServiceCheckDaemon.psm1 index e9b6bba..bff4d41 100644 --- a/lib/daemons/Start-IcingaServiceCheckDaemon.psm1 +++ b/lib/daemons/Start-IcingaServiceCheckDaemon.psm1 @@ -91,7 +91,7 @@ function Start-IcingaServiceCheckTask() # Flush data we no longer require in our cache to free memory foreach ($entry in $OldData.Keys) { foreach ($key in $OldData[$entry].Keys) { - Remove-IcingaHashtableItem -Hashtable $$IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand]['results'][$entry] -Key $key.Name + Remove-IcingaHashtableItem -Hashtable $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand]['results'][$entry] -Key $key.Name } } From 1550d2b4aeacbeaafa99652cc7b32caf09df7a57 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 6 Oct 2019 16:56:24 +0200 Subject: [PATCH 144/259] Added help funtion to test for PSObjects members --- lib/core/tools/Test-PSCustomObjectMember.psm1 | 13 +++++++++++++ 1 file changed, 13 insertions(+) create mode 100644 lib/core/tools/Test-PSCustomObjectMember.psm1 diff --git a/lib/core/tools/Test-PSCustomObjectMember.psm1 b/lib/core/tools/Test-PSCustomObjectMember.psm1 new file mode 100644 index 0000000..1edeace --- /dev/null +++ b/lib/core/tools/Test-PSCustomObjectMember.psm1 @@ -0,0 +1,13 @@ +function Test-PSCustomObjectMember() +{ + param( + $PSObject, + $Name + ); + + if ($null -eq $PSObject) { + return $FALSE; + } + + return ([bool]($PSObject.PSobject.Properties.Name -eq $Name)); +} From cbd45344770ad0df4374f4e133ceaea1b9d3a5a4 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 6 Oct 2019 16:56:59 +0200 Subject: [PATCH 145/259] Added Cmdlets to talk to Icinga Director Self-Service API --- .../Get-IcingaDirectorSelfServiceConfig.psm1 | 33 ++++++++++++++++ ...egister-IcingaDirectorSelfServiceHost.psm1 | 38 +++++++++++++++++++ 2 files changed, 71 insertions(+) create mode 100644 lib/apis/Get-IcingaDirectorSelfServiceConfig.psm1 create mode 100644 lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 diff --git a/lib/apis/Get-IcingaDirectorSelfServiceConfig.psm1 b/lib/apis/Get-IcingaDirectorSelfServiceConfig.psm1 new file mode 100644 index 0000000..7e48f9c --- /dev/null +++ b/lib/apis/Get-IcingaDirectorSelfServiceConfig.psm1 @@ -0,0 +1,33 @@ +function Get-IcingaDirectorSelfServiceConfig() +{ + param( + $DirectorUrl, + $ApiKey = $null + ); + + if ([string]::IsNullOrEmpty($DirectorUrl)) { + throw 'Please enter a valid Url to your Icinga Director'; + } + + if ([string]::IsNullOrEmpty($ApiKey)) { + throw 'Please enter either a template or your host key'; + } + + $ProgressPreference = "SilentlyContinue"; + + $EndpointUrl = [string]::Format('{0}/self-service/powershell-parameters?key={1}', $DirectorUrl, $ApiKey); + + $response = Invoke-WebRequest -Uri $EndpointUrl -UseBasicParsing -Headers @{ 'accept' = 'application/json'; 'X-Director-Accept' = 'application/json' } -Method 'POST'; + + if ($response.StatusCode -ne 200) { + throw $response.Content; + } + + $JsonContent = ConvertFrom-Json -InputObject $response.Content; + + if (Test-PSCustomObjectMember -PSObject $JsonContent -Name 'error') { + throw 'Icinga Director Self-Service has thrown an error: ' + $JsonContent.error; + } + + return $JsonContent; +} diff --git a/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 b/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 new file mode 100644 index 0000000..da2250d --- /dev/null +++ b/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 @@ -0,0 +1,38 @@ +function Register-IcingaDirectorSelfServiceHost() +{ + param( + $DirectorUrl, + $Hostname, + $ApiKey = $null + ); + + if ([string]::IsNullOrEmpty($DirectorUrl)) { + throw 'Please enter a valid Url to your Icinga Director'; + } + + if ([string]::IsNullOrEmpty($Hostname)) { + throw 'Please enter the hostname to use'; + } + + if ([string]::IsNullOrEmpty($ApiKey)) { + throw 'Please enter the API key of the template you wish to use'; + } + + $ProgressPreference = "SilentlyContinue"; + + $EndpointUrl = [string]::Format('{0}/self-service/register-host?name={1}&key={2}', $DirectorUrl, $Hostname, $ApiKey); + + $response = Invoke-WebRequest -Uri $EndpointUrl -UseBasicParsing -Headers @{ 'accept' = 'application/json'; 'X-Director-Accept' = 'application/json' } -Method 'POST'; + + if ($response.StatusCode -ne 200) { + throw $response.Content; + } + + $JsonContent = ConvertFrom-Json -InputObject $response.Content; + + if (Test-PSCustomObjectMember -PSObject $JsonContent -Name 'error') { + throw 'Icinga Director Self-Service has thrown an error: ' + $JsonContent.error; + } + + return $JsonContent; +} From d3d31bfcd439feaa2507089e179175e474a89059 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 6 Oct 2019 16:57:47 +0200 Subject: [PATCH 146/259] Added directories to .gitignore (cache and config) --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 1f45433..e808c30 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ log/* agent/* +config/* +cache/* .vscode/ *.log \ No newline at end of file From ffd3cf564433b6c7c86273c6e1dfbf9dbaac8c9b Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 6 Oct 2019 17:10:39 +0200 Subject: [PATCH 147/259] Added Cmdlet to update registered Service Check config --- ...et-IcingaRegisteredServiceCheckConfig.psm1 | 38 +++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 lib/daemon/Set-IcingaRegisteredServiceCheckConfig.psm1 diff --git a/lib/daemon/Set-IcingaRegisteredServiceCheckConfig.psm1 b/lib/daemon/Set-IcingaRegisteredServiceCheckConfig.psm1 new file mode 100644 index 0000000..9edc6b5 --- /dev/null +++ b/lib/daemon/Set-IcingaRegisteredServiceCheckConfig.psm1 @@ -0,0 +1,38 @@ +function Set-IcingaRegisteredServiceCheckConfig() +{ + param( + [string]$ServiceId, + [hashtable]$Arguments = $null, + $Interval = $null, + [array]$TimeIndexes = $null + ); + + $Services = Get-IcingaRegisteredServiceChecks; + + if ($Services.ContainsKey($ServiceId) -eq $FALSE) { + Write-Host 'Service Id was not found'; + return; + } + + [bool]$Modified = $FALSE; + $Path = [string]::Format('BackgroundDaemon.RegisteredServices.{0}', $ServiceId); + + if ($null -ne $Arguments) { + Set-IcingaPowerShellConfig -Path ([string]::Format('{0}.Arguments', $Path)) -Value $Arguments; + $Modified = $TRUE; + } + if ($null -ne $Interval) { + Set-IcingaPowerShellConfig -Path ([string]::Format('{0}.Interval', $Path)) -Value $Interval; + $Modified = $TRUE; + } + if ($null -ne $TimeIndexes) { + Set-IcingaPowerShellConfig -Path ([string]::Format('{0}.TimeIndexes', $Path)) -Value $TimeIndexes; + $Modified = $TRUE; + } + + if ($Modified) { + Write-Host 'Service configuration was successfully updated'; + } else { + Write-Host 'No arguments were specified to update the service configuraiton'; + } +} From d843ded4f7e08e2f84ba7d4d6d0b8dce8315fc1c Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 6 Oct 2019 18:06:41 +0200 Subject: [PATCH 148/259] Improved code styling --- lib/core/icingaagent/getters/Get-IcingaServiceUser.psm1 | 1 - lib/core/icingaagent/tests/Test-IcingaAcl.psm1 | 1 - lib/provider/services/Icinga_ProviderServices.psm1 | 2 +- 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/lib/core/icingaagent/getters/Get-IcingaServiceUser.psm1 b/lib/core/icingaagent/getters/Get-IcingaServiceUser.psm1 index cb3e2b8..dd867c8 100644 --- a/lib/core/icingaagent/getters/Get-IcingaServiceUser.psm1 +++ b/lib/core/icingaagent/getters/Get-IcingaServiceUser.psm1 @@ -1,7 +1,6 @@ function Get-IcingaServiceUser() { $Services = Get-IcingaServices -Service 'icinga2'; - if ($null -eq $Services) { throw 'Icinga Service not installed'; } diff --git a/lib/core/icingaagent/tests/Test-IcingaAcl.psm1 b/lib/core/icingaagent/tests/Test-IcingaAcl.psm1 index 2914a04..4d1d0c3 100644 --- a/lib/core/icingaagent/tests/Test-IcingaAcl.psm1 +++ b/lib/core/icingaagent/tests/Test-IcingaAcl.psm1 @@ -13,7 +13,6 @@ function Test-IcingaAcl() $ServiceUser = Get-IcingaServiceUser; $UserFound = $FALSE; $HasAccess = $FALSE; - foreach ($user in $FolderACL.Access) { # Not only check here for the exact name but also for included strings like NT AU or NT-AU or even further later on # As the Get-Acl Cmdlet will translate usernames into the own language, resultng in 'NT AUTHORITY\NetworkService' being translated diff --git a/lib/provider/services/Icinga_ProviderServices.psm1 b/lib/provider/services/Icinga_ProviderServices.psm1 index 74d66a4..a6e5a0f 100644 --- a/lib/provider/services/Icinga_ProviderServices.psm1 +++ b/lib/provider/services/Icinga_ProviderServices.psm1 @@ -2,7 +2,7 @@ function Get-IcingaServices() { param ( [array]$Service - ) + ); $ServiceInformation = Get-Service -Name $Service -ErrorAction SilentlyContinue; $ServiceWmiInfo = $null; From 4fe7b03e694ddc13ba9c5eabb747db02dbea6094 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 6 Oct 2019 20:16:05 +0200 Subject: [PATCH 149/259] Added Performance Counter Check Command --- .../Invoke-IcingaCheckPerfcounter.psm1 | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) create mode 100644 lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 diff --git a/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 b/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 new file mode 100644 index 0000000..4863cfb --- /dev/null +++ b/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 @@ -0,0 +1,36 @@ +Import-IcingaLib icinga\plugin; + +function Invoke-IcingaCheckPerfcounter() +{ + param( + [array]$PerfCounter, + $Warning, + $Critical, + [switch]$NoPerfData, + [int]$Verbose + ); + + $Counters = New-IcingaPerformanceCounterArray -CounterArray $PerfCounter; + $CheckPackage = New-IcingaCheckPackage -Name 'Performance Counter' -OperatorAnd -Verbose $Verbose; + + foreach ($counter in $Counters.Keys) { + + $CounterPackage = New-IcingaCheckPackage -Name $counter -OperatorAnd -Verbose $Verbose; + + foreach ($instanceName in $Counters[$counter].Keys) { + $instance = $Counters[$counter][$instanceName]; + if ($instance -isnot [hashtable]) { + $IcingaCheck = New-IcingaCheck -Name $counter -Value $Counters[$counter].Value; + $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + $CounterPackage.AddCheck($IcingaCheck); + break; + } + $IcingaCheck = New-IcingaCheck -Name $instanceName -Value $instance.Value; + $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + $CounterPackage.AddCheck($IcingaCheck); + } + $CheckPackage.AddCheck($CounterPackage); + } + + return (New-IcingaCheckresult -Check $CheckPackage -NoPerfData $NoPerfData -Compile); +} From 6900a1694fd5f64ba4090e96919cc2ee9247838b Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 7 Oct 2019 00:04:30 +0200 Subject: [PATCH 150/259] Added proper support for custom plugins / lib elements --- core/init.ps1 | 1 + custom/lib/README.md | 3 +++ custom/plugins/README.md | 3 +++ icinga-module-windows.psd1 | 2 +- icinga-module-windows.psm1 | 16 ++++++++++++++-- lib/core/tools/New-IcingaCheckCommand.psm1 | 2 +- 6 files changed, 23 insertions(+), 4 deletions(-) create mode 100644 custom/lib/README.md create mode 100644 custom/plugins/README.md diff --git a/core/init.ps1 b/core/init.ps1 index ac4b829..99b7756 100644 --- a/core/init.ps1 +++ b/core/init.ps1 @@ -10,6 +10,7 @@ Set-Variable -Name Icinga2 -Option Constant -Value @{ 'Use-Icinga', 'Import-IcingaLib', 'Get-IcingaPluginDir', + 'Get-IcingaCustomPluginDir', 'Get-IcingaCacheDir', 'Get-IcingaPowerShellConfigDir', 'Get-Icinga-Lib', diff --git a/custom/lib/README.md b/custom/lib/README.md new file mode 100644 index 0000000..751fa67 --- /dev/null +++ b/custom/lib/README.md @@ -0,0 +1,3 @@ +# Custom Libraries + +Here you can place your own libraries for the module. You can either extend the module with this or override existing libraries without having to worry about breaking future updates diff --git a/custom/plugins/README.md b/custom/plugins/README.md new file mode 100644 index 0000000..b74aded --- /dev/null +++ b/custom/plugins/README.md @@ -0,0 +1,3 @@ +# Custom Plugins + +Here you can place your own custom plugins or override existing ones. This will ensure future updates of the module will not rever your changes diff --git a/icinga-module-windows.psd1 b/icinga-module-windows.psd1 index 3ae95d2..a64d8ac 100644 --- a/icinga-module-windows.psd1 +++ b/icinga-module-windows.psd1 @@ -25,7 +25,7 @@ Description = 'Icinga 2 Windows Agent Module, which allows to entirely monitor t PowerShellVersion = '3.0' # Aus diesem Modul zu exportierende Funktionen. Um optimale Leistung zu erzielen, verwenden Sie keine Platzhalter und löschen den Eintrag nicht. Verwenden Sie ein leeres Array, wenn keine zu exportierenden Funktionen vorhanden sind. -FunctionsToExport = @( 'Use-Icinga', 'Import-IcingaLib', 'Get-IcingaPluginDir', 'Get-IcingaCacheDir', 'Get-IcingaPowerShellConfigDir', 'Start-Icinga-Checker', 'Stop-Icinga-Checker', 'Get-Icinga-Lib', 'Get-Icinga-Object', 'Get-Icinga-Service', 'Start-Icinga-Service', 'Stop-Icinga-Service', 'Restart-Icinga-Service', 'Install-Icinga-Service', 'Uninstall-Icinga-Service', 'Get-Icinga-Setup', 'Install-Icinga', 'Start-Icinga-Daemon', 'Stop-Icinga-Daemon', 'Icinga-Client', 'Get-Icinga-Command', 'New-Icinga-Monitoring', 'Get-Icinga-Counter', 'Get-Icinga-Config', 'Set-Icinga-Config', 'Remove-Icinga-Config', 'New-Icinga-Config' ) +FunctionsToExport = @( 'Use-Icinga', 'Import-IcingaLib', 'Get-IcingaPluginDir', 'Get-IcingaCustomPluginDir', 'Get-IcingaCacheDir', 'Get-IcingaPowerShellConfigDir', 'Start-Icinga-Checker', 'Stop-Icinga-Checker', 'Get-Icinga-Lib', 'Get-Icinga-Object', 'Get-Icinga-Service', 'Start-Icinga-Service', 'Stop-Icinga-Service', 'Restart-Icinga-Service', 'Install-Icinga-Service', 'Uninstall-Icinga-Service', 'Get-Icinga-Setup', 'Install-Icinga', 'Start-Icinga-Daemon', 'Stop-Icinga-Daemon', 'Icinga-Client', 'Get-Icinga-Command', 'New-Icinga-Monitoring', 'Get-Icinga-Counter', 'Get-Icinga-Config', 'Set-Icinga-Config', 'Remove-Icinga-Config', 'New-Icinga-Config' ) # Aus diesem Modul zu exportierende Cmdlets. Um optimale Leistung zu erzielen, verwenden Sie keine Plat'zhalter und löschen den Eintrag nicht. Verwenden Sie ein leeres Array, wenn keine zu exportierenden Cmdlets vorhanden sind. CmdletsToExport = @() diff --git a/icinga-module-windows.psm1 b/icinga-module-windows.psm1 index adfe97a..bc3850b 100644 --- a/icinga-module-windows.psm1 +++ b/icinga-module-windows.psm1 @@ -18,6 +18,8 @@ function Use-Icinga() # This function will allow us to load this entire module including possible # actions, making it available within our shell environment + # First load our custom modules + Import-IcingaLib '\' -Init -Custom; Import-IcingaLib '\' -Init; if ($LibOnly -eq $FALSE) { @@ -48,7 +50,8 @@ function Import-IcingaLib() # The Force Reload will remove the module in case it's loaded and reload it to track # possible development changes without having to create new PowerShell environments [Switch]$ForceReload, - [switch]$Init + [switch]$Init, + [switch]$Custom ); # This is just to only allow a global loading of the module. Import-IcingaLib is ignored on every other @@ -57,7 +60,11 @@ function Import-IcingaLib() return; } - [string]$directory = Join-Path -Path $PSScriptRoot -ChildPath 'lib\'; + if ($Custom) { + [string]$directory = Join-Path -Path $PSScriptRoot -ChildPath 'custom\'; + } else { + [string]$directory = Join-Path -Path $PSScriptRoot -ChildPath 'lib\'; + } [string]$module = Join-Path -Path $directory -ChildPath $Lib; [string]$moduleName = ''; @@ -99,6 +106,11 @@ function Get-IcingaPluginDir() return (Join-Path -Path $PSScriptRoot -ChildPath 'lib\plugins\'); } +function Get-IcingaCustomPluginDir() +{ + return (Join-Path -Path $PSScriptRoot -ChildPath 'custom\plugins\'); +} + function Get-IcingaCacheDir() { return (Join-Path -Path $PSScriptRoot -ChildPath 'cache'); diff --git a/lib/core/tools/New-IcingaCheckCommand.psm1 b/lib/core/tools/New-IcingaCheckCommand.psm1 index 56c8a92..f3a1787 100644 --- a/lib/core/tools/New-IcingaCheckCommand.psm1 +++ b/lib/core/tools/New-IcingaCheckCommand.psm1 @@ -29,7 +29,7 @@ function New-IcingaCheckCommand() $CommandName ); - [string]$ScriptFile = Join-Path -Path (Get-IcingaPluginDir) -ChildPath $CommandFile; + [string]$ScriptFile = Join-Path -Path (Get-IcingaCustomPluginDir) -ChildPath $CommandFile; if ((Test-Path $ScriptFile) -eq $TRUE) { throw 'This Check-Command does already exist.'; From 5acbb52575bcb8e829d854b2d5f4c9d1a29af469 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 7 Oct 2019 00:06:15 +0200 Subject: [PATCH 151/259] Added helper function to test for administrative shell --- lib/core/tools/Test-AdministrativeShell.psm1 | 11 +++++++++++ 1 file changed, 11 insertions(+) create mode 100644 lib/core/tools/Test-AdministrativeShell.psm1 diff --git a/lib/core/tools/Test-AdministrativeShell.psm1 b/lib/core/tools/Test-AdministrativeShell.psm1 new file mode 100644 index 0000000..aaa2f83 --- /dev/null +++ b/lib/core/tools/Test-AdministrativeShell.psm1 @@ -0,0 +1,11 @@ +function Test-AdministrativeShell() +{ + $WindowsPrincipcal = New-Object System.Security.Principal.WindowsPrincipal( + [System.Security.Principal.WindowsIdentity]::GetCurrent() + ); + + if ($WindowsPrincipcal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)) { + return $TRUE; + } + return $FALSE; +} From 169b8583d087008894f205163b399ba1884cf7b6 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 7 Oct 2019 00:56:19 +0200 Subject: [PATCH 152/259] Added cache folder to repository --- .gitignore | 4 +++- cache/README.md | 3 +++ 2 files changed, 6 insertions(+), 1 deletion(-) create mode 100644 cache/README.md diff --git a/.gitignore b/.gitignore index e808c30..95d338c 100644 --- a/.gitignore +++ b/.gitignore @@ -3,4 +3,6 @@ agent/* config/* cache/* .vscode/ -*.log \ No newline at end of file +*.log + +!cache/README.md diff --git a/cache/README.md b/cache/README.md new file mode 100644 index 0000000..5af9fa2 --- /dev/null +++ b/cache/README.md @@ -0,0 +1,3 @@ +# Cache folder + +Every content the module requires to run efficiently will be stored within this folder. The module will ensure housekeeping here to not spam the filesystem From 76479880a67ddf4abafb1674a0601a61220c3a00 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 7 Oct 2019 16:30:55 +0200 Subject: [PATCH 153/259] Fixed duplicate '__' in Perf Data output --- lib/core/tools/Format-IcingaPerfDataLabel.psm1 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/core/tools/Format-IcingaPerfDataLabel.psm1 b/lib/core/tools/Format-IcingaPerfDataLabel.psm1 index d28aaf1..c0bd663 100644 --- a/lib/core/tools/Format-IcingaPerfDataLabel.psm1 +++ b/lib/core/tools/Format-IcingaPerfDataLabel.psm1 @@ -4,6 +4,11 @@ function Format-IcingaPerfDataLabel() $PerfData ); + $Output = ((($PerfData) -Replace ' ', '_') -Replace '[\W]', ''); + + while ($Output.Contains('__')) { + $Output = $Output.Replace('__', '_'); + } # Remove all special characters and spaces on label names - return ((($PerfData) -Replace ' ', '_') -Replace '[\W]', ''); + return $Output; } From 03ecf123da1c4c147fb5cf15879834ae4516c1d0 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 17 Oct 2019 08:44:48 +0200 Subject: [PATCH 154/259] Improved Agent Install Wizard for global zone config --- .../misc/Start-IcingaAgentInstallWizard.psm1 | 43 +++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index f551460..9bb8200 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -6,6 +6,8 @@ function Start-IcingaAgentInstallWizard() [switch]$AutoUseHostname = $FALSE, [switch]$LowerCase = $FALSE, [switch]$UpperCase = $FALSE, + $AddDirectorGlobal = $null, + $AddGlobalTemplates = $null, [string]$PackageSource, [string]$AgentVersion, [switch]$AllowVersionChanges = $FALSE, @@ -24,6 +26,7 @@ function Start-IcingaAgentInstallWizard() ); [array]$InstallerArguments = @(); + [array]$GlobalZoneConfig = @(); if ([string]::IsNullOrEmpty($Hostname) -And $AutoUseFQDN -eq $FALSE -And $AutoUseHostname -eq $FALSE) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to manually specify a hostname?' -Default 'n').result -eq 1) { @@ -136,14 +139,44 @@ function Start-IcingaAgentInstallWizard() $InstallerArguments += "-ParentZone $ParentZone"; } + if ($null -eq $AddDirectorGlobal) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to add the global zone "director-global"?' -Default 'y').result -eq 1) { + $AddDirectorGlobal = $TRUE; + } else { + $AddDirectorGlobal = $FALSE; + } + } + + $InstallerArguments += ("-AddDirectorGlobal $AddDirectorGlobal"); + if ($AddDirectorGlobal) { + $GlobalZoneConfig += 'director-global'; + } + + if ($null -eq $AddGlobalTemplates) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to add the global zone "global-templates"?' -Default 'y').result -eq 1) { + $AddGlobalTemplates = $TRUE; + } else { + $AddGlobalTemplates = $FALSE; + } + } + + $InstallerArguments += ("-AddGlobalTemplates $AddGlobalTemplates"); + if ($AddGlobalTemplates) { + $GlobalZoneConfig += 'global-templates'; + } + if ($null -eq $GlobalZones) { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to add additional global zones, besides "director-global" and "global-templates"?' -Default 'n').result -eq 0) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to add custom global zones?' -Default 'n').result -eq 0) { $ArrayString = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify your additional zones seperated by ","' -Default 'v').answer; - $GlobalZones = ($ArrayString.Replace(' ', '')).Split(','); + $GlobalZones = ($ArrayString.Replace(' ', '')).Split(',') + $GlobalZoneConfig += $GlobalZones; $InstallerArguments += ("-GlobalZones " + ([string]::Join(',', $GlobalZones))); } else { $GlobalZones = @(); + $InstallerArguments += ("-GlobalZones @()"); } + } else { + $GlobalZoneConfig += $GlobalZones; } [bool]$CanConnectToParent = $FALSE; @@ -170,10 +203,12 @@ function Start-IcingaAgentInstallWizard() $CAPort = 5665; } } - if ([string]::IsNullOrEmpty($Ticket)) { + if ($null -eq $Ticket) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you have a Icinga Ticket available to sign your certificate?' -Default 'y').result -eq 1) { $Ticket = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter your Icinga Ticket' -Default 'v').answer; $InstallerArguments += "-Ticket $Ticket"; + } else { + $InstallerArguments += "-Ticket ''"; } } } else { @@ -210,7 +245,7 @@ function Start-IcingaAgentInstallWizard() Install-IcingaAgentBaseFeatures; Install-IcingaAgentCertificates -Hostname $Hostname -Endpoint $CAEndpoint -Port $CAPort -CACert $CAFile -Ticket $Ticket | Out-Null; Write-IcingaAgentApiConfig -Port $CAPort; - Write-IcingaAgentZonesConfig -Endpoints $Endpoints -EndpointConnections $EndpointConnections -ParentZone $ParentZone -GlobalZones $GlobalZones -Hostname $Hostname; + Write-IcingaAgentZonesConfig -Endpoints $Endpoints -EndpointConnections $EndpointConnections -ParentZone $ParentZone -GlobalZones $GlobalZoneConfig -Hostname $Hostname; Test-IcingaAgent; Restart-Service icinga2; } From a13a706e14318e05008376e2b263ef9034b681f7 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 17 Oct 2019 09:57:16 +0200 Subject: [PATCH 155/259] Added SecureString convertion functions --- lib/core/tools/ConvertFrom-IcingaSecureString.psm1 | 13 +++++++++++++ lib/core/tools/ConvertTo-IcingaSecureString.psm1 | 12 ++++++++++++ 2 files changed, 25 insertions(+) create mode 100644 lib/core/tools/ConvertFrom-IcingaSecureString.psm1 create mode 100644 lib/core/tools/ConvertTo-IcingaSecureString.psm1 diff --git a/lib/core/tools/ConvertFrom-IcingaSecureString.psm1 b/lib/core/tools/ConvertFrom-IcingaSecureString.psm1 new file mode 100644 index 0000000..77aa1d1 --- /dev/null +++ b/lib/core/tools/ConvertFrom-IcingaSecureString.psm1 @@ -0,0 +1,13 @@ +function ConvertFrom-IcingaSecureString() +{ + param([SecureString]$SecureString); + + if ($SecureString -eq $null) { + return ''; + } + + [IntPtr]$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecureString) + [string]$String = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) + + return $String; +} diff --git a/lib/core/tools/ConvertTo-IcingaSecureString.psm1 b/lib/core/tools/ConvertTo-IcingaSecureString.psm1 new file mode 100644 index 0000000..76831c6 --- /dev/null +++ b/lib/core/tools/ConvertTo-IcingaSecureString.psm1 @@ -0,0 +1,12 @@ +<# + # Helper class allowing to easily convert strings into SecureStrings + # and vice-versa + #> +function ConvertTo-IcingaSecureString() +{ + param( + [string]$String + ); + + return (ConvertTo-SecureString -AsPlainText $string -Force); +} From a00f2aeda5ebbf4b25d79744f9d7ed0ac1f555fd Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 17 Oct 2019 22:51:12 +0200 Subject: [PATCH 156/259] Added Icinga Service and Service permission management --- .../Get-IcingaAgentServicePermission.psm1 | 16 +++++++ .../Set-IcingaAgentServicePermission.psm1 | 46 +++++++++++++++++++ .../setters/Set-IcingaAgentServiceUser.psm1 | 30 ++++++++++++ .../icingaagent/tests/Test-IcingaAgent.psm1 | 1 + .../Test-IcingaAgentServicePermission.psm1 | 46 +++++++++++++++++++ lib/core/tools/Get-IcingaUserSID.psm1 | 31 +++++++++++++ 6 files changed, 170 insertions(+) create mode 100644 lib/core/icingaagent/getters/Get-IcingaAgentServicePermission.psm1 create mode 100644 lib/core/icingaagent/setters/Set-IcingaAgentServicePermission.psm1 create mode 100644 lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 create mode 100644 lib/core/icingaagent/tests/Test-IcingaAgentServicePermission.psm1 create mode 100644 lib/core/tools/Get-IcingaUserSID.psm1 diff --git a/lib/core/icingaagent/getters/Get-IcingaAgentServicePermission.psm1 b/lib/core/icingaagent/getters/Get-IcingaAgentServicePermission.psm1 new file mode 100644 index 0000000..ffe9ae9 --- /dev/null +++ b/lib/core/icingaagent/getters/Get-IcingaAgentServicePermission.psm1 @@ -0,0 +1,16 @@ +function Get-IcingaAgentServicePermission() +{ + $SystemPermissions = New-TemporaryFile; + $SystemOutput = Start-IcingaProcess -Executable 'secedit.exe' -Arguments ([string]::Format('/export /cfg "{0}.inf"', $SystemPermissions)); + + if ($SystemOutput.ExitCode -ne 0) { + throw ([string]::Format('Unable to fetch system permission information: {0}', $SystemOutput.Message)); + return $null; + } + + $SystemContent = Get-Content "$SystemPermissions.inf"; + + Remove-Item $SystemPermissions*; + + return $SystemContent; +} diff --git a/lib/core/icingaagent/setters/Set-IcingaAgentServicePermission.psm1 b/lib/core/icingaagent/setters/Set-IcingaAgentServicePermission.psm1 new file mode 100644 index 0000000..aa11db4 --- /dev/null +++ b/lib/core/icingaagent/setters/Set-IcingaAgentServicePermission.psm1 @@ -0,0 +1,46 @@ +function Set-IcingaAgentServicePermission() +{ + if (Test-IcingaAgentServicePermission -Silent) { + Write-Host 'The Icinga Service User already has permission to run as service'; + return; + } + + $SystemPermissions = New-TemporaryFile; + $ServiceUser = Get-IcingaServiceUser; + $ServiceUserSID = Get-IcingaUserSID $ServiceUser; + $SystemContent = Get-IcingaAgentServicePermission; + $NewSystemContent = @(); + + if ([string]::IsNullOrEmpty($ServiceUser)) { + Write-IcingaTestOutput -Severity 'FAILED' -Message 'There is no user assigned to the Icinga 2 service or the service is not yet installed'; + return $FALSE; + } + + foreach ($line in $SystemContent) { + if ($line -like '*SeServiceLogonRight*') { + $line = [string]::Format('{0},*{1}', $line, $ServiceUserSID); + } + + $NewSystemContent += $line; + } + + Set-Content -Path "$SystemPermissions.inf" -Value $NewSystemContent; + + $SystemOutput = Start-IcingaProcess -Executable 'secedit.exe' -Arguments ([string]::Format('/import /cfg "{0}.inf" /db "{0}.sdb"', $SystemPermissions)); + + if ($SystemOutput.ExitCode -ne 0) { + throw ([string]::Format('Unable to import system permission information: {0}', $SystemOutput.Message)); + return $null; + } + + $SystemOutput = Start-IcingaProcess -Executable 'secedit.exe' -Arguments ([string]::Format('/configure /cfg "{0}.inf" /db "{0}.sdb"', $SystemPermissions)); + + if ($SystemOutput.ExitCode -ne 0) { + throw ([string]::Format('Unable to configure system permission information: {0}', $SystemOutput.Message)); + return $null; + } + + Remove-Item $SystemPermissions*; + + Test-IcingaAgentServicePermission | Out-Null; +} diff --git a/lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 b/lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 new file mode 100644 index 0000000..5940775 --- /dev/null +++ b/lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 @@ -0,0 +1,30 @@ +function Set-IcingaAgentServiceUser() +{ + param( + [string]$User, + [securestring]$Password + ); + + if ([string]::IsNullOrEmpty($User)) { + throw 'Please specify a username to modify the service user'; + return $FALSE; + } + + $ArgString = 'config icinga2 obj= "{0}" password="{1}"'; + if($null -eq $Password) { + $ArgString = 'config icinga2 obj= "{0}"{1}'; + } + + $Output = Start-IcingaProcess ` + -Executable 'sc.exe' ` + -Arguments ([string]::Format($ArgString, $User, (ConvertFrom-IcingaSecureString $Password))) ` + -FlushNewLines $TRUE; + + if ($Output.ExitCode -eq 0) { + Write-Host 'Service User successfully updated' + return $TRUE; + } else { + Write-Host ([string]::Format('Failed to update the service user: {0}', $Output.Message)); + return $FALSE; + } +} diff --git a/lib/core/icingaagent/tests/Test-IcingaAgent.psm1 b/lib/core/icingaagent/tests/Test-IcingaAgent.psm1 index e0b5173..16ff760 100644 --- a/lib/core/icingaagent/tests/Test-IcingaAgent.psm1 +++ b/lib/core/icingaagent/tests/Test-IcingaAgent.psm1 @@ -2,6 +2,7 @@ function Test-IcingaAgent() { if (Get-Service 'icinga2' -ErrorAction SilentlyContinue) { Write-IcingaTestOutput -Severity 'PASSED' -Message 'Icinga Agent Service is installed'; + Test-IcingaAgentServicePermission | Out-Null; Test-IcingaAcl "$Env:ProgramData\icinga2\etc" -WriteOutput | Out-Null; Test-IcingaAcl "$Env:ProgramData\icinga2\var" -WriteOutput | Out-Null; Test-IcingaAcl (Get-IcingaCacheDir) -WriteOutput | Out-Null; diff --git a/lib/core/icingaagent/tests/Test-IcingaAgentServicePermission.psm1 b/lib/core/icingaagent/tests/Test-IcingaAgentServicePermission.psm1 new file mode 100644 index 0000000..9631291 --- /dev/null +++ b/lib/core/icingaagent/tests/Test-IcingaAgentServicePermission.psm1 @@ -0,0 +1,46 @@ +function Test-IcingaAgentServicePermission() +{ + param( + [switch]$Silent = $FALSE + ); + + $ServiceUser = Get-IcingaServiceUser; + $ServiceUserSID = Get-IcingaUserSID $ServiceUser; + $SystemContent = Get-IcingaAgentServicePermission; + [bool]$FoundSID = $FALSE; + + if ([string]::IsNullOrEmpty($ServiceUser)) { + if (-Not $Silent) { + Write-IcingaTestOutput -Severity 'FAILED' -Message 'There is no user assigned to the Icinga 2 service or the service is not yet installed'; + } + return $FALSE; + } + + foreach ($line in $SystemContent) { + if ($line -like '*SeServiceLogonRight*') { + $Index = $line.IndexOf('= ') + 2; + [string]$SIDs = $line.Substring($Index, $line.Length - $Index); + [array]$SIDArray = $SIDs.Split(','); + + foreach ($sid in $SIDArray) { + if ($sid -like "*$ServiceUserSID" -Or $sid -eq $ServiceUser) { + $FoundSID = $TRUE; + break; + } + } + } + if ($FoundSID) { + break; + } + } + + if (-Not $Silent) { + if ($FoundSID) { + Write-IcingaTestOutput -Severity 'PASSED' -Message ([string]::Format('The specified user "{0}" is allowed to run as service.', $ServiceUser)); + } else { + Write-IcingaTestOutput -Severity 'FAILED' -Message ([string]::Format('The specified user "{0}" is not allowed to run as service.', $ServiceUser)); + } + } + + return $FoundSID; +} diff --git a/lib/core/tools/Get-IcingaUserSID.psm1 b/lib/core/tools/Get-IcingaUserSID.psm1 new file mode 100644 index 0000000..5ca78b1 --- /dev/null +++ b/lib/core/tools/Get-IcingaUserSID.psm1 @@ -0,0 +1,31 @@ +function Get-IcingaUserSID() +{ + param( + [string]$User + ); + + [string]$Username = ''; + [string]$Domain = ''; + + if ($User.Contains('\')) { + $TmpArray = $User.Split('\'); + $Domain = $TmpArray[0]; + $Username = $TmpArray[1]; + } else { + $Domain = Get-IcingaHostname; + $Username = $User; + } + + try { + $NTUser = [System.Security.Principal.NTAccount]::New($Domain, $Username); + $SecurityData = $NTUser.Translate([System.Security.Principal.SecurityIdentifier]); + } catch { + throw $_.Exception; + } + + if ($null -eq $SecurityData) { + throw 'Failed to fetch user information from system'; + } + + return $SecurityData.Value; +} From 9bcd824f87c17aa07bee40c1091b400ae19b06f9 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 21 Oct 2019 15:18:51 +0200 Subject: [PATCH 157/259] Add first draft of new documentation --- README.md | 19 +-- doc/01-Introduction.md | 20 +-- doc/02-Installation.md | 67 ++------- doc/03-ExecutionPolicy.md | 12 -- doc/03-WebIntegration.md | 40 +++++ doc/04-DeveloperGuide.md | 13 ++ doc/05-IcingaIntegration.md | 20 +++ doc/10-InstallService.md | 30 ++-- doc/11-IcingaWeb2Integration.md | 2 +- doc/developerguide/01-NewIcingaCheck.md | 140 ++++++++++++++++++ doc/icingaintegration/01-DirectorBaskets.md | 44 ++++++ .../02-Icinga2AgentExample.md} | 0 doc/installation/01-KickstartScript.md | 30 ++++ doc/installation/02-ManualInstallation.md | 44 ++++++ 14 files changed, 374 insertions(+), 107 deletions(-) delete mode 100644 doc/03-ExecutionPolicy.md create mode 100644 doc/03-WebIntegration.md create mode 100644 doc/04-DeveloperGuide.md create mode 100644 doc/05-IcingaIntegration.md create mode 100644 doc/developerguide/01-NewIcingaCheck.md create mode 100644 doc/icingaintegration/01-DirectorBaskets.md rename doc/{12-Icinga2AgentExample.md => icingaintegration/02-Icinga2AgentExample.md} (100%) create mode 100644 doc/installation/01-KickstartScript.md create mode 100644 doc/installation/02-ManualInstallation.md diff --git a/README.md b/README.md index b1a1d98..cd6b33b 100644 --- a/README.md +++ b/README.md @@ -1,14 +1,10 @@ Icinga Module for Windows ============== -## This Module is a Technical-Preview and should **NOT** be used actively in production! +**This Module is a Technical-Preview and should **NOT** be used actively in production!** -This repository provides a PowerShell Module to fetch information and data of Windows Hosts, allowing a wide range of integrations - -* Remote Execeution -* Icinga Web 2 integration -* Usage with the Icinga 2 Agent -* ... +The Icinga PowerShell Framework provides a wide range of configurarion and check possibilities to ensure an easy integration and full monitoring of windows environments. +Each single chapter of this documentation will describe parts of the module and the possibilities. Before you continue, please take a look on the [installation guide](doc/02-Installation.md) @@ -19,7 +15,12 @@ Please take a look on the following content to get to know the possibilities of * [Introduction](doc/01-Introduction.md) * [Installation Guide](doc/02-Installation.md) -* [Execution Policies](doc/03-ExecutionPolicy.md) +* [Icinga Integration](doc/05-IcingaIntegration.md) + +Developer Guide +------------ + +If you wish to extend the Framework by yourself or write custom plugins for your environment, please have a look on the [Developer Guide](doc/04-DeveloperGuide.md) for detailed explanations of functions and code examples. Contributing ------------ @@ -28,4 +29,4 @@ The Icinga Windows Module is an Open Source project and lives from your contribu * Please check whether a related issue alredy exists on our [Issue Tracker](https://github.com/LordHepipud/icinga-module-windows/issues) * Send a [Pull Request](https://github.com/LordHepipud/icinga-module-windows/pulls) -* The master branche shall never be corrupt! \ No newline at end of file +* The master branche shall never be corrupt! diff --git a/doc/01-Introduction.md b/doc/01-Introduction.md index c65b927..805eead 100644 --- a/doc/01-Introduction.md +++ b/doc/01-Introduction.md @@ -1,23 +1,13 @@ Introduction -============== +=== -This PowerShell Module will provide a basic framework to retreive data from Windows Hosts. The module will work with the current common Windows Versions, starting from Windows 7 / 2008 R2. Older versions might also work, are however not official supported. +This PowerShell Framework will provide a collection of Cmdlets to entirely manage an Icinga 2 Agent setup and provide check plugins to fetch information from Windows hosts. -The module will execute local PowerShell scripts (modules) and return the result as formatted JSON. This result can later be parsed by any software to either do inventory or monitoring tasks. - -### Architecture - -![Architecture](images/01_architecture/architecture.png) - -The module provides three ways to fetch data: - -* An active Rest-Api -* A passive Checker component -* PowerShell Cmdlets +It will ensure all required Icinga configurations are handled and present and offer an easy way to extend the monitoring with custom plugins. The framework will provide a standardised set of Cmdlets, Tools and Providers to make daily work, integrations and testing available to everyone, regardless if you are a Developer, System Engineer or enthusiast. The following requirements have to be fullfilled: * Windows 7 / Windows 2008 R2 or later -* PowerShell Version 3.x or higher +* PowerShell Version 4.x or higher -If you are ready to get started, take a look on the [installation guide](02-Installation.md). \ No newline at end of file +If you are ready to get started, take a look on the [installation guide](02-Installation.md). diff --git a/doc/02-Installation.md b/doc/02-Installation.md index 77410b2..45deccc 100644 --- a/doc/02-Installation.md +++ b/doc/02-Installation.md @@ -1,66 +1,23 @@ Installing the Module -===================================== +=== -Before you can use this module, you will require to install and configure it. Once done, you are ready to start. +Installing the module is managed by differen ways, depending on the user environment including available possibitilies -Install the module --------------- +Instructions +--- -At first we need to obtain folders in which we can install the module. To get a list of available directories, you can use this command:S -```powershell - echo $env:PSModulePath -``` +* Install the Module with the [Kickstart Script](installation\01-KickstartScript.md) +* Install the module [manually](installation\02-ManualInstallation.md) -***We do recommend to use the Program Files folder (in case it's present) to install the module into, which will make the installation as service easier*** +Testing the installation +--- -To be able to use the module, you will require to have named the folder **exactly** as the .psm1 and .psd1 files inside the repository. - -Example folder path: - -``` - C:\Program Files\WindowsPowerShell\Modules\icinga-module-windows -``` - -To validate if the module is installed properly, you can start a new PowerShell instance and type the following command +Once the module is installed you can try if the installation was successfully by using the command ```powershell - Get-Module -ListAvailable -Name icinga-module-windows +Use-Icinga ``` -If you receive an output stating that the module is installed, you are fine to continue. +This command will initialise the entire module and load all available Cmdlets. -Configure the module --------------- - -Once the module is installed, you will want to run the initial setup. Therefor you will simply have to type in the command - -```powershell - Install-Icinga -``` - -This will create the base configuration of the module including the setup of directories and required files within the **PowerShell Module Directory**. - -Once completed successfully, you are ready to get started with using it. This will include - -* Using it localy with scripts -* Integration into for the Icinga 2 Agent -* Use it as Remote Execution target -* Integrate it into Icinga Web 2 - -If you wish to provide a Rest-Api of this module, you can run this Module as daemon. It will then listen on the default port **5891** - -```powershell - Start-Icinga-Daemon -``` - -Of course if you wish to actively send data to Icinga Web 2 for example, you can do so by running the Checker component - -```powershell - Start-Icinga-Checker -``` - -For additional setup possibilities, please take a look on the following pages: - -* [Use the module as Icinga Plugin Framework](12-Icinga2AgentExample.md) -* [Install the module as Windows Service](10-InstallService.md) -* [Integration into Icinga Web 2](11-IcingaWeb2Integration.md) +Whenever you intend to use specific Cmdlets of the framework for Icinga Plugins, Testing or configuration you will require to run this command for each new PowerShell instance to initialise the framework. diff --git a/doc/03-ExecutionPolicy.md b/doc/03-ExecutionPolicy.md deleted file mode 100644 index 2775ea0..0000000 --- a/doc/03-ExecutionPolicy.md +++ /dev/null @@ -1,12 +0,0 @@ -Setting Execution Policies -===================================== - -In order to be able to run the module on certain Windows Hosts, it might be required to either update the execution policies and/or unblock the module script files. - -The prefered way is to simply unblock the script files, allowing them to be executed on the system. This can be done by running a PowerShell instance as **Administrator** and enter the following command (we assume the module is installed at `C:\Program Files\WindowsPowershell\Modules\icinga-module-windows`. If not, please modify the command with the correct location) - -```powershell - Get-ChildItem -Path 'C:\Program Files\WindowsPowershell\Modules\icinga-module-windows' -Recurse | Unblock-File -``` - -Once done, please try again if you are now able to run the module on your host. If you are still not able to run the module and/or its scripts, please have a look on the Microsoft documentation for the [Set-Execution-Policy](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-6) Cmdlet to modify the Execution Policy for running PowerShell modules on your host, matching your internal guidelines. \ No newline at end of file diff --git a/doc/03-WebIntegration.md b/doc/03-WebIntegration.md new file mode 100644 index 0000000..6fa4549 --- /dev/null +++ b/doc/03-WebIntegration.md @@ -0,0 +1,40 @@ +Web Integration (Deprecated) +=== + +Before you can use this module, you will require to install and configure it. Once done, you are ready to start. + +Configure the module +--- + +Once the module is installed, you will want to run the initial setup. Therefor you will simply have to type in the command + +```powershell +Install-Icinga +``` + +This will create the base configuration of the module including the setup of directories and required files within the **PowerShell Module Directory**. + +Once completed successfully, you are ready to get started with using it. This will include + +* Using it localy with scripts +* Integration into for the Icinga 2 Agent +* Use it as Remote Execution target +* Integrate it into Icinga Web 2 + +If you wish to provide a Rest-Api of this module, you can run this Module as daemon. It will then listen on the default port **5891** + +```powershell +Start-Icinga-Daemon +``` + +Of course if you wish to actively send data to Icinga Web 2 for example, you can do so by running the Checker component + +```powershell +Start-Icinga-Checker +``` + +For additional setup possibilities, please take a look on the following pages: + +* [Use the module as Icinga Plugin Framework](12-Icinga2AgentExample.md) +* [Install the module as Windows Service](10-InstallService.md) +* [Integration into Icinga Web 2](11-IcingaWeb2Integration.md) diff --git a/doc/04-DeveloperGuide.md b/doc/04-DeveloperGuide.md new file mode 100644 index 0000000..cd3a4fb --- /dev/null +++ b/doc/04-DeveloperGuide.md @@ -0,0 +1,13 @@ +Developer Guide for Custom Plugins +=== + +This PowerShell Framework provides a wide collection of Cmdlets and Tools to allow an easy extension and developing of custom Check Plugins for Icinga. + +To ensure the overall functionality of the framework is supported by your custom Plugins, we would advice you to cover all topics of this Developer guide. + +Functions +--- + +A detailed overview of functions can be found below + +* [New-IcingaCheck](developerguide/01-NewIcingaCheck.md) diff --git a/doc/05-IcingaIntegration.md b/doc/05-IcingaIntegration.md new file mode 100644 index 0000000..d6231b3 --- /dev/null +++ b/doc/05-IcingaIntegration.md @@ -0,0 +1,20 @@ +Icinga Integration +=== + +Once you followed the [Installation Guide](02-Installation.md) you are ready to start the integration into Icinga 2. This will allow you to configure your Check-Commands and start using configuring service-templates and services. + +Before you are getting started, be aware that you will always have to use + +```powershell +Use-Icinga +``` + +before you are executing framework related Cmdlets and functions. Otherwise you might run into errors. + +Configuring Check-Commands +--- + +To get started, there are two ways for getting all Check-Commands configured. + +* [Automated coniguration](icingaintegration/01-DirectorBaskets.md) with Baskets +* [Manual configuration](icingaintegration/02-Icinga2AgentExample.md) of Check-Commands diff --git a/doc/10-InstallService.md b/doc/10-InstallService.md index 5ca4cab..ae05aae 100644 --- a/doc/10-InstallService.md +++ b/doc/10-InstallService.md @@ -1,15 +1,15 @@ Run the PowerShell Module as Windows Service -===================================== +=== Requirements --------------- +--- As PowerShell Scripts / Modules can not be installed directly as Windows Service, we will require a little assistance here. In order to make this work, you will require the Icinga Windows Service which can be downloaded directly from the [GitHub Repository](https://github.com/LordHepipud/icinga-windows-service). Install the Service --------------- +--- At first you will require the Service Binary from the [Icinga Windows Service GitHub Repository](https://github.com/LordHepipud/icinga-windows-service) and copy the binary locally to your system. A recommended path would be your Program Files / Program Files (x86) directory. @@ -17,33 +17,33 @@ Any other custom location is fully supported, has to be however accessable from Once you have found a location, the PowerShell Module will assist you with setting up the service itself. In this documentation we will assume the path you have chosen to copy the binary to is -``` - C:\Program Files\Icinga Windows Service +```powershell +C:\Program Files\Icinga-Framework-Service ``` and the binary name is -``` - icinga-service.exe +```powershell +icinga-service.exe ``` Now lets install the service with the help of the PowerShell Module: ```powershell - Install-Icinga-Service -IcingaServicePath 'C:\Program Files\Icinga Windows Service\icinga-service.exe' +Install-IcingaFrameworkService -ServicePath 'C:\Program Files\Icinga-Framework-Service\icinga-service.exe' ``` You can validate if the service has been installed properly by using the Get Service Cmdlet: -``` - Get-Icinga-Service +```powershell +Get-IcingaFrameworkService ``` Of course there are more Cmdlets available, making the management of this Icinga Service alot easier, which should be self explaining: -* Start-Icinga-Service -* Stop-Icinga-Service -* Restart-Icinga-Service -* Uninstall-Icinga-Service +* Start-IcingaFrameworkService +* Stop-IcingaFrameworkService +* Restart-IcingaFrameworkService +* Uninstall-IcingaFrameworkService -**Note:** If you run the PowerShell Module as service, both the Daemon and Checker component will be started. To prevent external access to the Daemon, you should ensure to block port **5891** on this host. \ No newline at end of file +Each enabled background daemon component is afterwards being started and executed. diff --git a/doc/11-IcingaWeb2Integration.md b/doc/11-IcingaWeb2Integration.md index b1eba9e..cc776e6 100644 --- a/doc/11-IcingaWeb2Integration.md +++ b/doc/11-IcingaWeb2Integration.md @@ -1,4 +1,4 @@ -Integrating Icinga Web 2 +Integrating Icinga Web 2 (Deprecated) ===================================== The PowerShell Module provides the possibility to directly (or indirectly over Proxies) connect to an Icinga Web 2 Api to send informations there. diff --git a/doc/developerguide/01-NewIcingaCheck.md b/doc/developerguide/01-NewIcingaCheck.md new file mode 100644 index 0000000..965ec62 --- /dev/null +++ b/doc/developerguide/01-NewIcingaCheck.md @@ -0,0 +1,140 @@ +# Developer Guide: New-IcingaCheck + +Below you will find a list of functions and detailed descriptions including use cases for Cmdlets and features the PowerShell Framework provides. + +| Type | Return Value | Description | +| --- | --- | --- | +| Cmdlet | PowerShell Object | Check Object containing values and handling warning / error states | + +The `IcingaCheck` is the basic start point for determining on how a certain value is performing. Checks will provide a bunch of internal commands within the PowerShell Object to analyse a value and get the Icinga result `Ok`, `Warning`, `Critical` including performance metrics. + +Checks are always used wihtin Check Plugins to have a standardised method for properly handling the input. + +It will be used like in this example: + +```powershell +$IcingaCheck = New-IcingaCheck -Name 'My Check' -Value 25 -Unit '%'; +``` + +You will have to provide a `Name` for each check which **must** be unique within each Check Plugin. This will make it easier to differentiate between checks for results. The `Value` is mandatory as this will be the base for each single check to fetch the actual status. + +For performance metrics you can provide a `Unit` to ensure your graphing is displaying values as the should be + +## Arguments + +| Argument | Input | Mandatory | Description | +| --- | --- | --- | --- | +| Name | String | * | The unique name of each check within a plugin. Will be display in the check output. | +| Value | Object | * | The value all comparison is done with. In general this should be a `Numeric` or `String` value | +| Unit | Units | | Specify the unit for a value to display graph properly | +| Minimum | String | | The minimum value which is displayed on your graphs | +| Maximum | String | | The maximum value which is displayed on your graphs | +| ObjectExists | Bool | | If you are using values coming from objects, like Services, you can use this argument to determin if the object itself exist or not. In case it doesn't, you will receive a proper output on the check result | +| Translation | Hashtable | | In case you want to map values to certain descriptions, you can place a hashtable at this argument which will then map the value to the description on the check result. For example this would apply to service running states | +| NoPerfData | Switch | | Disables Performance Data output for this check object | + +## Units + +| Unit | Name | Description | +| --- | --- | --- | +| % | Percentage | The input value is a percentual value | +| s | Seconds | The input is indicated as time seconds | +| ms | Milliseconds | The input is indicated as time in milliseconds | +| us | Microseconds | The input is indicated as time in microseconds | +| B | Bytes | The input is indicated as quantity in bytes | +| KB | Kilobytes | The input is indicated as quantity in kilobytes | +| MB | Megabytes | The input is indicated as quantity in megabytes | +| TB | Terabytes | The input is indicated as quantity in terabytes | +| c | Counter | A continues counter increasing values over time | + +## Object Functions + +The `New-IcingaCheck` Cmdlet will return a custom PowerShell object which provides a bunch of functions to easier manage the handling of the output. + +Please note that most of the listed functions below will return itself as object, which means you will have to drop the content with `| Out-Null` after calling them. + +### Wrong + +```powershell +$IcingaCheck.WarnOutOfRange(10) +``` + +### Correct + +```powershell +$IcingaCheck.WarnOutOfRange(10) | Out-Null +``` + +### Nested functions + +An example for a nested function call could be this + +```powershell +$IcingaCheck.WarnOutOfRange(10).CritOutOfRange(20) | Out-Null +``` + +### Functions + +For most parts it is recommended to use the `OutOfRange` functions for `warning` and `critical` checks as the user is able to dynamicly set the range with the arguments of the plugins. For string values the `Like` and `Match` functions should be used. + +#### Recommended functions + +| Function | Parameters | Description | Example | +| --- | --- | --- | --- | +| WarnOutOfRange | Warning | This will make use of the Icinga Threshhold handling, like `10`, `~:10`, `@10:20` and properly return the correct ok / warning state of the plugin | $IcingaCheck.WarnOutOfRange(10) | Out-Null | +| CritOutOfRange | Critial | This will make use of the Icinga Threshhold handling, like `10`, `~:10`, `@10:20` and properly return the correct ok / critical state of the plugin | $IcingaCheck.CritOutOfRange(10) | Out-Null | +| WarnIfLike | Warning | Will return warning in case the input is `like` the value | $IcingaCheck.WarnIfLike('\*running\*') | +| WarnIfNotLike | Warning | Will return warning in case the input is `not like` the value | $IcingaCheck.WarnIfNotLike('\*running\*') | +| WarnIfMatch | Warning | Will return warning in case the input is `matching` the value | $IcingaCheck.WarnIfMatch('running') | +| WarnIfNotMatch | Warning | Will return warning in case the input is `not matching` the value | $IcingaCheck.WarnIfNotMatch('running') | +| CritIfLike | Critial | Will return critical in case the input is `like` the value | $IcingaCheck.CritIfLike('\*running\*') | +| CritIfNotLike | Critial | Will return critical in case the input is `not like` the value | $IcingaCheck.CritIfNotLike('\*running\*') | +| CritIfMatch | Critial | Will return critical in case the input is `matching` the value | $IcingaCheck.CritIfMatch('running') | +| CritIfNotMatch | Critial | Will return critical in case the input is `not matching` the value | $IcingaCheck.CritIfNotMatch('running') | + +#### All other functions + +| Function | Parameters | Description | Example | +| --- | --- | --- | --- | +| WarnIfBetweenAndEqual | Min, Max | Will return warning in case the input is `between or equal` the `min` and `max` value | $IcingaCheck.WarnIfBetweenAndEqual(10, 20) | +| WarnIfBetween | Min, Max | Will return warning in case the input is between the `min` and `max` value | $IcingaCheck.WarnIfBetween(10, 20) | +| WarnIfLowerThan | Warning | Will return warning in case the input is `lower` than the value | $IcingaCheck.WarnIfLowerThan(10) | +| WarnIfLowerEqualThan | Warning | Will return warning in case the input is `lower or equal` than the value | $IcingaCheck.WarnIfLowerEqualThan(10) | +| WarnIfGreaterThan | Warning | Will return warning in case the input is `greater` than the value | $IcingaCheck.WarnIfGreaterThan(10) | +| WarnIfGreaterEqualThan | Warning | Will return warning in case the input is `greater or equal` than the value | $IcingaCheck.WarnIfGreaterEqualThan(10) | +| CritIfBetweenAndEqual | Min, Max | Will return critical in case the input is `between or equal` the `min` and `max` value | $IcingaCheck.CritIfBetweenAndEqual(10, 20) | +| CritIfBetween | Min, Max | Will return critical in case the input is between the `min` and `max` value | $IcingaCheck.CritIfBetween(10, 20) | +| CritIfLowerThan | Critial | Will return critical in case the input is `lower` than the value | $IcingaCheck.CritIfLowerThan(10) | +| CritIfLowerEqualThan | Critial | Will return critical in case the input is `lower or equal` than the value | $IcingaCheck.CritIfLowerEqualThan(10) | +| CritIfGreaterThan | Critial | Will return critical in case the input is `greater` than the value | $IcingaCheck.CritIfGreaterThan(10) | +| CritIfGreaterEqualThan | Critial | Will return critical in case the input is `greater or equal` than the value | $IcingaCheck.CritIfGreaterEqualThan(10) | + +### Examples + +#### Example 1 + +Simple check item which will return `critical` as the value is `37` and we want throw `warning` above `20` and `critical` above `35` + +```powershell +$IcingaCheck = New-IcingaCheck -Name 'My Check' -Value 37 -Unit '%'; +$IcingaCheck.WarnOutOfRange(20).CritOutOfRange(35) | Out-Null; +``` + +#### Example 2 + +Check item with `ObjectExists` argument including `Translation`. As the input status `4` is an integer, we will convert the status to the string value `Running` and use the `Translation` argument to properly print the output in human readable strings + +```powershell +$Service = Get-IcingaServices -Service 'icinga2'; +$ConvertedStatus = ConvertTo-ServiceStatusCode -Status 4; +$StatusRaw = $Service.Values.configuration.Status.raw; + +$IcingaCheck = New-IcingaCheck -Name 'Icinga 2 Service' -Value $StatusRaw -ObjectExists $Service -Translation $ProviderEnums.ServiceStatusName; +$IcingaCheck.CritIfNotMatch($ConvertedStatus) | Out-Null; +``` + +Output after parsed into `New-IcingaCheckResult` + +```text +[CRITICAL]: Icinga 2 Service Stopped is not matching Running +``` diff --git a/doc/icingaintegration/01-DirectorBaskets.md b/doc/icingaintegration/01-DirectorBaskets.md new file mode 100644 index 0000000..88ff689 --- /dev/null +++ b/doc/icingaintegration/01-DirectorBaskets.md @@ -0,0 +1,44 @@ +Icinga Basket Generator +=== + +To make the integration as easy as possible, the Framework is shipping with an Icinga Director Basket configuration generator. Each Check-Plugin available within the Framework is able to auto-generate a basket config which can later be imported into the Icinga Director + +Generating Baskets +--- + +To automaticly generate the Basket configuration, open a PowerShell terminal and type in + +```powershell +Use-Icinga +``` + +to load the framework Cmdlets. + +Afterwards use the command + +```powershell +Get-IcingaCheckCommandConfig +``` + +to automatically generate the configuration for all Check-Commands. + +If you wish to specify specific commands only, you can filter them as well: + +```powershell +Get-IcingaCheckCommandConfig -CheckName Invoke-IcingaCheckBiosSerial, Invoke-IcingaCheckCPU +``` + +Last but not least you can output the JSON-Basket directly into a file. To do this, simply use the `OutFile` argument. You only require to specify a directory here, as the file including a timestamp is generated by the Cmdlet itself + +```powershell +Get-IcingaCheckCommandConfig -OutFile 'C:\Users\myuser\Documents\ +``` + +Once the file is exported, you can navigate to your Icinga Director Basket menu and import the generated file. Afterwards all specified Check-Commands are available and ready to use + +Developer Note +--- + +The generated Basket configuration will benefit from a detailed documentation of the module and each single argument. Descriptions for arguments are parsed into the Director description field, informing users of what the argument actually does. Furthermore arguments are automaticly mapped to certain object types. A `switch` argument for example will always be rendered with a `yes/no` drop-down-field, while arguments with a fixed set of input types like `Running`, `Stopped`, and so on for services is rendered within a fixed custom list. + +This will increase the entire usability of the module and prevent you from having to document the a plugin multiple times. diff --git a/doc/12-Icinga2AgentExample.md b/doc/icingaintegration/02-Icinga2AgentExample.md similarity index 100% rename from doc/12-Icinga2AgentExample.md rename to doc/icingaintegration/02-Icinga2AgentExample.md diff --git a/doc/installation/01-KickstartScript.md b/doc/installation/01-KickstartScript.md new file mode 100644 index 0000000..7c76ec5 --- /dev/null +++ b/doc/installation/01-KickstartScript.md @@ -0,0 +1,30 @@ +Install the framework with the Kickstart Script +=== + +The easiest way to install the framework is by using the Kickstart Script provided from [this repository](https://github.com/LordHepipud/icinga-framework-kickstart). + +The code provided there will ask questions on where to install the framework and where the framework files are provided from. The code below is a straight copy of the initial required code-block. Simply open a PowerShell instance as administrator and copy the following code block into it: + +Getting Started +--- + +```powershell +[Net.ServicePointManager]::SecurityProtocol = "tls12, tls11"; +$ProgressPreference = "SilentlyContinue"; + +$Script = (Invoke-WebRequest -UseBasicParsing -Uri 'https://raw.githubusercontent.com/LordHepipud/icinga-framework-kickstart/master/script/icinga-framework-kickstart.ps1').Content; + +Invoke-Command -ScriptBlock ([Scriptblock]::Create($Script)); +``` + +What this block will do is to download the PowerShell Script from the repository, add it into a ScriptBlock to allow execution and finally execute it. + +The ServicePointManager part will ensure communication is possible to GitHub for example, as by default PowerShell will be unable to open a secure connection otherwise. +Last but not least we will set the progress preference to `SilentlyContinue`, ensuring the PowerShell progress bar will not slow down our installation. + +Next Steps +--- + +Once the above step is completed, simply follow the instructions and answer the questions the wizard will ask you. Once the framework is installed, the wizard will ask you if you wish to continue with the Agent installation wizard. + +The entire purpose is to offer a fluent and seamless installation experience. diff --git a/doc/installation/02-ManualInstallation.md b/doc/installation/02-ManualInstallation.md new file mode 100644 index 0000000..8515229 --- /dev/null +++ b/doc/installation/02-ManualInstallation.md @@ -0,0 +1,44 @@ +Install the framework manually +=== + +To install the module manually we will at first fetch information on where we can actually install the module into. PowerShell provides some default directories, which can however also extended manually. + +Getting Started +--- + +To do this, we can run the following command within PowerShell + +```powershell +echo $env:PSModulePath +``` + +***We do recommend to use the Program Files folder (in case it's present) to install the module into, which will make the installation as service easier*** + +To be able to use the module, you will require to have named the folder **exactly** as the .psm1 and .psd1 files inside the repository. + +Example folder path: + +```powershell +C:\Program Files\WindowsPowerShell\Modules\icinga-module-windows +``` + +To validate if the module is installed properly, you can start a **new** PowerShell instance and type the following command + +```powershell +Get-Module -ListAvailable -Name icinga-module-windows +``` + +If you receive an output stating that the module is installed, you are fine to continue. + +Execution Policies and File Blocking +--- + +In order to be able to run the module on certain Windows Hosts, it might be required to either update the execution policies and/or unblock the module script files. + +The prefered way is to simply unblock the script files, allowing them to be executed on the system. This can be done by running a PowerShell instance as **Administrator** and enter the following command (we assume the module is installed at `C:\Program Files\WindowsPowershell\Modules\icinga-module-windows`. If not, please modify the command with the correct location) + +```powershell +Get-ChildItem -Path 'C:\Program Files\WindowsPowershell\Modules\icinga-module-windows' -Recurse | Unblock-File +``` + +Once done, please try again if you are now able to run the module on your host. If you are still not able to run the module and/or its scripts, please have a look on the Microsoft documentation for the [Set-Execution-Policy](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-6) Cmdlet to modify the Execution Policy for running PowerShell modules on your host, matching your internal guidelines. From 3379a30648bf0985412c977b481be9ed149c79ff Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 21 Oct 2019 15:21:21 +0200 Subject: [PATCH 158/259] Fixes links in install documentation --- doc/02-Installation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/02-Installation.md b/doc/02-Installation.md index 45deccc..39657aa 100644 --- a/doc/02-Installation.md +++ b/doc/02-Installation.md @@ -6,8 +6,8 @@ Installing the module is managed by differen ways, depending on the user environ Instructions --- -* Install the Module with the [Kickstart Script](installation\01-KickstartScript.md) -* Install the module [manually](installation\02-ManualInstallation.md) +* Install the Module with the [Kickstart Script](installation/01-KickstartScript.md) +* Install the module [manually](installation/02-ManualInstallation.md) Testing the installation --- From a3d112056e006d5db5746c3d836c6faf7550d9d6 Mon Sep 17 00:00:00 2001 From: Michael Friedrich Date: Tue, 22 Oct 2019 10:02:23 +0200 Subject: [PATCH 159/259] Typos & wordings in IcingaIntegration docs --- doc/05-IcingaIntegration.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/doc/05-IcingaIntegration.md b/doc/05-IcingaIntegration.md index d6231b3..1015674 100644 --- a/doc/05-IcingaIntegration.md +++ b/doc/05-IcingaIntegration.md @@ -1,20 +1,20 @@ Icinga Integration === -Once you followed the [Installation Guide](02-Installation.md) you are ready to start the integration into Icinga 2. This will allow you to configure your Check-Commands and start using configuring service-templates and services. +Once you followed the [Installation Guide](02-Installation.md) you are ready to start the integration into Icinga 2. This will allow you to configure your Check-Commands and start using them inside service templates and services. -Before you are getting started, be aware that you will always have to use +Before you get started, be aware that you always have to use ```powershell Use-Icinga ``` -before you are executing framework related Cmdlets and functions. Otherwise you might run into errors. +before you can execute framework related Cmdlets and functions. Otherwise you might run into errors. Configuring Check-Commands --- -To get started, there are two ways for getting all Check-Commands configured. +To get started, there are two ways to configure check command objects: -* [Automated coniguration](icingaintegration/01-DirectorBaskets.md) with Baskets -* [Manual configuration](icingaintegration/02-Icinga2AgentExample.md) of Check-Commands +* [Automated configuration](icingaintegration/01-DirectorBaskets.md) with Baskets +* [Manual configuration](icingaintegration/02-Icinga2AgentExample.md) of check commands From 47417223f979723f1e0db723447f3996b473f418 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 22 Oct 2019 19:19:57 +0200 Subject: [PATCH 160/259] Add support to test for available functions --- lib/core/tools/Test-IcingaFunction.psm1 | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) create mode 100644 lib/core/tools/Test-IcingaFunction.psm1 diff --git a/lib/core/tools/Test-IcingaFunction.psm1 b/lib/core/tools/Test-IcingaFunction.psm1 new file mode 100644 index 0000000..9de4777 --- /dev/null +++ b/lib/core/tools/Test-IcingaFunction.psm1 @@ -0,0 +1,16 @@ +function Test-IcingaFunction() +{ + param( + [string]$Name + ); + + if ([string]::IsNullOrEmpty($Name)) { + return $FALSE; + } + + if (Get-Command $Name -ErrorAction SilentlyContinue) { + return $TRUE; + } + + return $FALSE; +} From 0839c1e2e57e29e3056fa3532ed7e42634353e66 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 22 Oct 2019 19:53:50 +0200 Subject: [PATCH 161/259] Add support for dynamic background daemon loading --- lib/daemon/Get-IcingaBackgroundDaemons.psm1 | 22 +++++++++++++++++++ .../Register-IcingaBackgroundDaemon.psm1 | 22 +++++++++++++++++++ lib/daemon/Start-IcingaPowerShellDaemon.psm1 | 12 ++++++++-- .../Unregister-IcingaBackgroundDaemon.psm1 | 17 ++++++++++++++ 4 files changed, 71 insertions(+), 2 deletions(-) create mode 100644 lib/daemon/Get-IcingaBackgroundDaemons.psm1 create mode 100644 lib/daemon/Register-IcingaBackgroundDaemon.psm1 create mode 100644 lib/daemon/Unregister-IcingaBackgroundDaemon.psm1 diff --git a/lib/daemon/Get-IcingaBackgroundDaemons.psm1 b/lib/daemon/Get-IcingaBackgroundDaemons.psm1 new file mode 100644 index 0000000..fc6c152 --- /dev/null +++ b/lib/daemon/Get-IcingaBackgroundDaemons.psm1 @@ -0,0 +1,22 @@ +function Get-IcingaBackgroundDaemons() +{ + $Daemons = Get-IcingaPowerShellConfig -Path 'BackgroundDaemon.EnabledDaemons'; + + if ($null -eq $Daemons) { + return $null; + } + + [hashtable]$Output = @{}; + + foreach ($daemon in $Daemons.PSObject.Properties) { + $Arguments = @{}; + + foreach ($argument in $daemon.Value.Arguments.PSObject.Properties) { + $Arguments.Add($argument.Name, $argument.Value); + } + + $Output.Add($daemon.Name, $Arguments); + } + + return $Output; +} diff --git a/lib/daemon/Register-IcingaBackgroundDaemon.psm1 b/lib/daemon/Register-IcingaBackgroundDaemon.psm1 new file mode 100644 index 0000000..83aa6b7 --- /dev/null +++ b/lib/daemon/Register-IcingaBackgroundDaemon.psm1 @@ -0,0 +1,22 @@ +function Register-IcingaBackgroundDaemon() +{ + param( + [string]$Command, + [hashtable]$Arguments + ); + + if ([string]::IsNullOrEmpty($Command)) { + throw 'Please specify a Cmdlet to run as Background Daemon'; + } + + if (-Not (Test-IcingaFunction $Command)) { + throw ([string]::Format('The Cmdlet "{0}" is not available in your session. Please restart the session and try again or verify your input', $Command)); + } + + $Path = [string]::Format('BackgroundDaemon.EnabledDaemons.{0}', $Command); + + Set-IcingaPowerShellConfig -Path ([string]::Format('{0}.Command', $Path)) -Value $Command; + Set-IcingaPowerShellConfig -Path ([string]::Format('{0}.Arguments', $Path)) -Value $Arguments; + + Write-Host ([string]::Format('Background daemon Cmdlet "{0}" has been configured', $Command)); +} diff --git a/lib/daemon/Start-IcingaPowerShellDaemon.psm1 b/lib/daemon/Start-IcingaPowerShellDaemon.psm1 index fa8951d..4fe858c 100644 --- a/lib/daemon/Start-IcingaPowerShellDaemon.psm1 +++ b/lib/daemon/Start-IcingaPowerShellDaemon.psm1 @@ -6,8 +6,16 @@ function Start-IcingaPowerShellDaemon() Use-Icinga -LibOnly -Daemon; try { - # Todo: Add dynamic loading of enabled background tasks - Start-IcingaServiceCheckDaemon; + $EnabledDaemons = Get-IcingaBackgroundDaemons; + + foreach ($daemon in $EnabledDaemons.Keys) { + if (-Not (Test-IcingaFunction $daemon)) { + continue; + } + + $daemonArgs = $EnabledDaemons[$daemon]; + &$daemon @daemonArgs; + } } catch { # Todo: Add exception handling } diff --git a/lib/daemon/Unregister-IcingaBackgroundDaemon.psm1 b/lib/daemon/Unregister-IcingaBackgroundDaemon.psm1 new file mode 100644 index 0000000..a836b11 --- /dev/null +++ b/lib/daemon/Unregister-IcingaBackgroundDaemon.psm1 @@ -0,0 +1,17 @@ +function Unregister-IcingaBackgroundDaemon() +{ + param( + [string]$BackgroundDaemon, + [hashtable]$Arguments + ); + + if ([string]::IsNullOrEmpty($BackgroundDaemon)) { + throw 'Please specify a Cmdlet to remove from running as Background Daemon'; + } + + $Path = [string]::Format('BackgroundDaemon.EnabledDaemons.{0}', $BackgroundDaemon); + + Remove-IcingaPowerShellConfig -Path $Path; + + Write-Host 'Background daemon has been removed'; +} From 4f1127639c8869ba51b0c31de8b38302aeb4361b Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 22 Oct 2019 19:57:01 +0200 Subject: [PATCH 162/259] Move service check daemon to proper location --- .../ServiceCheckDaemon}/Get-IcingaRegisteredServiceChecks.psm1 | 0 .../ServiceCheckDaemon}/Register-IcingaServiceCheck.psm1 | 0 .../Set-IcingaRegisteredServiceCheckConfig.psm1 | 0 .../ServiceCheckDaemon}/Show-IcingaRegisteredServiceChecks.psm1 | 0 .../{ => ServiceCheckDaemon}/Start-IcingaServiceCheckDaemon.psm1 | 0 .../ServiceCheckDaemon}/Unregister-IcingaServiceCheck.psm1 | 0 6 files changed, 0 insertions(+), 0 deletions(-) rename lib/{daemon => daemons/ServiceCheckDaemon}/Get-IcingaRegisteredServiceChecks.psm1 (100%) rename lib/{daemon => daemons/ServiceCheckDaemon}/Register-IcingaServiceCheck.psm1 (100%) rename lib/{daemon => daemons/ServiceCheckDaemon}/Set-IcingaRegisteredServiceCheckConfig.psm1 (100%) rename lib/{daemon => daemons/ServiceCheckDaemon}/Show-IcingaRegisteredServiceChecks.psm1 (100%) rename lib/daemons/{ => ServiceCheckDaemon}/Start-IcingaServiceCheckDaemon.psm1 (100%) rename lib/{daemon => daemons/ServiceCheckDaemon}/Unregister-IcingaServiceCheck.psm1 (100%) diff --git a/lib/daemon/Get-IcingaRegisteredServiceChecks.psm1 b/lib/daemons/ServiceCheckDaemon/Get-IcingaRegisteredServiceChecks.psm1 similarity index 100% rename from lib/daemon/Get-IcingaRegisteredServiceChecks.psm1 rename to lib/daemons/ServiceCheckDaemon/Get-IcingaRegisteredServiceChecks.psm1 diff --git a/lib/daemon/Register-IcingaServiceCheck.psm1 b/lib/daemons/ServiceCheckDaemon/Register-IcingaServiceCheck.psm1 similarity index 100% rename from lib/daemon/Register-IcingaServiceCheck.psm1 rename to lib/daemons/ServiceCheckDaemon/Register-IcingaServiceCheck.psm1 diff --git a/lib/daemon/Set-IcingaRegisteredServiceCheckConfig.psm1 b/lib/daemons/ServiceCheckDaemon/Set-IcingaRegisteredServiceCheckConfig.psm1 similarity index 100% rename from lib/daemon/Set-IcingaRegisteredServiceCheckConfig.psm1 rename to lib/daemons/ServiceCheckDaemon/Set-IcingaRegisteredServiceCheckConfig.psm1 diff --git a/lib/daemon/Show-IcingaRegisteredServiceChecks.psm1 b/lib/daemons/ServiceCheckDaemon/Show-IcingaRegisteredServiceChecks.psm1 similarity index 100% rename from lib/daemon/Show-IcingaRegisteredServiceChecks.psm1 rename to lib/daemons/ServiceCheckDaemon/Show-IcingaRegisteredServiceChecks.psm1 diff --git a/lib/daemons/Start-IcingaServiceCheckDaemon.psm1 b/lib/daemons/ServiceCheckDaemon/Start-IcingaServiceCheckDaemon.psm1 similarity index 100% rename from lib/daemons/Start-IcingaServiceCheckDaemon.psm1 rename to lib/daemons/ServiceCheckDaemon/Start-IcingaServiceCheckDaemon.psm1 diff --git a/lib/daemon/Unregister-IcingaServiceCheck.psm1 b/lib/daemons/ServiceCheckDaemon/Unregister-IcingaServiceCheck.psm1 similarity index 100% rename from lib/daemon/Unregister-IcingaServiceCheck.psm1 rename to lib/daemons/ServiceCheckDaemon/Unregister-IcingaServiceCheck.psm1 From 18c060cc4da1b2b5ff3c91362dbc7327fc216e7e Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 22 Oct 2019 20:05:43 +0200 Subject: [PATCH 163/259] Add tool function to close and flush TCP connections --- lib/core/tools/Close-IcingaTcpConnection.psm1 | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 lib/core/tools/Close-IcingaTcpConnection.psm1 diff --git a/lib/core/tools/Close-IcingaTcpConnection.psm1 b/lib/core/tools/Close-IcingaTcpConnection.psm1 new file mode 100644 index 0000000..65b532a --- /dev/null +++ b/lib/core/tools/Close-IcingaTcpConnection.psm1 @@ -0,0 +1,14 @@ +function Close-IcingaTcpConnection() +{ + param( + $TcpClient + ); + + if ($null -eq $TcpClient) { + return; + } + + $TcpClient.Close(); + $TcpClient.Dispose(); + $TcpClient = $null; +} From 29d83aaf7f2ce7bb5cedec411d64e1dd79e401ca Mon Sep 17 00:00:00 2001 From: Crited Date: Mon, 28 Oct 2019 16:10:27 +0100 Subject: [PATCH 164/259] Added Docs, Added IcingaCheckDirectory, Fixed Uptime --- lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 | 19 ++++ lib/plugins/Invoke-IcingaCheckCPU.psm1 | 37 ++++++- lib/plugins/Invoke-IcingaCheckDirectory.psm1 | 98 +++++++++++++++++++ .../Invoke-IcingaCheckProcessCount.psm1 | 40 +++++++- lib/plugins/Invoke-IcingaCheckService.psm1 | 10 -- lib/plugins/Invoke-IcingaCheckUpdates.psm1 | 32 +++++- lib/plugins/Invoke-IcingaCheckUptime.psm1 | 34 ++++++- .../Invoke-IcingaCheckUsedPartitionSpace.psm1 | 45 ++++++++- lib/plugins/Invoke-IcingaCheckUsers.psm1 | 36 ++++++- 9 files changed, 329 insertions(+), 22 deletions(-) create mode 100644 lib/plugins/Invoke-IcingaCheckDirectory.psm1 diff --git a/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 b/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 index 8f71fb7..14793f0 100644 --- a/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 +++ b/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 @@ -1,5 +1,24 @@ Import-IcingaLib provider\bios; +<# +.SYNOPSIS + Finds out the Bios Serial +.DESCRIPTION + Invoke-IcingaCheckBiosSerial returns either the Bios Serial or nothing. + More Information on https://github.com/LordHepipud/icinga-module-windows +.FUNCTIONALITY + This module is intended to be used to find out the Bios Serial of a given system + Either the a Bios Serial is returned or not. Thereby the Check is always okay. +.EXAMPLE + PS>Invoke-IcingaCheckBiosSerial + [OK]: SerialNumber is 1234-5678-9101-1121-3141-5161-7100 +.OUTPUTS + System.String +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> + function Invoke-IcingaCheckBiosSerial() { $Bios = Get-IcingaBiosSerialNumber; diff --git a/lib/plugins/Invoke-IcingaCheckCPU.psm1 b/lib/plugins/Invoke-IcingaCheckCPU.psm1 index da6fc66..194dafc 100644 --- a/lib/plugins/Invoke-IcingaCheckCPU.psm1 +++ b/lib/plugins/Invoke-IcingaCheckCPU.psm1 @@ -2,11 +2,44 @@ Import-IcingaLib core\perfcounter; Import-IcingaLib core\tools; Import-IcingaLib icinga\plugin; +<# +.SYNOPSIS + Checks cpu usage of cores. +.DESCRIPTION + Invoke-IcingaCheckCPU returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. + e.g A system has 4 cores, each running at 60% usage, WARNING is set to 50%, CRITICAL is set to 75%. In this case the check will return WARNING. + More Information on https://github.com/LordHepipud/icinga-module-windows +.FUNCTIONALITY + This module is intended to be used to check on the current cpu usage of a specified core. + Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. +.EXAMPLE + PS>Invoke-IcingaCheckCpu -Warning 50 -Critical 75 + [OK]: Check package "CPU Load" is [OK] + | 'Core #0'=4,588831%;50;75;0;100 'Core #1'=0,9411243%;50;75;0;100 'Core #2'=11,53223%;50;75;0;100 'Core #3'=4,073013%;50;75;0;100 +.EXAMPLE + PS>Invoke-IcingaCheckCpu -Warning 50 -Critical 75 -Core 1 + [OK]: Check package "CPU Load" is [OK] + | 'Core #1'=2,612651%;50;75;0;100 +.PARAMETER Warning + Used to specify a Warning threshold. In this case an integer value. +.PARAMETER Critical + Used to specify a Critical threshold. In this case an integer value. +.PARAMETER Core + Used to specify a single core to check on. +.INPUTS + System.String +.OUTPUTS + System.String +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> + function Invoke-IcingaCheckCPU() { param( - $Warning, - $Critical, + [int]$Warning, + [int]$Critical, $Core = '*', [switch]$NoPerfData, $Verbose diff --git a/lib/plugins/Invoke-IcingaCheckDirectory.psm1 b/lib/plugins/Invoke-IcingaCheckDirectory.psm1 new file mode 100644 index 0000000..bfcc104 --- /dev/null +++ b/lib/plugins/Invoke-IcingaCheckDirectory.psm1 @@ -0,0 +1,98 @@ +Import-IcingaLib provider\bios; + +<# +.SYNOPSIS + Checks how many files are in a directory. +.DESCRIPTION + Invoke-IcingaCheckDirectory returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. + e.g 'C:\Users\Icinga\Backup' contains 200 files, WARNING is set to 150, CRITICAL is set to 300. In this case the check will return CRITICAL + More Information on https://github.com/LordHepipud/icinga-module-windows +.FUNCTIONALITY + This module is intended to be used to check how many files and directories are within are specified path. + Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. +.EXAMPLE + PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -InvokeIcingaCheck_Int_Warning 20 -InvokeIcingaCheck_Int_Critical 30 -Verbose 3 + [OK]: Check package "C:\Users\Icinga\Downloads" is [OK] (Match All) + \_ [OK]: C:\Users\Icinga\Downloads is 19 +.EXAMPLE + PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -InvokeIcingaCheck_Int_Warning 20 -InvokeIcingaCheck_Int_Critical 30 -Verbose 3 + [WARNING]: Check package "C:\Users\Icinga\Downloads" is [WARNING] (Match All) + \_ [WARNING]: C:\Users\Icinga\Downloads is 24 +.EXAMPLE + PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -InvokeIcingaCheck_Int_Warning 20 -InvokeIcingaCheck_Int_Critical 30 -Verbose 3 -YoungerThen 08.10.2018 -OlderThen 10.12.2018 + [OK]: Check package "C:\Users\Icinga\Downloads" is [OK] (Match All) + \_ [OK]: C:\Users\Icinga\Downloads is 1 +.EXAMPLE + PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -FileNames "*.txt","*.sql" -InvokeIcingaCheck_Int_Warning 20 -InvokeIcingaCheck_Int_Critical 30 -Verbose 3 + [OK]: Check package "C:\Users\Icinga\Downloads" is [OK] (Match All) + \_ [OK]: C:\Users\Icinga\Downloads is 4 +.PARAMETER IcingaCheckDirectory_Int_Warning + Used to specify a Warning threshold. In this case an integer value. +.PARAMETER IcingaCheckDirectory_Int_Critical + Used to specify a Critical threshold. In this case an integer value. +.PARAMETER Path + Used to specify a path. + e.g. 'C:\Users\Icinga\Downloads' +.PARAMETER FileNames + Used to specify an array of filenames or expressions to match against. + + e.g '*.txt','.sql' # Fiends all files ending with .txt and .sql +.PARAMETER Recurse + A switch, which can be set to filter through directories recursively. +.PARAMETER YoungerThen + String that expects input format "MM.dd.yyyy". Used to only filter for files younger then the specified date. +.PARAMETER OlderThen + String that expects input format "MM.dd.yyyy". Used to only filter for files older then the specified date. +.INPUTS + System.String +.OUTPUTS + System.String +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> + +function Invoke-IcingaCheckDirectory() +{ + param( + [string]$Path, + [array]$FileNames, + [switch]$Recurse, + [int]$IcingaCheckDirectory_Int_Critical, + [int]$IcingaCheckDirectory_Int_Warning, + [string]$YoungerThen, + [string]$OlderThen, + [int]$Verbose + ); + + if ($Recurse -eq $TRUE) { + $FileCount = (Get-ChildItem -Include $FileNames -Recurse -Path $Path); + } else { + $FileCount = (Get-ChildItem -Include $FileNames -Path $Path); + } + + if ($OlderThen -ne "" -And $YoungerThen -ne "") { + $OlderThen=[datetime]::ParseExact($OlderThen,'MM.dd.yyyy',$null) + $YoungerThen=[datetime]::ParseExact($YoungerThen,'MM.dd.yyyy',$null) + $FileCount = ($FileCount | Where-Object {$_.LastWriteTime -lt ($OlderThen)}) #| Where-Object {$_LastWriteTime -gt ($YoungerThen)} + $FileCount = ($FileCount | Where-Object {$_.LastWriteTime -gt ($YoungerThen)}) + } elseif ($OlderThen -ne "") { + $OlderThen=[datetime]::ParseExact($OlderThen,'MM.dd.yyyy',$null) + $FileCount = ($FileCount | Where-Object {$_.LastWriteTime -lt ($OlderThen)}) + } elseif ($YoungerThen -ne "") { + $YoungerThen=[datetime]::ParseExact($YoungerThen,'MM.dd.yyyy',$null) + $FileCount = ($FileCount | Where-Object {$_.LastWriteTime -gt ($YoungerThen)}) + } + + $DirectoryCheck = New-IcingaCheck -Name $Path -Value $FileCount.Count -NoPerfData; + + $DirectoryCheck.WarnOutOfRange( + ($IcingaCheckDirectory_Int_Warning) + ).CritOutOfRange( + ($IcingaCheckDirectory_Int_Critical) + ) | Out-Null; + + $DirectoryPackage = New-IcingaCheckPackage -Name $Path -OperatorAnd -Checks $DirectoryCheck -Verbose $Verbose; + + return (New-IcingaCheckresult -Check $DirectoryPackage -NoPerfData $TRUE -Compile); +} \ No newline at end of file diff --git a/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 b/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 index fba2d26..37ff850 100644 --- a/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 +++ b/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 @@ -1,11 +1,47 @@ Import-IcingaLib provider\process; Import-IcingaLib icinga\plugin; +<# +.SYNOPSIS + Checks how many processes of a process exist. +.DESCRIPTION + Invoke-IcingaCheckDirectory returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. + e.g there are three conhost processes running, WARNING is set to 3, CRITICAL is set to 4. In this case the check will return WARNING. + More Information on https://github.com/LordHepipud/icinga-module-windows +.FUNCTIONALITY + This module is intended to be used to check how many processes of a process exist. + Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. +.EXAMPLE + PS>Invoke-IcingaCheckProcessCount -Process conhost -Warning 5 -Critical 10 + [OK]: Check package "Process Check" is [OK] + | 'Process Count "conhost"'=3;; +.EXAMPLE + PS>Invoke-IcingaCheckProcessCount -Process conhost,wininit -Warning 5 -Critical 10 -Verbose 4 + [OK]: Check package "Process Check" is [OK] (Match All) + \_ [OK]: Process Count "conhost" is 3 + \_ [OK]: Process Count "wininit" is 1 + | 'Process Count "conhost"'=3;5;10 'Process Count "wininit"'=1;5;10 +.PARAMETER Warning + Used to specify a Warning threshold. In this case an integer value. +.PARAMETER Critical + Used to specify a Critical threshold. In this case an integer value. +.PARAMETER Process + Used to specify an array of processes to count and match against. + e.g. conhost,wininit +.INPUTS + System.String +.OUTPUTS + System.String +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> + function Invoke-IcingaCheckProcessCount() { param( - $Warning, - $Critical, + [int]$Warning, + [int]$Critical, [array]$Process, [switch]$NoPerfData, $Verbose diff --git a/lib/plugins/Invoke-IcingaCheckService.psm1 b/lib/plugins/Invoke-IcingaCheckService.psm1 index 4c4fcd4..23f8b30 100644 --- a/lib/plugins/Invoke-IcingaCheckService.psm1 +++ b/lib/plugins/Invoke-IcingaCheckService.psm1 @@ -5,38 +5,28 @@ Import-IcingaLib icinga\plugin; <# .SYNOPSIS Checks if a service has a specified status. - .DESCRIPTION Invoke-icingaCheckService returns either 'OK' or 'CRITICAL', if a service status is matching status to be checked. - More Information on https://github.com/LordHepipud/icinga-module-windows - .FUNCTIONALITY This module is intended to be used to check whether one or more services have a certain status. As soon as one of the specified services does not match the status, the function returns 'CRITICAL' instead of 'OK'. - .EXAMPLE PS>Invoke-IcingaCheckService -Service WiaRPC, Spooler -Status '1' -Verbose 3 [CRITICAL]: Check package "Services" is [CRITICAL] (Match All) \_ [OK]: Service "Ereignisse zum Abrufen von Standbildern (WiaRPC)" is Stopped \_ [CRITICAL]: Service "Druckwarteschlange (Spooler)" Running is not matching Stopped - .PARAMETER Service Used to specify an array of services which should be checked against the status. Seperated with ',' - .PARAMETER Status Status for the specified service or services to check against. - .INPUTS System.Array - .OUTPUTS System.String - .LINK https://github.com/LordHepipud/icinga-module-windows - .NOTES #> diff --git a/lib/plugins/Invoke-IcingaCheckUpdates.psm1 b/lib/plugins/Invoke-IcingaCheckUpdates.psm1 index 50f1e0b..25e61f8 100644 --- a/lib/plugins/Invoke-IcingaCheckUpdates.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUpdates.psm1 @@ -1,12 +1,40 @@ Import-IcingaLib icinga\plugin; Import-IcingaLib provider\updates; +<# +.SYNOPSIS + Checks how many updates are to be applied +.DESCRIPTION + Invoke-IcingaCheckUpdates returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. + e.g 'C:\Users\Icinga\Backup' 10 updates are pending, WARNING is set to 20, CRITICAL is set to 50. In this case the check will return OK. + More Information on https://github.com/LordHepipud/icinga-module-windows +.FUNCTIONALITY + This module is intended to be used to check how many updates are to be applied and thereby currently pending + Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. + +.EXAMPLE + PS> Invoke-IcingaCheckUpdates -Warning 4 -Critical 20 + [OK]: Check package "Updates" is [OK] + | 'Pending Update Count'=2;4;20 +.PARAMETER Warning + Used to specify a Warning threshold. In this case an integer value. +.PARAMETER Critical + Used to specify a Critical threshold. In this case an integer value. +.INPUTS + System.String +.OUTPUTS + System.String +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> + function Invoke-IcingaCheckUpdates() { param ( [array]$UpdateFilter, - $Warning, - $Critical, + [int]$Warning, + [int]$Critical, [switch]$NoPerfData, [int]$Verbose ); diff --git a/lib/plugins/Invoke-IcingaCheckUptime.psm1 b/lib/plugins/Invoke-IcingaCheckUptime.psm1 index ace81c8..147c04a 100644 --- a/lib/plugins/Invoke-IcingaCheckUptime.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUptime.psm1 @@ -2,11 +2,41 @@ Import-IcingaLib icinga\plugin; Import-IcingaLib provider\windows; Import-IcingaLib core\tools; +<# +.SYNOPSIS + Checks how long a Windows system has been up for. +.DESCRIPTION + InvokeIcingaCheckUptime returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. + e.g 'C:\Users\Icinga\Backup' the system has been running for 10 days, WARNING is set to 15d, CRITICAL is set to 30d. In this case the check will return OK. + More Information on https://github.com/LordHepipud/icinga-module-windows +.FUNCTIONALITY + This module is intended to check how long a Windows system has been up for. + Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. + +.EXAMPLE + PS> Invoke-IcingaCheckUptime -Warning 18d -Critical 20d + [WARNING]: Check package "Windows Uptime: Days: 19 Hours: 13 Minutes: 48 Seconds: 29" is [WARNING] + | 'Windows Uptime'=1691309,539176s;1555200;1728000 +.PARAMETER IcingaCheckUsers_String_Warning + Used to specify a Warning threshold. In this case a string. + Allowed units include: ms, s, m, h, d, w, M, y +.PARAMETER IcingaCheckUsers_String_Critical + Used to specify a Critical threshold. In this case a string. + Allowed units include: ms, s, m, h, d, w, M, y +.INPUTS + System.String +.OUTPUTS + System.String +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> + function Invoke-IcingaCheckUptime() { param( - $Warning, - $Critical, + [string]$Warning, + [string]$Critical, [switch]$NoPerfData, [int]$Verbose ); diff --git a/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 b/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 index baed4c8..6d58b45 100644 --- a/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 @@ -1,11 +1,52 @@ Import-IcingaLib core\perfcounter; Import-IcingaLib icinga\plugin; +<# +.SYNOPSIS + Checks how much space on a partition is used. +.DESCRIPTION + Invoke-IcingaCheckUsedPartition returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. + e.g 'C:' is at 8% usage, WARNING is set to 60, CRITICAL is set to 80. In this case the check will return OK. + More Information on https://github.com/LordHepipud/icinga-module-windows +.FUNCTIONALITY + This module is intended to be used to check how much usage there is on an partition. + Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. +.EXAMPLE + PS>Invoke-IcingaCheckUsedPartitionSpace -Warning 60 -Critical 80 + [OK]: Check package "Used Partition Space" is [OK] + | 'Partition C'=8,06204986572266%;60;;0;100 'Partition D'=12,06204736572266%;60;;0;100 'Partition K'=19,062047896572266%;60;;0;100 +.EXAMPLE + PS>Invoke-IcingaCheckUsedPartitionSpace -Warning 60 -Critical 80 -Exclude "C:\" + [OK]: Check package "Used Partition Space" is [OK] + | 'Partition D'=12,06204736572266%;60;;0;100 'Partition K'=19,062047896572266%;60;;0;100 +.EXAMPLE + PS>Invoke-IcingaCheckUsedPartitionSpace -Warning 60 -Critical 80 -Include "C:\" + [OK]: Check package "Used Partition Space" is [OK] + | 'Partition C'=8,06204986572266%;60;;0;100 +.PARAMETER Warning + Used to specify a Warning threshold. In this case an integer value. +.PARAMETER Critical + Used to specify a Critical threshold. In this case an integer value. +.PARAMETER Exclude + Used to specify an array of partitions to be excluded. + e.g. 'C:\','D:\' +.PARAMETER Include + Used to specify an array of partitions to be included. + e.g. 'C:\','D:\' +.INPUTS + System.String +.OUTPUTS + System.String +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> + function Invoke-IcingaCheckUsedPartitionSpace() { param( - $Warning, - $Critical, + [int]$Warning, + [int]$Critical, [array]$Include = @(), [array]$Exclude = @(), [switch]$NoPerfData, diff --git a/lib/plugins/Invoke-IcingaCheckUsers.psm1 b/lib/plugins/Invoke-IcingaCheckUsers.psm1 index 370f9c9..d3e6de9 100644 --- a/lib/plugins/Invoke-IcingaCheckUsers.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUsers.psm1 @@ -1,12 +1,44 @@ Import-IcingaLib icinga\plugin; Import-IcingaLib provider\users; +<# +.SYNOPSIS + Checks how many files are in a directory. +.DESCRIPTION + Invoke-IcingaCheckDirectory returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. + e.g 'C:\Users\Icinga\Backup' contains 200 files, WARNING is set to 150, CRITICAL is set to 300. In this case the check will return CRITICAL + More Information on https://github.com/LordHepipud/icinga-module-windows +.FUNCTIONALITY + This module is intended to be used to check how many files and directories are within are specified path. + Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. + +.EXAMPLE + PS> +.EXAMPLE + PS> +.PARAMETER Warning + Used to specify a Warning threshold. In this case an integer value. +.PARAMETER Critical + Used to specify a Critical threshold. In this case an integer value. +.PARAMETER Username + Used to specify an array of usernames to match against. + + e.g 'Administrator', 'Icinga' +.INPUTS + System.String +.OUTPUTS + System.String +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> + function Invoke-IcingaCheckUsers() { param ( [array]$Username, - $Warning, - $Critical, + [int]$Warning, + [int]$Critical, [switch]$NoPerfData, [int]$Verbose ); From af236099ad7516ace2ea664c46d3815a99dc6973 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 28 Oct 2019 16:56:05 +0100 Subject: [PATCH 165/259] Add secure prompt to install Wizard --- .../misc/Start-IcingaAgentInstallWizard.psm1 | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index 9bb8200..7d7fe9e 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -280,7 +280,8 @@ function Get-IcingaAgentInstallerAnswerInput() param( $Prompt, [ValidateSet("y","n","v")] - $Default + $Default, + [switch]$Secure ); $DefaultAnswer = ''; @@ -291,10 +292,15 @@ function Get-IcingaAgentInstallerAnswerInput() $DefaultAnswer = ' (y/N)'; } - $answer = Read-Host -Prompt ([string]::Format('{0}{1}', $Prompt, $DefaultAnswer)); - $answer = $answer.ToLower(); + if (-Not $Secure) { + $answer = Read-Host -Prompt ([string]::Format('{0}{1}', $Prompt, $DefaultAnswer)); + } else { + $answer = Read-Host -Prompt ([string]::Format('{0}{1}', $Prompt, $DefaultAnswer)) -AsSecureString; + } if ($Default -ne 'v') { + $answer = $answer.ToLower(); + $returnValue = 0; if ([string]::IsNullOrEmpty($answer) -Or $answer -eq $Default) { $returnValue = 1; From 722d884a6b9578d364f402260264e83c59536456 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 28 Oct 2019 16:59:11 +0100 Subject: [PATCH 166/259] Update Start-IcingaAgentInstallWizard.psm1 --- .../misc/Start-IcingaAgentInstallWizard.psm1 | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index 7d7fe9e..0722083 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -22,7 +22,9 @@ function Start-IcingaAgentInstallWizard() [string]$Ticket, [string]$CAFile, [switch]$RunInstaller, - [switch]$Reconfigure + [switch]$Reconfigure, + [string]$ServiceUser, + [securestring]$ServicePass = $null ); [array]$InstallerArguments = @(); @@ -220,6 +222,25 @@ function Start-IcingaAgentInstallWizard() } } + if ([string]::IsNullOrEmpty($ServiceUser)) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to change the user the Icinga Agent service is running with (Default: "NT Authority\NetworkService")?' -Default 'n').result -eq 0) { + $ServiceUser = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the user you wish the Icinga Agent service to run with' -Default 'v').answer; + $InstallerArguments += "-ServiceUser $ServiceUser"; + if ($null -eq $ServicePass) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Does your Icinga Service user require a password to login (not required for System users)?' -Default 'y').result -eq 1) { + $ServicePass = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the password for your service user' -Secure -Default 'v').answer; + $InstallerArguments += "-ServicePass $ServicePass"; + } else { + $ServicePass = ''; + $InstallerArguments += "-ServicePass ''"; + } + } + } else { + $InstallerArguments += "-ServiceUser 'NT Authority\NetworkService'"; + $ServiceUser = 'NT Authority\NetworkService'; + } + } + if ($InstallerArguments.Count -ne 0) { $InstallerArguments += "-RunInstaller"; Write-Host 'The wizard is complete. These are the configured settings:'; @@ -242,6 +263,11 @@ function Start-IcingaAgentInstallWizard() if ($RunInstaller) { if ((Install-IcingaAgent -Version $AgentVersion -Source $PackageSource -AllowUpdates $AllowVersionChanges) -Or $Reconfigure) { Move-IcingaAgentDefaultConfig; + Set-IcingaAgentServiceUser -User $ServiceUser -Password $ServicePass; + Set-IcingaAgentServicePermission; + Set-IcingaAcl "$Env:ProgramData\icinga2\etc"; + Set-IcingaAcl "$Env:ProgramData\icinga2\var"; + Set-IcingaAcl (Get-IcingaCacheDir); Install-IcingaAgentBaseFeatures; Install-IcingaAgentCertificates -Hostname $Hostname -Endpoint $CAEndpoint -Port $CAPort -CACert $CAFile -Ticket $Ticket | Out-Null; Write-IcingaAgentApiConfig -Port $CAPort; From e7a2d041fe7399ffce5a450cc2134bbf133c5924 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 28 Oct 2019 17:03:19 +0100 Subject: [PATCH 167/259] Code cleanup --- icinga-module-windows.psm1 | 323 ++++++------------------------------- 1 file changed, 45 insertions(+), 278 deletions(-) diff --git a/icinga-module-windows.psm1 b/icinga-module-windows.psm1 index bc3850b..c50c163 100644 --- a/icinga-module-windows.psm1 +++ b/icinga-module-windows.psm1 @@ -101,6 +101,51 @@ function Import-IcingaLib() } } +function Publish-IcingaModuleManifests() +{ + param( + [string]$Module + ); + + [string]$ManifestDir = Join-Path -Path $PSScriptRoot -ChildPath 'manifests'; + [string]$ModuleFile = [string]::Format('{0}.psd1', $Module); + [string]$PSDFile = Join-Path -Path $ManifestDir -ChildPath $ModuleFile; + + if (Test-Path $PSDFile) { + return; + } + + New-ModuleManifest -path $PSDFile -ModuleVersion 1.0 -Author $env:USERNAME -CompanyName 'Icinga GmbH' -Copyright '(c) 2019 Icinga GmbH. All rights reserved.' -PowerShellVersion 4.0; + $Content = Get-Content $PSDFile; + $NewContent = @(); + + foreach ($line in $Content) { + if ([string]::IsNullOrEmpty($line)) { + continue; + } + + if ($line[0] -eq '#') { + continue; + } + + if ($line.Contains('#')) { + $line = $line.Substring(0, $line.IndexOf('#')); + } + + $tmpLine = $line; + while ($tmpLine.Contains(' ')) { + $tmpLine = $tmpLine.Replace(' ', ''); + } + if ([string]::IsNullOrEmpty($tmpLine)) { + continue; + } + + $NewContent += $line; + } + + Set-Content -Path $PSDFile -Value $NewContent; +} + function Get-IcingaPluginDir() { return (Join-Path -Path $PSScriptRoot -ChildPath 'lib\plugins\'); @@ -120,281 +165,3 @@ function Get-IcingaPowerShellConfigDir() { return (Join-Path -Path $PSScriptRoot -ChildPath 'config'); } - -function Install-Icinga() -{ - [string]$command = Get-Icinga-Command('setup'); - return &$command; -} - -function Get-Icinga-Setup() -{ - [string]$command = Get-Icinga-Command('setup'); - return &$command -IsAgentIntalled $TRUE; -} - -function Get-Icinga-Service() -{ - $Icinga2.Service.Status(); -} - -function Start-Icinga-Service() -{ - $Icinga2.Service.Start(); -} - -function Stop-Icinga-Service() -{ - $Icinga2.Service.Stop(); -} - -function Restart-Icinga-Service() -{ - $Icinga2.Service.Restart(); -} - -function Install-Icinga-Service() -{ - [CmdletBinding()] - param( - [string]$IcingaServicePath = '' - ) - $Icinga2.Service.Install($IcingaServicePath); -} - -function Uninstall-Icinga-Service() -{ - $Icinga2.Service.Uninstall(); -} - -function Start-Icinga-Daemon -{ - [CmdletBinding()] - param( - [Switch]$NoConsole = $FALSE - ); - - if ((Get-Icinga-Setup) -eq $FALSE) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - 'The agent seems to be not configured on this system. Please run "Install-Icinga" and try again.' - ); - return; - } - - if ($NoConsole) { - $Icinga2.Log.DisableConsole(); - } - - $Icinga2.TCPDaemon.Start(); -} - -function Stop-Icinga-Daemon() -{ - if ((Get-Icinga-Setup) -eq $FALSE) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - 'The agent seems to be not configured on this system. Please run "Install-Icinga" and try again.' - ); - return; - } - - $Icinga2.TCPDaemon.Stop(); -} - -function Start-Icinga-Checker -{ - [CmdletBinding()] - param( - [Switch]$NoConsole = $FALSE - ); - - if ((Get-Icinga-Setup) -eq $FALSE) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - 'The agent seems to be not configured on this system. Please run "Install-Icinga" and try again.' - ); - return; - } - - if ($NoConsole) { - $Icinga2.Log.DisableConsole(); - } - - $Icinga2.Checker.Start(); -} - -function Stop-Icinga-Checker -{ - if ((Get-Icinga-Setup) -eq $FALSE) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - 'The agent seems to be not configured on this system. Please run "Install-Icinga" and try again.' - ); - return; - } - - $Icinga2.Checker.Stop(); -} - -<# - # This function allows us to easily call core modules by simply - # providing the name of the module we want to load - #> -function Get-Icinga-Command() -{ - [CmdletBinding()] - param( - [string]$command = '' - ); - - [string]$command = [string]::Format('core\{0}.ps1', $command); - - return (Join-Path $PSScriptRoot -ChildPath $command); -} - -<# - # Execute checks based on a filter or execute all of them - #> -function New-Icinga-Monitoring() -{ - param( - [array]$Include = @(), - [array]$Exclude = @(), - [switch]$ListModules = $FALSE, - $Config = $null - ); - - if ((Get-Icinga-Setup) -eq $FALSE) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - 'The agent seems to be not configured on this system. Please run "Install-Icinga" and try again.' - ); - return; - } - - [string]$command = Get-Icinga-Command('monitoring'); - return &$command -Include $Include -Exclude $Exclude -ListModules $ListModules -Config $Config -AgentRoot $Icinga2.App.RootPath; -} - -<# - # Retreive Performance Counter from our Windows System - #> -function Get-Icinga-Counter() -{ - param( - # Allows to specify the full path of a counter to fetch data. Example '\Processor(*)\% Processor Time' - [string]$Counter = '', - # Allows to fetch all counters of a specific category, like 'Processor' - [string]$ListCounter = '', - # Provide an array of counters we check in a bulk '\Processor(*)\% Processor Time', '\Processor(*)\% c1 time'" - [array]$CounterArray = @(), - # List all available Performance Counter Categories on a system - [switch]$ListCategories = $FALSE, - # By default counters will wait globally for 500 milliseconds. With this we can skip it. Use with caution! - [switch]$SkipWait = $FALSE, - # These arguments apply to CreateStructuredPerformanceCounterTable - # This is the category name we want to create a structured output - # Example: 'Network Interface' - [string]$CreateStructuredOutputForCategory = '', - # This is the hashtable of Performance Counters, created by - # PerformanceCounterArray - [hashtable]$StructuredCounterInput = @{}, - # This argument is just a helper to replace certain strings within - # a instance name with simply nothing. - # Example: 'HarddiskVolume1' => '1' - [array]$StructuredCounterInstanceCleanup = @() - ); - - if ((Get-Icinga-Setup) -eq $FALSE) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - 'The agent seems to be not configured on this system. Please run "Install-Icinga" and try again.' - ); - return; - } - - [string]$command = Get-Icinga-Command('perfcounter'); - return (&$command ` - -Counter $Counter ` - -ListCounter $ListCounter ` - -CounterArray $CounterArray ` - -ListCategories $ListCategories ` - -SkipWait $SkipWait ` - -CreateStructuredOutputForCategory $CreateStructuredOutputForCategory ` - -StructuredCounterInput $StructuredCounterInput ` - -StructuredCounterInstanceCleanup $StructuredCounterInstanceCleanup - ); -} - -<# - # Get a single config key of Icinga 2 or the entire configuration - #> -function Get-Icinga-Config() -{ - param( - [string]$Key = '', - [switch]$ListConfig = $FALSE - ); - - [string]$command = Get-Icinga-Command('config'); - return &$command -GetConfig $Key -ListConfig $ListConfig; -} - -function Set-Icinga-Config() -{ - param( - [string]$Key = '', - [Object]$Value = '' - ); - - [string]$command = Get-Icinga-Command('config'); - return &$command -AddKey $Key -AddValue $Value; -} - -function Remove-Icinga-Config() -{ - param( - [string]$Key = '' - ); - - [string]$command = Get-Icinga-Command('config'); - return &$command -RemoveConfig $Key; -} - -function New-Icinga-Config() -{ - [string]$command = Get-Icinga-Command('config'); - return &$command -Reload $TRUE; -} - -function Get-Icinga-Lib() -{ - param([string]$Include); - - [string]$IncludeFile = (Join-Path $PSScriptRoot -ChildPath ( - [string]::Format( - '\core\include\{0}.ps1', - $Include - ))); - - if (-Not (Test-Path $IncludeFile)) { - return; - } - - return (& $IncludeFile); -} - -function Get-Icinga-Object() -{ - return $Icinga2; -} - -# Initialise base configuration for our module -<# -$Icinga2 = & (Join-Path -Path $PSScriptRoot -ChildPath '\core\init.ps1') ` - -RootDirectory $PSScriptRoot ` - -ModuleName $MyInvocation.MyCommand.Name; - -Export-ModuleMember @Icinga2; -#> \ No newline at end of file From ace1ecbee7408ef95e2d016daa5db23e191363df Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 28 Oct 2019 17:07:48 +0100 Subject: [PATCH 168/259] Fixes service user to point to local machine if not defined --- lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 b/lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 index 5940775..6779bf8 100644 --- a/lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 +++ b/lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 @@ -10,6 +10,10 @@ function Set-IcingaAgentServiceUser() return $FALSE; } + if ($User.Contains('\') -eq $FALSE) { + $User = [string]::Format('.\{0}', $User); + } + $ArgString = 'config icinga2 obj= "{0}" password="{1}"'; if($null -eq $Password) { $ArgString = 'config icinga2 obj= "{0}"{1}'; From a0b5efba19cc232cb00f703c4ff1596d62e3bdb4 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Mon, 28 Oct 2019 17:10:33 +0100 Subject: [PATCH 169/259] Separation of install wizard and answer input --- .../Get-IcingaAgentInstallerAnswerInput.psm1 | 44 +++++++++++++++++ .../misc/Start-IcingaAgentInstallWizard.psm1 | 47 ------------------- 2 files changed, 44 insertions(+), 47 deletions(-) create mode 100644 lib/core/icingaagent/getters/Get-IcingaAgentInstallerAnswerInput.psm1 diff --git a/lib/core/icingaagent/getters/Get-IcingaAgentInstallerAnswerInput.psm1 b/lib/core/icingaagent/getters/Get-IcingaAgentInstallerAnswerInput.psm1 new file mode 100644 index 0000000..9dfe228 --- /dev/null +++ b/lib/core/icingaagent/getters/Get-IcingaAgentInstallerAnswerInput.psm1 @@ -0,0 +1,44 @@ +function Get-IcingaAgentInstallerAnswerInput() +{ + param( + $Prompt, + [ValidateSet("y","n","v")] + $Default, + [switch]$Secure + ); + + $DefaultAnswer = ''; + + if ($Default -eq 'y') { + $DefaultAnswer = ' (Y/n)'; + } elseif ($Default -eq 'n') { + $DefaultAnswer = ' (y/N)'; + } + + if (-Not $Secure) { + $answer = Read-Host -Prompt ([string]::Format('{0}{1}', $Prompt, $DefaultAnswer)); + } else { + $answer = Read-Host -Prompt ([string]::Format('{0}{1}', $Prompt, $DefaultAnswer)) -AsSecureString; + } + + if ($Default -ne 'v') { + $answer = $answer.ToLower(); + + $returnValue = 0; + if ([string]::IsNullOrEmpty($answer) -Or $answer -eq $Default) { + $returnValue = 1; + } else { + $returnValue = 0; + } + + return @{ + 'result' = $returnValue; + 'answer' = ''; + } + } + + return @{ + 'result' = 2; + 'answer' = $answer; + } +} diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index 0722083..60a5551 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -300,50 +300,3 @@ function Get-IcingaAgentInstallCommand() return $Installer; } } - -function Get-IcingaAgentInstallerAnswerInput() -{ - param( - $Prompt, - [ValidateSet("y","n","v")] - $Default, - [switch]$Secure - ); - - $DefaultAnswer = ''; - - if ($Default -eq 'y') { - $DefaultAnswer = ' (Y/n)'; - } elseif ($Default -eq 'n') { - $DefaultAnswer = ' (y/N)'; - } - - if (-Not $Secure) { - $answer = Read-Host -Prompt ([string]::Format('{0}{1}', $Prompt, $DefaultAnswer)); - } else { - $answer = Read-Host -Prompt ([string]::Format('{0}{1}', $Prompt, $DefaultAnswer)) -AsSecureString; - } - - if ($Default -ne 'v') { - $answer = $answer.ToLower(); - - $returnValue = 0; - if ([string]::IsNullOrEmpty($answer) -Or $answer -eq $Default) { - $returnValue = 1; - } else { - $returnValue = 0; - } - - return @{ - 'result' = $returnValue; - 'answer' = ''; - } - } - - return @{ - 'result' = 2; - 'answer' = $answer; - } -} - -Export-ModuleMember -Function @( 'Start-IcingaAgentInstallWizard' ); From cfb6d9f5a00dbddbadc294ad480d4ecb3e47ff2f Mon Sep 17 00:00:00 2001 From: Crited Date: Tue, 29 Oct 2019 09:01:38 +0100 Subject: [PATCH 170/259] Add Set-NumericNegative Tool; Seperate Directory check into provider, change directory check from date to relative (20d) --- lib/core/tools/Set-NumericNegative.psm1 | 11 ++++ lib/plugins/Invoke-IcingaCheckDirectory.psm1 | 55 +++++++----------- .../directory/Icinga_Provider_Directory.psm1 | 57 +++++++++++++++++++ 3 files changed, 89 insertions(+), 34 deletions(-) create mode 100644 lib/core/tools/Set-NumericNegative.psm1 create mode 100644 lib/provider/directory/Icinga_Provider_Directory.psm1 diff --git a/lib/core/tools/Set-NumericNegative.psm1 b/lib/core/tools/Set-NumericNegative.psm1 new file mode 100644 index 0000000..394d72a --- /dev/null +++ b/lib/core/tools/Set-NumericNegative.psm1 @@ -0,0 +1,11 @@ + +function Set-NumericNegative() +{ + param( + $Value + ); + + $Value = $Value * -1; + + return $Value; +} \ No newline at end of file diff --git a/lib/plugins/Invoke-IcingaCheckDirectory.psm1 b/lib/plugins/Invoke-IcingaCheckDirectory.psm1 index bfcc104..7b0957e 100644 --- a/lib/plugins/Invoke-IcingaCheckDirectory.psm1 +++ b/lib/plugins/Invoke-IcingaCheckDirectory.psm1 @@ -1,4 +1,4 @@ -Import-IcingaLib provider\bios; +Import-IcingaLib provider\directory; <# .SYNOPSIS @@ -11,24 +11,24 @@ Import-IcingaLib provider\bios; This module is intended to be used to check how many files and directories are within are specified path. Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. .EXAMPLE - PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -InvokeIcingaCheck_Int_Warning 20 -InvokeIcingaCheck_Int_Critical 30 -Verbose 3 + PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -Warning 20 -Critical 30 -Verbose 3 [OK]: Check package "C:\Users\Icinga\Downloads" is [OK] (Match All) \_ [OK]: C:\Users\Icinga\Downloads is 19 .EXAMPLE - PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -InvokeIcingaCheck_Int_Warning 20 -InvokeIcingaCheck_Int_Critical 30 -Verbose 3 + PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -Warning 20 -Critical 30 -Verbose 3 [WARNING]: Check package "C:\Users\Icinga\Downloads" is [WARNING] (Match All) \_ [WARNING]: C:\Users\Icinga\Downloads is 24 .EXAMPLE - PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -InvokeIcingaCheck_Int_Warning 20 -InvokeIcingaCheck_Int_Critical 30 -Verbose 3 -YoungerThen 08.10.2018 -OlderThen 10.12.2018 + PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -Warning 20 -Critical 30 -Verbose 3 -YoungerThen 20d -OlderThen 10d [OK]: Check package "C:\Users\Icinga\Downloads" is [OK] (Match All) \_ [OK]: C:\Users\Icinga\Downloads is 1 .EXAMPLE - PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -FileNames "*.txt","*.sql" -InvokeIcingaCheck_Int_Warning 20 -InvokeIcingaCheck_Int_Critical 30 -Verbose 3 + PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -FileNames "*.txt","*.sql" -Warning 20 -Critical 30 -Verbose 3 [OK]: Check package "C:\Users\Icinga\Downloads" is [OK] (Match All) \_ [OK]: C:\Users\Icinga\Downloads is 4 -.PARAMETER IcingaCheckDirectory_Int_Warning +.PARAMETER Warning Used to specify a Warning threshold. In this case an integer value. -.PARAMETER IcingaCheckDirectory_Int_Critical +.PARAMETER Critical Used to specify a Critical threshold. In this case an integer value. .PARAMETER Path Used to specify a path. @@ -36,13 +36,17 @@ Import-IcingaLib provider\bios; .PARAMETER FileNames Used to specify an array of filenames or expressions to match against. - e.g '*.txt','.sql' # Fiends all files ending with .txt and .sql + e.g '*.txt', '*.sql' # Fiends all files ending with .txt and .sql .PARAMETER Recurse A switch, which can be set to filter through directories recursively. .PARAMETER YoungerThen - String that expects input format "MM.dd.yyyy". Used to only filter for files younger then the specified date. + String that expects input format like "20d", which translates to 20 days. Allowed units: ms, s, m, h, d, w, M, y. + + Thereby all files younger then 20 days are considered within the check .PARAMETER OlderThen - String that expects input format "MM.dd.yyyy". Used to only filter for files older then the specified date. + String that expects input format like "20d", which translates to 20 days. Allowed units: ms, s, m, h, d, w, M, y. + + Thereby all files older then 20 days are considered within the check .INPUTS System.String .OUTPUTS @@ -58,38 +62,21 @@ function Invoke-IcingaCheckDirectory() [string]$Path, [array]$FileNames, [switch]$Recurse, - [int]$IcingaCheckDirectory_Int_Critical, - [int]$IcingaCheckDirectory_Int_Warning, + [int]$Critical, + [int]$Warning, [string]$YoungerThen, [string]$OlderThen, [int]$Verbose ); - if ($Recurse -eq $TRUE) { - $FileCount = (Get-ChildItem -Include $FileNames -Recurse -Path $Path); - } else { - $FileCount = (Get-ChildItem -Include $FileNames -Path $Path); - } - - if ($OlderThen -ne "" -And $YoungerThen -ne "") { - $OlderThen=[datetime]::ParseExact($OlderThen,'MM.dd.yyyy',$null) - $YoungerThen=[datetime]::ParseExact($YoungerThen,'MM.dd.yyyy',$null) - $FileCount = ($FileCount | Where-Object {$_.LastWriteTime -lt ($OlderThen)}) #| Where-Object {$_LastWriteTime -gt ($YoungerThen)} - $FileCount = ($FileCount | Where-Object {$_.LastWriteTime -gt ($YoungerThen)}) - } elseif ($OlderThen -ne "") { - $OlderThen=[datetime]::ParseExact($OlderThen,'MM.dd.yyyy',$null) - $FileCount = ($FileCount | Where-Object {$_.LastWriteTime -lt ($OlderThen)}) - } elseif ($YoungerThen -ne "") { - $YoungerThen=[datetime]::ParseExact($YoungerThen,'MM.dd.yyyy',$null) - $FileCount = ($FileCount | Where-Object {$_.LastWriteTime -gt ($YoungerThen)}) - } - - $DirectoryCheck = New-IcingaCheck -Name $Path -Value $FileCount.Count -NoPerfData; + $DirectoryData = Get-IcingaDirectoryAll -Path $Path -FileNames $FileNames ` + -Recurse $Recurse -YoungerThen $YoungerThen -OlderThen $OlderThen; + $DirectoryCheck = New-IcingaCheck -Name $Path -Value $DirectoryData.Count -NoPerfData; $DirectoryCheck.WarnOutOfRange( - ($IcingaCheckDirectory_Int_Warning) + ($Warning) ).CritOutOfRange( - ($IcingaCheckDirectory_Int_Critical) + ($Critical) ) | Out-Null; $DirectoryPackage = New-IcingaCheckPackage -Name $Path -OperatorAnd -Checks $DirectoryCheck -Verbose $Verbose; diff --git a/lib/provider/directory/Icinga_Provider_Directory.psm1 b/lib/provider/directory/Icinga_Provider_Directory.psm1 new file mode 100644 index 0000000..efcfc31 --- /dev/null +++ b/lib/provider/directory/Icinga_Provider_Directory.psm1 @@ -0,0 +1,57 @@ +Import-IcingaLib core\tools; + +function Get-IcingaDirectoryAll() +{ + param( + [string]$Path, + [array]$FileNames, + [bool]$Recurse, + [string]$YoungerThen, + [string]$OlderThen, + ); + + if ($Recurse -eq $TRUE) { + $DirectoryData = Get-ChildItem -Recurse -Path $Path -Include $FileNames; + } else { + $DirectoryData = Get-ChildItem -Path $Path -Include $FileNames; + } + + if ([string]::IsNullOrEmpty($OlderThen) -eq $FALSE -And [string]::IsNullOrEmpty($YoungerThen) -eq $FALSE) { + $OlderThen = Set-NumericNegative (ConvertTo-Seconds $OlderThen); + $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -lt (Get-Date).AddSeconds($OlderThen)}) + $YoungerThen = Set-NumericNegative (ConvertTo-Seconds $YoungerThen); + $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -gt (Get-Date).AddSeconds($YoungerThen)}) + } elseif ([string]::IsNullOrEmpty($OlderThen) -eq $FALSE) { + $OlderThen = Set-NumericNegative (ConvertTo-Seconds $OlderThen); + $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -lt (Get-Date).AddSeconds($OlderThen)}) + } elseif ([string]::IsNullOrEmpty($YoungerThen) -eq $FALSE) { + $YoungerThen = Set-NumericNegative (ConvertTo-Seconds $YoungerThen); + $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -gt ((Get-Date).AddSeconds($YoungerThen))}) + } + + return $DirectoryData; +} + +function Get-IcingaDirectory() +{ + param( + [string]$Path, + [array]$FileNames + ); + + $DirectoryData = Get-ChildItem -Include $FileNames -Path $Path; + + return $DirectoryData; +} + +function Get-IcingaDirectoryRecurse() +{ + param( + [string]$Path, + [array]$FileNames + ); + + $DirectoryData = Get-ChildItem -Recurse -Include $FileNames -Path $Path; + + return $DirectoryData; +} \ No newline at end of file From 4e4c79d0dfa7bf9002d0ae4c4e91a6526732a994 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 29 Oct 2019 09:06:52 +0100 Subject: [PATCH 171/259] Fixes invalid , --- lib/provider/directory/Icinga_Provider_Directory.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/provider/directory/Icinga_Provider_Directory.psm1 b/lib/provider/directory/Icinga_Provider_Directory.psm1 index efcfc31..e4d187c 100644 --- a/lib/provider/directory/Icinga_Provider_Directory.psm1 +++ b/lib/provider/directory/Icinga_Provider_Directory.psm1 @@ -7,7 +7,7 @@ function Get-IcingaDirectoryAll() [array]$FileNames, [bool]$Recurse, [string]$YoungerThen, - [string]$OlderThen, + [string]$OlderThen ); if ($Recurse -eq $TRUE) { From de6328139f019f1d80c3716f27fa85c78fb67858 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 29 Oct 2019 09:08:44 +0100 Subject: [PATCH 172/259] Fixes filtering of 'core' plugin argument --- .../tools/Get-IcingaCheckCommandConfig.psm1 | 318 +++++++++--------- 1 file changed, 157 insertions(+), 161 deletions(-) diff --git a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 index bbfedcd..7542201 100644 --- a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 +++ b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 @@ -165,184 +165,180 @@ function Get-IcingaCheckCommandConfig() # Loop through parameters of a given command foreach ($parameter in $Data.parameters.parameter) { - # Filter for Parameter 'core', because its set by default - if ($parameter.name -ne 'core') { + # IsNumeric-Check on position to determine the order-value + If (Test-Numeric($parameter.position) -eq $TRUE) { + [string]$Order = [int]$parameter.position + 1; + } else { + [string]$Order = 99 + } - # IsNumeric-Check on position to determine the order-value - If (Test-Numeric($parameter.position) -eq $TRUE) { - [string]$Order = [int]$parameter.position + 1; - } else { - [string]$Order = 99 - } + $IcingaCustomVariable = [string]::Format('$PowerShell_{0}_{1}$', (Get-Culture).TextInfo.ToTitleCase($parameter.type.name), $parameter.Name); - $IcingaCustomVariable = [string]::Format('$PowerShell_{0}_{1}$', (Get-Culture).TextInfo.ToTitleCase($parameter.type.name), $parameter.Name); + # Todo: Should we improve this? Actually the handling would be identical, we just need to assign + # the proper field for this + if ($IcingaCustomVariable -eq '$PowerShell_Int32_Verbose$' -Or $IcingaCustomVariable -eq '$PowerShell_Int_Verbose$') { + $IcingaCustomVariable = '$PowerShell_Object_Verbose$'; + } - # Todo: Should we improve this? Actually the handling would be identical, we just need to assign - # the proper field for this - if ($IcingaCustomVariable -eq '$PowerShell_Int32_Verbose$' -Or $IcingaCustomVariable -eq '$PowerShell_Int_Verbose$') { - $IcingaCustomVariable = '$PowerShell_Object_Verbose$'; - } - - # Add arguments to a given command - if ($parameter.type.name -eq 'switch') { - $Basket.Command[$Data.Name].arguments.Add( - [string]::Format('-{0}', $parameter.Name), @{ - 'set_if' = $IcingaCustomVariable; - 'set_if_format' = 'string'; - 'order' = $Order; - } - ); - - $Basket.Command[$Data.Name].vars.Add($parameter.Name, $FALSE); - - # Conditional whether type of parameter is array - } elseif ($parameter.type.name -eq 'array') { - $Basket.Command[$Data.Name].arguments.Add( - [string]::Format('-{0}', $parameter.Name), @{ - 'value' = @{ - 'type' = 'Function'; - 'body' = [string]::Format( - 'var arr = macro("{0}");{1}if (len(arr) == 0) {2}{1}return "$null";{1}{3}{1}return arr.join(",");', - $IcingaCustomVariable, - "`r`n", - '{', - '}' - ); - } - 'order' = $Order; - } - ); - } else { - # Default to Object - $Basket.Command[$Data.Name].arguments.Add( - [string]::Format('-{0}', $parameter.Name), @{ - 'value' = $IcingaCustomVariable; - 'order' = $Order; - } - ); - - if ($parameter.name -ne 'Verbose') { - $Basket.Command[$Data.Name].vars.Add($parameter.Name, '$$null'); - } else { - $Basket.Command[$Data.Name].vars.Add($parameter.Name, "0"); + # Add arguments to a given command + if ($parameter.type.name -eq 'switch') { + $Basket.Command[$Data.Name].arguments.Add( + [string]::Format('-{0}', $parameter.Name), @{ + 'set_if' = $IcingaCustomVariable; + 'set_if_format' = 'string'; + 'order' = $Order; } - } + ); - # Determine wether a parameter is required based on given syntax-information - if ($parameter.required -eq $TRUE) { - $Required = 'y'; - } else { - $Required = 'n'; - } + $Basket.Command[$Data.Name].vars.Add($parameter.Name, $FALSE); - $IcingaCustomVariable = [string]::Format('PowerShell_{0}_{1}', (Get-Culture).TextInfo.ToTitleCase($parameter.type.name), $parameter.Name); - - # Todo: Should we improve this? Actually the handling would be identical, we just need to assign - # the proper field for this - if ($IcingaCustomVariable -eq 'PowerShell_Int32_Verbose' -Or $IcingaCustomVariable -eq 'PowerShell_Int_Verbose') { - $IcingaCustomVariable = 'PowerShell_Object_Verbose'; - } - - [bool]$ArgumentKnown = $FALSE; - - foreach ($argument in $Basket.Datafield.Keys) { - if ($Basket.Datafield[$argument].varname -eq $IcingaCustomVariable) { - $ArgumentKnown = $TRUE; - break; + # Conditional whether type of parameter is array + } elseif ($parameter.type.name -eq 'array') { + $Basket.Command[$Data.Name].arguments.Add( + [string]::Format('-{0}', $parameter.Name), @{ + 'value' = @{ + 'type' = 'Function'; + 'body' = [string]::Format( + 'var arr = macro("{0}");{1}if (len(arr) == 0) {2}{1}return "$null";{1}{3}{1}return arr.join(",");', + $IcingaCustomVariable, + "`r`n", + '{', + '}' + ); + } + 'order' = $Order; } + ); + } else { + # Default to Object + $Basket.Command[$Data.Name].arguments.Add( + [string]::Format('-{0}', $parameter.Name), @{ + 'value' = $IcingaCustomVariable; + 'order' = $Order; + } + ); + + if ($parameter.name -ne 'Verbose') { + $Basket.Command[$Data.Name].vars.Add($parameter.Name, '$$null'); + } else { + $Basket.Command[$Data.Name].vars.Add($parameter.Name, "0"); + } + } + + # Determine wether a parameter is required based on given syntax-information + if ($parameter.required -eq $TRUE) { + $Required = 'y'; + } else { + $Required = 'n'; + } + + $IcingaCustomVariable = [string]::Format('PowerShell_{0}_{1}', (Get-Culture).TextInfo.ToTitleCase($parameter.type.name), $parameter.Name); + + # Todo: Should we improve this? Actually the handling would be identical, we just need to assign + # the proper field for this + if ($IcingaCustomVariable -eq 'PowerShell_Int32_Verbose' -Or $IcingaCustomVariable -eq 'PowerShell_Int_Verbose') { + $IcingaCustomVariable = 'PowerShell_Object_Verbose'; + } + + [bool]$ArgumentKnown = $FALSE; + + foreach ($argument in $Basket.Datafield.Keys) { + if ($Basket.Datafield[$argument].varname -eq $IcingaCustomVariable) { + $ArgumentKnown = $TRUE; + break; + } + } + + if ($ArgumentKnown) { + continue; + } + + $DataListName = [string]::Format('PowerShell {0}', $parameter.Name) + + if ($parameter.type.name -eq 'switch') { + $IcingaDataType='Boolean'; + } elseif ($parameter.type.name -eq 'Object') { + if ($parameter.Name -eq 'Verbose') { + $IcingaDataType='Datalist' } - if ($ArgumentKnown) { - continue; - } + $IcingaDataType='String'; - $DataListName = [string]::Format('PowerShell {0}', $parameter.Name) + } elseif ($parameter.type.name -eq 'Array') { + $IcingaDataType='Array'; + } else { + $IcingaDataType='String'; + } - if ($parameter.type.name -eq 'switch') { - $IcingaDataType='Boolean'; + if($Basket.Datafield.ContainsKey('0') -eq $FALSE){ + $Basket.Datafield.Add( + '0', @{ + 'varname' = 'PowerShell_Switch_NoPerfData'; + 'caption' = 'Ignore Performance Data'; + 'description' = 'Specifies if the plugin will return performance data output or not'; + 'datatype' = 'Icinga\Module\Director\DataType\DataTypeBoolean'; + 'format' = $NULL; + 'originalId' = '0'; + } + ); + } + + if($Basket.Datafield.ContainsKey('1') -eq $FALSE){ + $Basket.Datafield.Add( + '1', @{ + 'varname' = 'PowerShell_Object_Verbose'; + 'caption' = 'Verbose'; + 'description' = 'Specifies if the plugin will return performance data output or not'; + 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; + 'format' = $NULL; + 'originalId' = '1'; + 'settings' = @{ + 'datalist' = 'PowerShell Verbose'; + 'datatype' = 'string'; + 'behavior' = 'strict'; + } + } + ); + } + + $IcingaDataType = [string]::Format('Icinga\Module\Director\DataType\DataType{0}', $IcingaDataType) + + if ($Basket.Datafield.Values.varname -ne $IcingaCustomVariable) { + $Basket.Datafield.Add( + [string]$FieldID, @{ + 'varname' = $IcingaCustomVariable; + 'caption' = $parameter.Name; + 'description' = $parameter.Description.Text; + 'datatype' = $IcingaDataType; + 'format' = $NULL; + 'originalId' = [string]$FieldID; + } + ); + + if ($parameter.Name -eq 'Verbose') { + $Basket.Datafield[[string]$FieldID].Add( + 'settings', @{ + 'behavior' = 'strict'; + 'datatype' = 'string'; + 'datalist' = $DataListName; + } + ); } elseif ($parameter.type.name -eq 'Object') { - if ($parameter.Name -eq 'Verbose') { - $IcingaDataType='Datalist' - } - - $IcingaDataType='String'; - - } elseif ($parameter.type.name -eq 'Array') { - $IcingaDataType='Array'; + $Basket.Datafield[[string]$FieldID].Add( + 'settings', @{ + 'visbility' = 'visible'; + } + ); } else { - $IcingaDataType='String'; - } - - if($Basket.Datafield.ContainsKey('0') -eq $FALSE){ - $Basket.Datafield.Add( - '0', @{ - 'varname' = 'PowerShell_Switch_NoPerfData'; - 'caption' = 'Ignore Performance Data'; - 'description' = 'Specifies if the plugin will return performance data output or not'; - 'datatype' = 'Icinga\Module\Director\DataType\DataTypeBoolean'; - 'format' = $NULL; - 'originalId' = '0'; + $Basket.Datafield[[string]$FieldID].Add( + 'settings', @{ + 'visbility' = 'visible'; } ); } - if($Basket.Datafield.ContainsKey('1') -eq $FALSE){ - $Basket.Datafield.Add( - '1', @{ - 'varname' = 'PowerShell_Object_Verbose'; - 'caption' = 'Verbose'; - 'description' = 'Specifies if the plugin will return performance data output or not'; - 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; - 'format' = $NULL; - 'originalId' = '1'; - 'settings' = @{ - 'datalist' = 'PowerShell Verbose'; - 'datatype' = 'string'; - 'behavior' = 'strict'; - } - } - ); - } - - $IcingaDataType = [string]::Format('Icinga\Module\Director\DataType\DataType{0}', $IcingaDataType) - - if ($Basket.Datafield.Values.varname -ne $IcingaCustomVariable) { - $Basket.Datafield.Add( - [string]$FieldID, @{ - 'varname' = $IcingaCustomVariable; - 'caption' = $parameter.Name; - 'description' = $parameter.Description.Text; - 'datatype' = $IcingaDataType; - 'format' = $NULL; - 'originalId' = [string]$FieldID; - } - ); - - if ($parameter.Name -eq 'Verbose') { - $Basket.Datafield[[string]$FieldID].Add( - 'settings', @{ - 'behavior' = 'strict'; - 'datatype' = 'string'; - 'datalist' = $DataListName; - } - ); - } elseif ($parameter.type.name -eq 'Object') { - $Basket.Datafield[[string]$FieldID].Add( - 'settings', @{ - 'visbility' = 'visible'; - } - ); - } else { - $Basket.Datafield[[string]$FieldID].Add( - 'settings', @{ - 'visbility' = 'visible'; - } - ); - } - - # Increment FieldID, so unique datafields are added. - [int]$FieldID = [int]$FieldID + 1; - } + # Increment FieldID, so unique datafields are added. + [int]$FieldID = [int]$FieldID + 1; } # Increment FieldNumeration, so unique fields for a given command are added. From 6d80c0434a0c5233ff542f23289d2d7be576aeba Mon Sep 17 00:00:00 2001 From: Crited Date: Tue, 29 Oct 2019 10:18:20 +0100 Subject: [PATCH 173/259] Set default for Warning, Critical; Change Verbose to Verbosity with default and ValidateSet, Add ValidateSet for ServiceStatus, Fixed CPU-Check --- lib/plugins/Invoke-IcingaCheckCPU.psm1 | 11 ++++++----- lib/plugins/Invoke-IcingaCheckDirectory.psm1 | 19 ++++++++++--------- lib/plugins/Invoke-IcingaCheckEventlog.psm1 | 13 +++++++------ .../Invoke-IcingaCheckPerfcounter.psm1 | 11 ++++++----- .../Invoke-IcingaCheckProcessCount.psm1 | 11 ++++++----- lib/plugins/Invoke-IcingaCheckService.psm1 | 6 ++++-- lib/plugins/Invoke-IcingaCheckUpdates.psm1 | 9 +++++---- lib/plugins/Invoke-IcingaCheckUptime.psm1 | 11 ++++++----- .../Invoke-IcingaCheckUsedPartitionSpace.psm1 | 9 +++++---- lib/plugins/Invoke-IcingaCheckUsers.psm1 | 11 ++++++----- 10 files changed, 61 insertions(+), 50 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckCPU.psm1 b/lib/plugins/Invoke-IcingaCheckCPU.psm1 index 194dafc..7fdd5c7 100644 --- a/lib/plugins/Invoke-IcingaCheckCPU.psm1 +++ b/lib/plugins/Invoke-IcingaCheckCPU.psm1 @@ -38,15 +38,16 @@ Import-IcingaLib icinga\plugin; function Invoke-IcingaCheckCPU() { param( - [int]$Warning, - [int]$Critical, - $Core = '*', + [int]$Warning = $null, + [int]$Critical = $null, + [string]$Core = '*', [switch]$NoPerfData, - $Verbose + [ValidateSet(0, 1, 2, 3)] + [int]$Verbosity = 0 ); $CpuCounter = New-IcingaPerformanceCounter -Counter ([string]::Format('\Processor({0})\% processor time', $Core)); - $CpuPackage = New-IcingaCheckPackage -Name 'CPU Load' -OperatorAnd -Verbos $Verbose; + $CpuPackage = New-IcingaCheckPackage -Name 'CPU Load' -OperatorAnd -Verbose $Verbosity; $CpuCount = ([string](Get-IcingaCpuCount)).Length; if ($CpuCounter.Counters.Count -ne 0) { diff --git a/lib/plugins/Invoke-IcingaCheckDirectory.psm1 b/lib/plugins/Invoke-IcingaCheckDirectory.psm1 index 7b0957e..9f7f26d 100644 --- a/lib/plugins/Invoke-IcingaCheckDirectory.psm1 +++ b/lib/plugins/Invoke-IcingaCheckDirectory.psm1 @@ -11,19 +11,19 @@ Import-IcingaLib provider\directory; This module is intended to be used to check how many files and directories are within are specified path. Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. .EXAMPLE - PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -Warning 20 -Critical 30 -Verbose 3 + PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -Warning 20 -Critical 30 -Verbosity 3 [OK]: Check package "C:\Users\Icinga\Downloads" is [OK] (Match All) \_ [OK]: C:\Users\Icinga\Downloads is 19 .EXAMPLE - PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -Warning 20 -Critical 30 -Verbose 3 + PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -Warning 20 -Critical 30 -Verbosity 3 [WARNING]: Check package "C:\Users\Icinga\Downloads" is [WARNING] (Match All) \_ [WARNING]: C:\Users\Icinga\Downloads is 24 .EXAMPLE - PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -Warning 20 -Critical 30 -Verbose 3 -YoungerThen 20d -OlderThen 10d + PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -Warning 20 -Critical 30 -Verbosity 3 -YoungerThen 20d -OlderThen 10d [OK]: Check package "C:\Users\Icinga\Downloads" is [OK] (Match All) \_ [OK]: C:\Users\Icinga\Downloads is 1 .EXAMPLE - PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -FileNames "*.txt","*.sql" -Warning 20 -Critical 30 -Verbose 3 + PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -FileNames "*.txt","*.sql" -Warning 20 -Critical 30 -Verbosity 3 [OK]: Check package "C:\Users\Icinga\Downloads" is [OK] (Match All) \_ [OK]: C:\Users\Icinga\Downloads is 4 .PARAMETER Warning @@ -62,12 +62,13 @@ function Invoke-IcingaCheckDirectory() [string]$Path, [array]$FileNames, [switch]$Recurse, - [int]$Critical, - [int]$Warning, + [int]$Critical = $null, + [int]$Warning = $null, [string]$YoungerThen, [string]$OlderThen, - [int]$Verbose - ); + [ValidateSet(0, 1, 2, 3)] + [int]$Verbosity = 0 + ); $DirectoryData = Get-IcingaDirectoryAll -Path $Path -FileNames $FileNames ` -Recurse $Recurse -YoungerThen $YoungerThen -OlderThen $OlderThen; @@ -79,7 +80,7 @@ function Invoke-IcingaCheckDirectory() ($Critical) ) | Out-Null; - $DirectoryPackage = New-IcingaCheckPackage -Name $Path -OperatorAnd -Checks $DirectoryCheck -Verbose $Verbose; + $DirectoryPackage = New-IcingaCheckPackage -Name $Path -OperatorAnd -Checks $DirectoryCheck -Verbose $Verbosity; return (New-IcingaCheckresult -Check $DirectoryPackage -NoPerfData $TRUE -Compile); } \ No newline at end of file diff --git a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 index 09c1fc6..1f25d89 100644 --- a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 +++ b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 @@ -3,8 +3,8 @@ Import-IcingaLib icinga\plugin; function Invoke-IcingaCheckEventlog() { param( - $Warning, - $Critical, + $Warning = $null, + $Critical = $null, [string]$LogName, [array]$IncludeEventId, [array]$ExcludeEventId, @@ -18,10 +18,11 @@ function Invoke-IcingaCheckEventlog() $Before = $null, [switch]$DisableTimeCache = $FALSE, [switch]$NoPerfData, - $Verbose + [ValidateSet(0, 1, 2, 3)] + [int]$Verbosity = 0 ); - $EventLogPackage = New-IcingaCheckPackage -Name 'EventLog' -OperatorAnd -Verbose $Verbose; + $EventLogPackage = New-IcingaCheckPackage -Name 'EventLog' -OperatorAnd -Verbose $Verbosity; $EventLogData = Get-IcingaEventLog -LogName $LogName -IncludeEventId $IncludeEventId -ExcludeEventId $ExcludeEventId -IncludeUsername $IncludeUsername -ExcludeUsername $ExcludeUsername ` -IncludeEntryType $IncludeEntryType -ExcludeEntryType $ExcludeEntryType -IncludeMessage $IncludeMessage -ExcludeMessage $ExcludeMessage ` -After $After -Before $Before -DisableTimeCache $DisableTimeCache; @@ -29,7 +30,7 @@ function Invoke-IcingaCheckEventlog() if ($EventLogData.eventlog.Count -ne 0) { foreach ($event in $EventLogData.eventlog.Keys) { $eventEntry = $EventLogData.eventlog[$event]; - $EventLogEntryPackage = New-IcingaCheckPackage -Name ([string]::Format('Between: [{0}] - [{1}] there occured {2} event(s).', $eventEntry.OldestEntry, $eventEntry.NewestEntry, $eventEntry.Count)) -OperatorAnd -Verbose $Verbose; + $EventLogEntryPackage = New-IcingaCheckPackage -Name ([string]::Format('Between: [{0}] - [{1}] there occured {2} event(s).', $eventEntry.OldestEntry, $eventEntry.NewestEntry, $eventEntry.Count)) -OperatorAnd -Verbose $Verbosity; $IcingaCheck = New-IcingaCheck -Name ([string]::Format('EventId {0}', $EventLogData.eventlog[$event].EventId)) -Value $eventEntry.Count -NoPerfData; $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; $EventLogEntryPackage.AddCheck($IcingaCheck); @@ -37,7 +38,7 @@ function Invoke-IcingaCheckEventlog() $EventLogPackage.AddCheck($EventLogEntryPackage); } - $EventLogCountPackage = New-IcingaCheckPackage -Name 'EventLog Count' -OperatorAnd -Verbose $Verbose -Hidden; + $EventLogCountPackage = New-IcingaCheckPackage -Name 'EventLog Count' -OperatorAnd -Verbose $Verbosity -Hidden; foreach ($event in $EventLogData.events.Keys) { $IcingaCheck = New-IcingaCheck -Name ([string]::Format('EventId {0}', $event)) -Value $EventLogData.events[$event] -Unit 'c'; diff --git a/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 b/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 index 4863cfb..58ea192 100644 --- a/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 +++ b/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 @@ -4,18 +4,19 @@ function Invoke-IcingaCheckPerfcounter() { param( [array]$PerfCounter, - $Warning, - $Critical, + [double]$Warning = $null, + [double]$Critical = $null, [switch]$NoPerfData, - [int]$Verbose + [ValidateSet(0, 1, 2, 3)] + [int]$Verbosity = 0 ); $Counters = New-IcingaPerformanceCounterArray -CounterArray $PerfCounter; - $CheckPackage = New-IcingaCheckPackage -Name 'Performance Counter' -OperatorAnd -Verbose $Verbose; + $CheckPackage = New-IcingaCheckPackage -Name 'Performance Counter' -OperatorAnd -Verbose $Verbosity; foreach ($counter in $Counters.Keys) { - $CounterPackage = New-IcingaCheckPackage -Name $counter -OperatorAnd -Verbose $Verbose; + $CounterPackage = New-IcingaCheckPackage -Name $counter -OperatorAnd -Verbose $Verbosity; foreach ($instanceName in $Counters[$counter].Keys) { $instance = $Counters[$counter][$instanceName]; diff --git a/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 b/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 index 37ff850..117602a 100644 --- a/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 +++ b/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 @@ -16,7 +16,7 @@ Import-IcingaLib icinga\plugin; [OK]: Check package "Process Check" is [OK] | 'Process Count "conhost"'=3;; .EXAMPLE - PS>Invoke-IcingaCheckProcessCount -Process conhost,wininit -Warning 5 -Critical 10 -Verbose 4 + PS>Invoke-IcingaCheckProcessCount -Process conhost,wininit -Warning 5 -Critical 10 -Verbosity 4 [OK]: Check package "Process Check" is [OK] (Match All) \_ [OK]: Process Count "conhost" is 3 \_ [OK]: Process Count "wininit" is 1 @@ -40,16 +40,17 @@ Import-IcingaLib icinga\plugin; function Invoke-IcingaCheckProcessCount() { param( - [int]$Warning, - [int]$Critical, + [int]$Warning = $null, + [int]$Critical = $null, [array]$Process, [switch]$NoPerfData, - $Verbose + [ValidateSet(0, 1, 2, 3)] + [int]$Verbosity = 0 ); $ProcessInformation = (Get-IcingaProcessData -Name $Process) - $ProcessPackage = New-icingaCheckPackage -Name "Process Check" -OperatorAnd -Verbose $Verbose -NoPerfData $NoPerfData; + $ProcessPackage = New-icingaCheckPackage -Name "Process Check" -OperatorAnd -Verbose $Verbosity -NoPerfData $NoPerfData; if ($Process.Count -eq 0) { $ProcessCount = $ProcessInformation['Process Count']; diff --git a/lib/plugins/Invoke-IcingaCheckService.psm1 b/lib/plugins/Invoke-IcingaCheckService.psm1 index 23f8b30..3a59d28 100644 --- a/lib/plugins/Invoke-IcingaCheckService.psm1 +++ b/lib/plugins/Invoke-IcingaCheckService.psm1 @@ -34,11 +34,13 @@ function Invoke-IcingaCheckService() { param( [array]$Service, + [ValidateSet('Stopped', 'StartPending', 'StopPending', 'Running', 'ContinuePending', 'PausePending', 'Paused')] [string]$Status, - [int]$Verbose + [ValidateSet(0, 1, 2, 3)] + [int]$Verbosity = 0 ); - $ServicesPackage = New-IcingaCheckPackage -Name 'Services' -OperatorAnd -Verbose $Verbose; + $ServicesPackage = New-IcingaCheckPackage -Name 'Services' -OperatorAnd -Verbose $Verbosity; if ($Service.Count -ne 1) { foreach ($services in $Service) { diff --git a/lib/plugins/Invoke-IcingaCheckUpdates.psm1 b/lib/plugins/Invoke-IcingaCheckUpdates.psm1 index 25e61f8..a878db4 100644 --- a/lib/plugins/Invoke-IcingaCheckUpdates.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUpdates.psm1 @@ -33,10 +33,11 @@ function Invoke-IcingaCheckUpdates() { param ( [array]$UpdateFilter, - [int]$Warning, - [int]$Critical, + [int]$Warning = $null, + [int]$Critical = $null, [switch]$NoPerfData, - [int]$Verbose + [ValidateSet(0, 1, 2, 3)] + [int]$Verbosity = 0 ); $PendingUpdates = Get-IcingaUpdatesPending; @@ -74,7 +75,7 @@ function Invoke-IcingaCheckUpdates() $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; $UpdateCount.AddCheck($IcingaCheck); - $UpdatePackage = New-IcingaCheckPackage -Name 'Updates' -OperatorAnd -Verbose $Verbose -Checks @( + $UpdatePackage = New-IcingaCheckPackage -Name 'Updates' -OperatorAnd -Verbose $Verbosity -Checks @( $UpdateCount ); diff --git a/lib/plugins/Invoke-IcingaCheckUptime.psm1 b/lib/plugins/Invoke-IcingaCheckUptime.psm1 index 147c04a..e9ba339 100644 --- a/lib/plugins/Invoke-IcingaCheckUptime.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUptime.psm1 @@ -35,11 +35,12 @@ Import-IcingaLib core\tools; function Invoke-IcingaCheckUptime() { param( - [string]$Warning, - [string]$Critical, + [string]$Warning = $null, + [string]$Critical = $null, [switch]$NoPerfData, - [int]$Verbose - ); + [ValidateSet(0, 1, 2, 3)] + [int]$Verbosity = 0 + ); $WindowsData = Get-IcingaWindows; $Name = ([string]::Format('Windows Uptime: {0}', (ConvertFrom-TimeSpan -Seconds $WindowsData.windows.metadata.uptime.value))); @@ -51,7 +52,7 @@ function Invoke-IcingaCheckUptime() (ConvertTo-SecondsFromIcingaThresholds -Threshold $Critical) ) | Out-Null; - $CheckPackage = New-IcingaCheckPackage -Name $Name -OperatorAnd -Checks $IcingaCheck -Verbose $Verbose; + $CheckPackage = New-IcingaCheckPackage -Name $Name -OperatorAnd -Checks $IcingaCheck -Verbose $Verbosity; return (New-IcingaCheckresult -Check $CheckPackage -NoPerfData $NoPerfData -Compile); } diff --git a/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 b/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 index 6d58b45..6cbcbd5 100644 --- a/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 @@ -45,16 +45,17 @@ Import-IcingaLib icinga\plugin; function Invoke-IcingaCheckUsedPartitionSpace() { param( - [int]$Warning, - [int]$Critical, + [int]$Warning = $null, + [int]$Critical = $null, [array]$Include = @(), [array]$Exclude = @(), [switch]$NoPerfData, - $Verbose + [ValidateSet(0, 1, 2, 3)] + [int]$Verbosity = 0 ); $DiskFree = Get-IcingaDiskPartitions; - $DiskPackage = New-IcingaCheckPackage -Name 'Used Partition Space' -OperatorAnd -Verbos $Verbose; + $DiskPackage = New-IcingaCheckPackage -Name 'Used Partition Space' -OperatorAnd -Verbos $Verbosity; foreach ($Letter in $DiskFree.Keys) { if ($Include.Count -ne 0) { diff --git a/lib/plugins/Invoke-IcingaCheckUsers.psm1 b/lib/plugins/Invoke-IcingaCheckUsers.psm1 index d3e6de9..3139e9f 100644 --- a/lib/plugins/Invoke-IcingaCheckUsers.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUsers.psm1 @@ -37,13 +37,14 @@ function Invoke-IcingaCheckUsers() { param ( [array]$Username, - [int]$Warning, - [int]$Critical, + [int]$Warning = $null, + [int]$Critical = $null, [switch]$NoPerfData, - [int]$Verbose - ); + [ValidateSet(0, 1, 2, 3)] + [int]$Verbosity = 0 + ); - $UsersPackage = New-IcingaCheckPackage -Name 'Users' -OperatorAnd -Verbose $Verbose; + $UsersPackage = New-IcingaCheckPackage -Name 'Users' -OperatorAnd -Verbose $Verbosity; $LoggedOnUsers = Get-IcingaLoggedOnUsers -UserFilter $Username; if ($Username.Count -ne 0) { From 8ee0b354e2bb06099790c1d2ddd7defb36adda8a Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 29 Oct 2019 10:47:24 +0100 Subject: [PATCH 174/259] Fixes code styling --- lib/plugins/Invoke-IcingaCheckCPU.psm1 | 4 +- lib/plugins/Invoke-IcingaCheckDirectory.psm1 | 40 ++++++------- lib/plugins/Invoke-IcingaCheckEventlog.psm1 | 6 +- .../Invoke-IcingaCheckPerfcounter.psm1 | 6 +- .../Invoke-IcingaCheckProcessCount.psm1 | 48 +++++++-------- lib/plugins/Invoke-IcingaCheckService.psm1 | 60 +++++++++---------- lib/plugins/Invoke-IcingaCheckUpdates.psm1 | 6 +- lib/plugins/Invoke-IcingaCheckUptime.psm1 | 32 +++++----- .../Invoke-IcingaCheckUsedPartitionSpace.psm1 | 58 +++++++++--------- lib/plugins/Invoke-IcingaCheckUsers.psm1 | 58 +++++++++--------- 10 files changed, 159 insertions(+), 159 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckCPU.psm1 b/lib/plugins/Invoke-IcingaCheckCPU.psm1 index 7fdd5c7..f3b3d49 100644 --- a/lib/plugins/Invoke-IcingaCheckCPU.psm1 +++ b/lib/plugins/Invoke-IcingaCheckCPU.psm1 @@ -40,10 +40,10 @@ function Invoke-IcingaCheckCPU() param( [int]$Warning = $null, [int]$Critical = $null, - [string]$Core = '*', + [string]$Core = '*', [switch]$NoPerfData, [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 + [int]$Verbosity = 0 ); $CpuCounter = New-IcingaPerformanceCounter -Counter ([string]::Format('\Processor({0})\% processor time', $Core)); diff --git a/lib/plugins/Invoke-IcingaCheckDirectory.psm1 b/lib/plugins/Invoke-IcingaCheckDirectory.psm1 index 9f7f26d..d901f7b 100644 --- a/lib/plugins/Invoke-IcingaCheckDirectory.psm1 +++ b/lib/plugins/Invoke-IcingaCheckDirectory.psm1 @@ -58,29 +58,29 @@ Import-IcingaLib provider\directory; function Invoke-IcingaCheckDirectory() { - param( - [string]$Path, - [array]$FileNames, - [switch]$Recurse, - [int]$Critical = $null, - [int]$Warning = $null, - [string]$YoungerThen, - [string]$OlderThen, - [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 + param( + [string]$Path, + [array]$FileNames, + [switch]$Recurse, + [int]$Critical = $null, + [int]$Warning = $null, + [string]$YoungerThen, + [string]$OlderThen, + [ValidateSet(0, 1, 2, 3)] + [int]$Verbosity = 0 ); - $DirectoryData = Get-IcingaDirectoryAll -Path $Path -FileNames $FileNames ` - -Recurse $Recurse -YoungerThen $YoungerThen -OlderThen $OlderThen; - $DirectoryCheck = New-IcingaCheck -Name $Path -Value $DirectoryData.Count -NoPerfData; + $DirectoryData = Get-IcingaDirectoryAll -Path $Path -FileNames $FileNames ` + -Recurse $Recurse -YoungerThen $YoungerThen -OlderThen $OlderThen; + $DirectoryCheck = New-IcingaCheck -Name $Path -Value $DirectoryData.Count -NoPerfData; - $DirectoryCheck.WarnOutOfRange( - ($Warning) - ).CritOutOfRange( - ($Critical) - ) | Out-Null; + $DirectoryCheck.WarnOutOfRange( + ($Warning) + ).CritOutOfRange( + ($Critical) + ) | Out-Null; - $DirectoryPackage = New-IcingaCheckPackage -Name $Path -OperatorAnd -Checks $DirectoryCheck -Verbose $Verbosity; + $DirectoryPackage = New-IcingaCheckPackage -Name $Path -OperatorAnd -Checks $DirectoryCheck -Verbose $Verbosity; - return (New-IcingaCheckresult -Check $DirectoryPackage -NoPerfData $TRUE -Compile); + return (New-IcingaCheckresult -Check $DirectoryPackage -NoPerfData $TRUE -Compile); } \ No newline at end of file diff --git a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 index 1f25d89..a62847f 100644 --- a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 +++ b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 @@ -3,8 +3,8 @@ Import-IcingaLib icinga\plugin; function Invoke-IcingaCheckEventlog() { param( - $Warning = $null, - $Critical = $null, + $Warning = $null, + $Critical = $null, [string]$LogName, [array]$IncludeEventId, [array]$ExcludeEventId, @@ -19,7 +19,7 @@ function Invoke-IcingaCheckEventlog() [switch]$DisableTimeCache = $FALSE, [switch]$NoPerfData, [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 + [int]$Verbosity = 0 ); $EventLogPackage = New-IcingaCheckPackage -Name 'EventLog' -OperatorAnd -Verbose $Verbosity; diff --git a/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 b/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 index 58ea192..b10df7e 100644 --- a/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 +++ b/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 @@ -4,11 +4,11 @@ function Invoke-IcingaCheckPerfcounter() { param( [array]$PerfCounter, - [double]$Warning = $null, - [double]$Critical = $null, + [double]$Warning = $null, + [double]$Critical = $null, [switch]$NoPerfData, [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 + [int]$Verbosity = 0 ); $Counters = New-IcingaPerformanceCounterArray -CounterArray $PerfCounter; diff --git a/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 b/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 index 117602a..a40c6e2 100644 --- a/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 +++ b/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 @@ -39,33 +39,33 @@ Import-IcingaLib icinga\plugin; function Invoke-IcingaCheckProcessCount() { - param( - [int]$Warning = $null, - [int]$Critical = $null, - [array]$Process, - [switch]$NoPerfData, - [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 - ); + param( + [int]$Warning = $null, + [int]$Critical = $null, + [array]$Process, + [switch]$NoPerfData, + [ValidateSet(0, 1, 2, 3)] + [int]$Verbosity = 0 + ); - $ProcessInformation = (Get-IcingaProcessData -Name $Process) + $ProcessInformation = (Get-IcingaProcessData -Name $Process) - $ProcessPackage = New-icingaCheckPackage -Name "Process Check" -OperatorAnd -Verbose $Verbosity -NoPerfData $NoPerfData; + $ProcessPackage = New-icingaCheckPackage -Name "Process Check" -OperatorAnd -Verbose $Verbosity -NoPerfData $NoPerfData; - if ($Process.Count -eq 0) { - $ProcessCount = $ProcessInformation['Process Count']; - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Process Count')) -Value $ProcessCount; - $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; - $ProcessPackage.AddCheck($IcingaCheck); - } else { - foreach ($proc in $process) { - $ProcessCount = $ProcessInformation."Processes".$proc.processlist.Count; - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Process Count "{0}"', $proc)) -Value $ProcessCount; - $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; - $ProcessPackage.AddCheck($IcingaCheck); - } - } + if ($Process.Count -eq 0) { + $ProcessCount = $ProcessInformation['Process Count']; + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Process Count')) -Value $ProcessCount; + $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + $ProcessPackage.AddCheck($IcingaCheck); + } else { + foreach ($proc in $process) { + $ProcessCount = $ProcessInformation."Processes".$proc.processlist.Count; + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Process Count "{0}"', $proc)) -Value $ProcessCount; + $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + $ProcessPackage.AddCheck($IcingaCheck); + } + } - return (New-IcingaCheckResult -Check $ProcessPackage -NoPerfData $NoPerfData -Compile); + return (New-IcingaCheckResult -Check $ProcessPackage -NoPerfData $NoPerfData -Compile); } diff --git a/lib/plugins/Invoke-IcingaCheckService.psm1 b/lib/plugins/Invoke-IcingaCheckService.psm1 index 3a59d28..59975d9 100644 --- a/lib/plugins/Invoke-IcingaCheckService.psm1 +++ b/lib/plugins/Invoke-IcingaCheckService.psm1 @@ -32,40 +32,40 @@ Import-IcingaLib icinga\plugin; function Invoke-IcingaCheckService() { - param( - [array]$Service, - [ValidateSet('Stopped', 'StartPending', 'StopPending', 'Running', 'ContinuePending', 'PausePending', 'Paused')] - [string]$Status, - [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 - ); + param( + [array]$Service, + [ValidateSet('Stopped', 'StartPending', 'StopPending', 'Running', 'ContinuePending', 'PausePending', 'Paused')] + [string]$Status, + [ValidateSet(0, 1, 2, 3)] + [int]$Verbosity = 0 + ); - $ServicesPackage = New-IcingaCheckPackage -Name 'Services' -OperatorAnd -Verbose $Verbosity; + $ServicesPackage = New-IcingaCheckPackage -Name 'Services' -OperatorAnd -Verbose $Verbosity; - if ($Service.Count -ne 1) { - foreach ($services in $Service) { - $IcingaCheck = $null; + if ($Service.Count -ne 1) { + foreach ($services in $Service) { + $IcingaCheck = $null; - $FoundService = Get-IcingaServices -Service $services; - $ServiceName = Get-IcingaServiceCheckName -ServiceInput $services -Service $FoundService; - $ConvertedStatus = ConvertTo-ServiceStatusCode -Status $Status; - $StatusRaw = $FoundService.Values.configuration.Status.raw; - - $IcingaCheck = New-IcingaCheck -Name $ServiceName -Value $StatusRaw -ObjectExists $FoundService -Translation $ProviderEnums.ServiceStatusName; - $IcingaCheck.CritIfNotMatch($ConvertedStatus) | Out-Null; - $ServicesPackage.AddCheck($IcingaCheck) - } - } else { + $FoundService = Get-IcingaServices -Service $services; + $ServiceName = Get-IcingaServiceCheckName -ServiceInput $services -Service $FoundService; + $ConvertedStatus = ConvertTo-ServiceStatusCode -Status $Status; + $StatusRaw = $FoundService.Values.configuration.Status.raw; + + $IcingaCheck = New-IcingaCheck -Name $ServiceName -Value $StatusRaw -ObjectExists $FoundService -Translation $ProviderEnums.ServiceStatusName; + $IcingaCheck.CritIfNotMatch($ConvertedStatus) | Out-Null; + $ServicesPackage.AddCheck($IcingaCheck) + } + } else { - $FoundService = Get-IcingaServices -Service $Service; - $ServiceName = Get-IcingaServiceCheckName -ServiceInput $Service -Service $FoundService; - $Status = ConvertTo-ServiceStatusCode -Status $Status; - $StatusRaw = $FoundService.Values.configuration.Status.raw; + $FoundService = Get-IcingaServices -Service $Service; + $ServiceName = Get-IcingaServiceCheckName -ServiceInput $Service -Service $FoundService; + $Status = ConvertTo-ServiceStatusCode -Status $Status; + $StatusRaw = $FoundService.Values.configuration.Status.raw; - $IcingaCheck = New-IcingaCheck -Name $ServiceName -Value $StatusRaw -ObjectExists $FoundService -Translation $ProviderEnums.ServiceStatusName; - $IcingaCheck.CritIfNotMatch($Status) | Out-Null; - $ServicesPackage.AddCheck($IcingaCheck); + $IcingaCheck = New-IcingaCheck -Name $ServiceName -Value $StatusRaw -ObjectExists $FoundService -Translation $ProviderEnums.ServiceStatusName; + $IcingaCheck.CritIfNotMatch($Status) | Out-Null; + $ServicesPackage.AddCheck($IcingaCheck); - } - return (New-IcingaCheckResult -Name 'Services' -Check $ServicesPackage -NoPerfData $TRUE -Compile); + } + return (New-IcingaCheckResult -Name 'Services' -Check $ServicesPackage -NoPerfData $TRUE -Compile); } diff --git a/lib/plugins/Invoke-IcingaCheckUpdates.psm1 b/lib/plugins/Invoke-IcingaCheckUpdates.psm1 index a878db4..4443e35 100644 --- a/lib/plugins/Invoke-IcingaCheckUpdates.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUpdates.psm1 @@ -33,11 +33,11 @@ function Invoke-IcingaCheckUpdates() { param ( [array]$UpdateFilter, - [int]$Warning = $null, - [int]$Critical = $null, + [int]$Warning = $null, + [int]$Critical = $null, [switch]$NoPerfData, [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 + [int]$Verbosity = 0 ); $PendingUpdates = Get-IcingaUpdatesPending; diff --git a/lib/plugins/Invoke-IcingaCheckUptime.psm1 b/lib/plugins/Invoke-IcingaCheckUptime.psm1 index e9ba339..f71a871 100644 --- a/lib/plugins/Invoke-IcingaCheckUptime.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUptime.psm1 @@ -34,25 +34,25 @@ Import-IcingaLib core\tools; function Invoke-IcingaCheckUptime() { - param( - [string]$Warning = $null, - [string]$Critical = $null, - [switch]$NoPerfData, - [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 + param( + [string]$Warning = $null, + [string]$Critical = $null, + [switch]$NoPerfData, + [ValidateSet(0, 1, 2, 3)] + [int]$Verbosity = 0 ); - $WindowsData = Get-IcingaWindows; - $Name = ([string]::Format('Windows Uptime: {0}', (ConvertFrom-TimeSpan -Seconds $WindowsData.windows.metadata.uptime.value))); + $WindowsData = Get-IcingaWindows; + $Name = ([string]::Format('Windows Uptime: {0}', (ConvertFrom-TimeSpan -Seconds $WindowsData.windows.metadata.uptime.value))); - $IcingaCheck = New-IcingaCheck -Name 'Windows Uptime' -Value $WindowsData.windows.metadata.uptime.value -Unit 's'; - $IcingaCheck.WarnOutOfRange( - (ConvertTo-SecondsFromIcingaThresholds -Threshold $Warning) - ).CritOutOfRange( - (ConvertTo-SecondsFromIcingaThresholds -Threshold $Critical) - ) | Out-Null; + $IcingaCheck = New-IcingaCheck -Name 'Windows Uptime' -Value $WindowsData.windows.metadata.uptime.value -Unit 's'; + $IcingaCheck.WarnOutOfRange( + (ConvertTo-SecondsFromIcingaThresholds -Threshold $Warning) + ).CritOutOfRange( + (ConvertTo-SecondsFromIcingaThresholds -Threshold $Critical) + ) | Out-Null; - $CheckPackage = New-IcingaCheckPackage -Name $Name -OperatorAnd -Checks $IcingaCheck -Verbose $Verbosity; + $CheckPackage = New-IcingaCheckPackage -Name $Name -OperatorAnd -Checks $IcingaCheck -Verbose $Verbosity; - return (New-IcingaCheckresult -Check $CheckPackage -NoPerfData $NoPerfData -Compile); + return (New-IcingaCheckresult -Check $CheckPackage -NoPerfData $NoPerfData -Compile); } diff --git a/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 b/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 index 6cbcbd5..bfb3ca3 100644 --- a/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 @@ -44,39 +44,39 @@ Import-IcingaLib icinga\plugin; function Invoke-IcingaCheckUsedPartitionSpace() { - param( - [int]$Warning = $null, - [int]$Critical = $null, - [array]$Include = @(), - [array]$Exclude = @(), - [switch]$NoPerfData, - [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 - ); + param( + [int]$Warning = $null, + [int]$Critical = $null, + [array]$Include = @(), + [array]$Exclude = @(), + [switch]$NoPerfData, + [ValidateSet(0, 1, 2, 3)] + [int]$Verbosity = 0 + ); - $DiskFree = Get-IcingaDiskPartitions; - $DiskPackage = New-IcingaCheckPackage -Name 'Used Partition Space' -OperatorAnd -Verbos $Verbosity; + $DiskFree = Get-IcingaDiskPartitions; + $DiskPackage = New-IcingaCheckPackage -Name 'Used Partition Space' -OperatorAnd -Verbos $Verbosity; - foreach ($Letter in $DiskFree.Keys) { - if ($Include.Count -ne 0) { - $Include = $Include.trim(' :/\'); - if (-Not ($Include.Contains($Letter))) { - continue; - } - } + foreach ($Letter in $DiskFree.Keys) { + if ($Include.Count -ne 0) { + $Include = $Include.trim(' :/\'); + if (-Not ($Include.Contains($Letter))) { + continue; + } + } - if ($Exclude.Count -ne 0) { - $Exclude = $Exclude.trim(' :/\'); - if ($Exclude.Contains($Letter)) { - continue; - } - } + if ($Exclude.Count -ne 0) { + $Exclude = $Exclude.trim(' :/\'); + if ($Exclude.Contains($Letter)) { + continue; + } + } - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Partition {0}', $Letter)) -Value (100-($DiskFree.([string]::Format($Letter))."Free Space")) -Unit '%'; - $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; - $DiskPackage.AddCheck($IcingaCheck); - } + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Partition {0}', $Letter)) -Value (100-($DiskFree.([string]::Format($Letter))."Free Space")) -Unit '%'; + $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + $DiskPackage.AddCheck($IcingaCheck); + } - return (New-IcingaCheckResult -Check $DiskPackage -NoPerfData $NoPerfData -Compile); + return (New-IcingaCheckResult -Check $DiskPackage -NoPerfData $NoPerfData -Compile); } diff --git a/lib/plugins/Invoke-IcingaCheckUsers.psm1 b/lib/plugins/Invoke-IcingaCheckUsers.psm1 index 3139e9f..4a13833 100644 --- a/lib/plugins/Invoke-IcingaCheckUsers.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUsers.psm1 @@ -37,39 +37,39 @@ function Invoke-IcingaCheckUsers() { param ( [array]$Username, - [int]$Warning = $null, - [int]$Critical = $null, + [int]$Warning = $null, + [int]$Critical = $null, [switch]$NoPerfData, [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 + [int]$Verbosity = 0 ); - - $UsersPackage = New-IcingaCheckPackage -Name 'Users' -OperatorAnd -Verbose $Verbosity; - $LoggedOnUsers = Get-IcingaLoggedOnUsers -UserFilter $Username; - if ($Username.Count -ne 0) { - foreach ($User in $Username) { - $IcingaCheck = $null; - [int]$LoginCount = 0; + $UsersPackage = New-IcingaCheckPackage -Name 'Users' -OperatorAnd -Verbose $Verbosity; + $LoggedOnUsers = Get-IcingaLoggedOnUsers -UserFilter $Username; - if ($LoggedOnUsers.users.ContainsKey($User)) { - $LoginCount = $LoggedOnUsers.users.$User.count; - } + if ($Username.Count -ne 0) { + foreach ($User in $Username) { + $IcingaCheck = $null; + [int]$LoginCount = 0; - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Logged On User "{0}"', $User)) -Value $LoginCount; - $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; - $UsersPackage.AddCheck($IcingaCheck); - } - } else { - foreach ($User in $LoggedOnUsers.users.Keys) { - $UsersPackage.AddCheck( - (New-IcingaCheck -Name ([string]::Format('Logged On User "{0}"', $User)) -Value $LoggedOnUsers.users.$User.count) - ); - } - $IcingaCheck = New-IcingaCheck -Name 'Logged On Users' -Value $LoggedOnUsers.count; - $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; - $UsersPackage.AddCheck($IcingaCheck) - } - - return (New-IcingaCheckResult -Name 'Users' -Check $UsersPackage -NoPerfData $NoPerfData -Compile); + if ($LoggedOnUsers.users.ContainsKey($User)) { + $LoginCount = $LoggedOnUsers.users.$User.count; + } + + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Logged On User "{0}"', $User)) -Value $LoginCount; + $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + $UsersPackage.AddCheck($IcingaCheck); + } + } else { + foreach ($User in $LoggedOnUsers.users.Keys) { + $UsersPackage.AddCheck( + (New-IcingaCheck -Name ([string]::Format('Logged On User "{0}"', $User)) -Value $LoggedOnUsers.users.$User.count) + ); + } + $IcingaCheck = New-IcingaCheck -Name 'Logged On Users' -Value $LoggedOnUsers.count; + $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + $UsersPackage.AddCheck($IcingaCheck) + } + + return (New-IcingaCheckResult -Name 'Users' -Check $UsersPackage -NoPerfData $NoPerfData -Compile); } From 5f411ca88a0a1b1e0bb030bc471f530f5fb4f4c3 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 29 Oct 2019 10:51:17 +0100 Subject: [PATCH 175/259] Fixes data types of plugins --- lib/plugins/Invoke-IcingaCheckCPU.psm1 | 4 ++-- lib/plugins/Invoke-IcingaCheckDirectory.psm1 | 4 ++-- lib/plugins/Invoke-IcingaCheckEventlog.psm1 | 4 ++-- lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 | 4 ++-- lib/plugins/Invoke-IcingaCheckProcessCount.psm1 | 4 ++-- lib/plugins/Invoke-IcingaCheckUpdates.psm1 | 6 +++--- lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 | 4 ++-- lib/plugins/Invoke-IcingaCheckUsers.psm1 | 4 ++-- 8 files changed, 17 insertions(+), 17 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckCPU.psm1 b/lib/plugins/Invoke-IcingaCheckCPU.psm1 index f3b3d49..6f0d968 100644 --- a/lib/plugins/Invoke-IcingaCheckCPU.psm1 +++ b/lib/plugins/Invoke-IcingaCheckCPU.psm1 @@ -38,8 +38,8 @@ Import-IcingaLib icinga\plugin; function Invoke-IcingaCheckCPU() { param( - [int]$Warning = $null, - [int]$Critical = $null, + $Warning = $null, + $Critical = $null, [string]$Core = '*', [switch]$NoPerfData, [ValidateSet(0, 1, 2, 3)] diff --git a/lib/plugins/Invoke-IcingaCheckDirectory.psm1 b/lib/plugins/Invoke-IcingaCheckDirectory.psm1 index d901f7b..c20ecba 100644 --- a/lib/plugins/Invoke-IcingaCheckDirectory.psm1 +++ b/lib/plugins/Invoke-IcingaCheckDirectory.psm1 @@ -62,8 +62,8 @@ function Invoke-IcingaCheckDirectory() [string]$Path, [array]$FileNames, [switch]$Recurse, - [int]$Critical = $null, - [int]$Warning = $null, + $Critical = $null, + $Warning = $null, [string]$YoungerThen, [string]$OlderThen, [ValidateSet(0, 1, 2, 3)] diff --git a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 index a62847f..4e92802 100644 --- a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 +++ b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 @@ -14,8 +14,8 @@ function Invoke-IcingaCheckEventlog() [array]$ExcludeEntryType, [array]$IncludeMessage, [array]$ExcludeMessage, - $After = $null, - $Before = $null, + $After = $null, + $Before = $null, [switch]$DisableTimeCache = $FALSE, [switch]$NoPerfData, [ValidateSet(0, 1, 2, 3)] diff --git a/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 b/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 index b10df7e..c9b0588 100644 --- a/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 +++ b/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 @@ -4,8 +4,8 @@ function Invoke-IcingaCheckPerfcounter() { param( [array]$PerfCounter, - [double]$Warning = $null, - [double]$Critical = $null, + $Warning = $null, + $Critical = $null, [switch]$NoPerfData, [ValidateSet(0, 1, 2, 3)] [int]$Verbosity = 0 diff --git a/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 b/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 index a40c6e2..7487371 100644 --- a/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 +++ b/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 @@ -40,8 +40,8 @@ Import-IcingaLib icinga\plugin; function Invoke-IcingaCheckProcessCount() { param( - [int]$Warning = $null, - [int]$Critical = $null, + $Warning = $null, + $Critical = $null, [array]$Process, [switch]$NoPerfData, [ValidateSet(0, 1, 2, 3)] diff --git a/lib/plugins/Invoke-IcingaCheckUpdates.psm1 b/lib/plugins/Invoke-IcingaCheckUpdates.psm1 index 4443e35..33d81a5 100644 --- a/lib/plugins/Invoke-IcingaCheckUpdates.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUpdates.psm1 @@ -33,11 +33,11 @@ function Invoke-IcingaCheckUpdates() { param ( [array]$UpdateFilter, - [int]$Warning = $null, - [int]$Critical = $null, + $Warning = $null, + $Critical = $null, [switch]$NoPerfData, [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 + [int]$Verbosity = 0 ); $PendingUpdates = Get-IcingaUpdatesPending; diff --git a/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 b/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 index bfb3ca3..95aa13f 100644 --- a/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 @@ -45,8 +45,8 @@ Import-IcingaLib icinga\plugin; function Invoke-IcingaCheckUsedPartitionSpace() { param( - [int]$Warning = $null, - [int]$Critical = $null, + $Warning = $null, + $Critical = $null, [array]$Include = @(), [array]$Exclude = @(), [switch]$NoPerfData, diff --git a/lib/plugins/Invoke-IcingaCheckUsers.psm1 b/lib/plugins/Invoke-IcingaCheckUsers.psm1 index 4a13833..20ca89b 100644 --- a/lib/plugins/Invoke-IcingaCheckUsers.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUsers.psm1 @@ -37,8 +37,8 @@ function Invoke-IcingaCheckUsers() { param ( [array]$Username, - [int]$Warning = $null, - [int]$Critical = $null, + $Warning = $null, + $Critical = $null, [switch]$NoPerfData, [ValidateSet(0, 1, 2, 3)] [int]$Verbosity = 0 From 65d80118bb3b1b357b3994d4cce17732d026ecf7 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 29 Oct 2019 10:51:39 +0100 Subject: [PATCH 176/259] Add default status for service check plugin --- lib/plugins/Invoke-IcingaCheckService.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/plugins/Invoke-IcingaCheckService.psm1 b/lib/plugins/Invoke-IcingaCheckService.psm1 index 59975d9..73de9ba 100644 --- a/lib/plugins/Invoke-IcingaCheckService.psm1 +++ b/lib/plugins/Invoke-IcingaCheckService.psm1 @@ -35,7 +35,7 @@ function Invoke-IcingaCheckService() param( [array]$Service, [ValidateSet('Stopped', 'StartPending', 'StopPending', 'Running', 'ContinuePending', 'PausePending', 'Paused')] - [string]$Status, + [string]$Status = 'Running', [ValidateSet(0, 1, 2, 3)] [int]$Verbosity = 0 ); From 401d08f66f66d93828c9d4889f709a146b7dd4b0 Mon Sep 17 00:00:00 2001 From: Crited Date: Tue, 29 Oct 2019 11:34:59 +0100 Subject: [PATCH 177/259] Documentation skeletons and actual documentation --- lib/core/tools/ConvertTo-ByteUnit.psm1 | 96 +++++++++++++++++++ lib/core/tools/ConvertTo-Seconds.psm1 | 23 ++++- lib/core/tools/Set-NumericNegative.psm1 | 16 ++++ lib/core/tools/Test-Numeric.psm1 | 14 +++ lib/plugins/Invoke-IcingaCheckEventlog.psm1 | 56 +++++++++++ .../Invoke-IcingaCheckPerfcounter.psm1 | 34 +++++++ 6 files changed, 238 insertions(+), 1 deletion(-) diff --git a/lib/core/tools/ConvertTo-ByteUnit.psm1 b/lib/core/tools/ConvertTo-ByteUnit.psm1 index ee132a0..67c8c33 100644 --- a/lib/core/tools/ConvertTo-ByteUnit.psm1 +++ b/lib/core/tools/ConvertTo-ByteUnit.psm1 @@ -1,3 +1,19 @@ +<# +.SYNOPSIS + Converts unit sizes to byte. +.DESCRIPTION + This module converts a given unit size to byte. + e.g Kilobyte to Byte. + + More Information on https://github.com/LordHepipud/icinga-module-windows +.EXAMPLE + PS> ConvertTo-Byte -Unit TB 200 + 200000000000000 +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> + function ConvertTo-Byte() { param( @@ -22,6 +38,22 @@ function ConvertTo-Byte() return $result; } +<# +.SYNOPSIS + Converts unit sizes to kilobyte. +.DESCRIPTION + This module converts a given unit size to kilobyte. + e.g byte to kilobyte. + + More Information on https://github.com/LordHepipud/icinga-module-windows +.EXAMPLE + PS> ConvertTo-KiloByte -Unit TB 200 + 200000000000 +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> + function ConvertTo-KiloByte() { param( @@ -46,6 +78,22 @@ function ConvertTo-KiloByte() return $result; } +<# +.SYNOPSIS + Converts unit sizes to megabyte. +.DESCRIPTION + This module converts a given unit size to megabyte. + e.g byte to megabyte. + + More Information on https://github.com/LordHepipud/icinga-module-windows +.EXAMPLE + PS> ConvertTo-KiloByte -Unit TB 200 + 200000000 +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> + function ConvertTo-MegaByte() { param( @@ -70,6 +118,22 @@ function ConvertTo-MegaByte() return $result; } +<# +.SYNOPSIS + Converts unit sizes to gigabyte. +.DESCRIPTION + This module converts a given unit size to gigabyte. + e.g byte to gigabyte. + + More Information on https://github.com/LordHepipud/icinga-module-windows +.EXAMPLE + PS> ConvertTo-GigaByte -Unit TB 200 + 200000 +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> + function ConvertTo-GigaByte() { param( @@ -94,6 +158,22 @@ function ConvertTo-GigaByte() return $result; } +<# +.SYNOPSIS + Converts unit sizes to terabyte. +.DESCRIPTION + This module converts a given unit size to terabyte. + e.g byte to terabyte. + + More Information on https://github.com/LordHepipud/icinga-module-windows +.EXAMPLE + PS> ConvertTo-TeraByte -Unit GB 2000000 + 2000 +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> + function ConvertTo-TeraByte() { param( @@ -118,6 +198,22 @@ function ConvertTo-TeraByte() return $result; } +<# +.SYNOPSIS + Converts unit sizes to petabyte. +.DESCRIPTION + This module converts a given unit size to petabyte. + e.g byte to petabyte. + + More Information on https://github.com/LordHepipud/icinga-module-windows +.EXAMPLE + PS> ConvertTo-PetaByte -Unit GB 2000000 + 2 +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> + function ConvertTo-PetaByte() { param( diff --git a/lib/core/tools/ConvertTo-Seconds.psm1 b/lib/core/tools/ConvertTo-Seconds.psm1 index 194f3ed..7553361 100644 --- a/lib/core/tools/ConvertTo-Seconds.psm1 +++ b/lib/core/tools/ConvertTo-Seconds.psm1 @@ -1,5 +1,26 @@ Import-IcingaLib core\tools; -# year month week days hours minutes seconds milliseconds + +<# +.SYNOPSIS + Converts unit to seconds. +.DESCRIPTION + This module converts a given time unit to seconds. + e.g hours to seconds. + + More Information on https://github.com/LordHepipud/icinga-module-windows + +.PARAMETER Value + Specify unit to be converted to seconds. Allowed units: ms, s, m, h, d, w, M, y + ms = miliseconds; s = seconds; m = minutes; h = hours; d = days; w = weeks; M = months; y = years; + + Like 20d for 20 days. +.EXAMPLE + PS> ConvertTo-Seconds 30d + 2592000 +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> function ConvertTo-Seconds() { diff --git a/lib/core/tools/Set-NumericNegative.psm1 b/lib/core/tools/Set-NumericNegative.psm1 index 394d72a..2ae24d9 100644 --- a/lib/core/tools/Set-NumericNegative.psm1 +++ b/lib/core/tools/Set-NumericNegative.psm1 @@ -1,3 +1,19 @@ +<# +.SYNOPSIS + Sets nummeric values to be negative +.DESCRIPTION + This module sets a numeric value to be negative. + e.g 12 to -12 + + More Information on https://github.com/LordHepipud/icinga-module-windows +.EXAMPLE + PS> Set-NumericNegative 32 + -32 +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> + function Set-NumericNegative() { diff --git a/lib/core/tools/Test-Numeric.psm1 b/lib/core/tools/Test-Numeric.psm1 index 8d3fca9..ad67b36 100644 --- a/lib/core/tools/Test-Numeric.psm1 +++ b/lib/core/tools/Test-Numeric.psm1 @@ -1,3 +1,17 @@ +<# +.SYNOPSIS + Tests whether a value is numeric +.DESCRIPTION + This module tests whether a value is numeric + + More Information on https://github.com/LordHepipud/icinga-module-windows +.EXAMPLE + PS> Test-Numeric 32 + True +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> function Test-Numeric ($number) { return $number -Match "^[\d\.]+$"; } diff --git a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 index 4e92802..353a21a 100644 --- a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 +++ b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 @@ -1,5 +1,61 @@ Import-IcingaLib icinga\plugin; +<# +.SYNOPSIS + ??? +.DESCRIPTION + ??? + e.g + + More Information on https://github.com/LordHepipud/icinga-module-windows +.FUNCTIONALITY + ??? + Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. +.EXAMPLE + PS> +.EXAMPLE + PS> +.EXAMPLE + PS> +.EXAMPLE + PS> +.PARAMETER Warning + Used to specify a Warning threshold. In this case an ??? value. +.PARAMETER Critical + Used to specify a Critical threshold. In this case an ??? value. +.PARAMETER LogName + Used to specify a certain log. +.PARAMETER IncludeEventId + Used to specify an array of events identified by their id to be included. +.PARAMETER ExcludeEventId + Used to specify an array of events identified by their id to be excluded. +.PARAMETER IncludeUsername + Used to specify an array of usernames within the eventlog to be included. +.PARAMETER ExcludeUsername + Used to specify an array of usernames within the eventlog to be excluded. +.PARAMETER IncludeEntryType + Used to specify an array of entry types within the eventlog to be included. +.PARAMETER ExcludeEntryType + Used to specify an array of entry types within the eventlog to be excluded. +.PARAMETER IncludeMessage + Used to specify an array of messages within the eventlog to be included. +.PARAMETER ExcludeMessage + Used to specify an array of messages within the eventlog to be excluded. +.PARAMETER After + ??? +.PARAMETER Before + ??? +.PARAMETER DisableTimeCache + Switch to disable the time cache on a check. If this parameter is set the time cache is disabled. +.INPUTS + System.String +.OUTPUTS + System.String +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> + function Invoke-IcingaCheckEventlog() { param( diff --git a/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 b/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 index c9b0588..e771716 100644 --- a/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 +++ b/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 @@ -1,5 +1,39 @@ Import-IcingaLib icinga\plugin; +<# +.SYNOPSIS + Performs checks on various performance counter +.DESCRIPTION + Invoke-IcingaCheckDirectory returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. + e.g + + More Information on https://github.com/LordHepipud/icinga-module-windows +.FUNCTIONALITY + This module is intended to be used to perform checks on different performance counter. + Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. +.EXAMPLE + PS> +.EXAMPLE + PS> +.EXAMPLE + PS> +.EXAMPLE + PS> +.PARAMETER Warning + Used to specify a Warning threshold. In this case an ??? value. +.PARAMETER Critical + Used to specify a Critical threshold. In this case an ??? value. +.PARAMETER PerfCounter + Used to specify an array of performance counter to check against. +.INPUTS + System.String +.OUTPUTS + System.String +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> + function Invoke-IcingaCheckPerfcounter() { param( From f899c6f01097db14d37e72c86d12e7038857c10b Mon Sep 17 00:00:00 2001 From: Crited Date: Tue, 29 Oct 2019 15:40:35 +0100 Subject: [PATCH 178/259] Changes Performance Counter category output --- lib/core/perfcounter/Show-IcingaPerformanceCounters.psm1 | 2 +- lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/core/perfcounter/Show-IcingaPerformanceCounters.psm1 b/lib/core/perfcounter/Show-IcingaPerformanceCounters.psm1 index 5080aa6..2d2bb80 100644 --- a/lib/core/perfcounter/Show-IcingaPerformanceCounters.psm1 +++ b/lib/core/perfcounter/Show-IcingaPerformanceCounters.psm1 @@ -53,5 +53,5 @@ function Show-IcingaPerformanceCounters() $counters.Add('error', $_.Exception.Message); } - return $counters; + return $counters.Keys; } diff --git a/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 b/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 index 49e29e7..fdbf42b 100644 --- a/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 +++ b/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 @@ -1,6 +1,6 @@ function Get-IcingaMemoryPerformanceCounter() { - $MemoryStart = (Show-IcingaPerformanceCounters -CounterCategory 'Memory').Keys; + $MemoryStart = (Show-IcingaPerformanceCounters -CounterCategory 'Memory'); $MemoryCounter = New-IcingaPerformanceCounterArray -Counter $MemoryStart; [hashtable]$Result = @{}; From 2314ef6f76a1c27812a8fe0d17a1abd97d181fd7 Mon Sep 17 00:00:00 2001 From: Crited Date: Tue, 29 Oct 2019 16:02:31 +0100 Subject: [PATCH 179/259] Added Documentation/Changed Documentation --- lib/plugins/Invoke-IcingaCheckEventlog.psm1 | 39 ++++++++++++------- .../Invoke-IcingaCheckPerfcounter.psm1 | 15 ++++--- lib/plugins/Invoke-IcingaCheckUptime.psm1 | 5 +-- 3 files changed, 34 insertions(+), 25 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 index 353a21a..1cea274 100644 --- a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 +++ b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 @@ -2,27 +2,36 @@ Import-IcingaLib icinga\plugin; <# .SYNOPSIS - ??? + Checks how many eventlog occurences of a given type there are. .DESCRIPTION - ??? - e.g + Invoke-IcingaCheckEventlog returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. + e.g Eventlog returns 500 entrys with the specified parameters, WARNING is set to 200, CRITICAL is set to 800. Thereby the check will return WARNING. More Information on https://github.com/LordHepipud/icinga-module-windows .FUNCTIONALITY - ??? + This Module is intended to be used to check how many eventlog occurences of a given type there are. Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. .EXAMPLE - PS> + PS> Invoke-IcingaCheckEventlog -LogName Application -IncludeEntryType Warning -Warning 100 -Critical 1000 + [WARNING]: Check package "EventLog" is [WARNING] + | 'EventId_508'=2c;; 'EventId_2002'=586c;; 'EventId_63'=6c;; 'EventId_2248216578'=1364c;; 'EventId_1008'=1745c;; 'EventId_2147489653'=1c;; 'EventId_636'=3c;; 'EventId_2147484656'=1c;; 'EventId_2147489654'=1c;; 'EventId_640'=3c;; 'EventId_533'=1c;; + 1 + PS> Invoke-IcingaCheckEventlog -LogName Application -IncludeEntryType Warning -Warning 100 -Critical 1000 + [OK]: Check package "EventLog" is [OK]| + 0 .EXAMPLE - PS> -.EXAMPLE - PS> -.EXAMPLE - PS> + PS> Invoke-IcingaCheckEventlog -LogName Application -IncludeEntryType Warning -Warning 100 -Critical 1000 + [WARNING]: Check package "EventLog" is [WARNING] + | 'EventId_508'=2c;; 'EventId_2002'=586c;; 'EventId_63'=6c;; 'EventId_2248216578'=1364c;; 'EventId_1008'=1745c;; 'EventId_2147489653'=1c;; 'EventId_636'=3c;; 'EventId_2147484656'=1c;; 'EventId_2147489654'=1c;; 'EventId_640'=3c;; 'EventId_533'=1c;; + 1 + PS> Invoke-IcingaCheckEventlog -LogName Application -IncludeEntryType Warning -Warning 100 -Critical 1000 -DisableTimeCache + [WARNING]: Check package "EventLog" is [WARNING] + | 'EventId_508'=2c;; 'EventId_2002'=586c;; 'EventId_63'=6c;; 'EventId_2248216578'=1364c;; 'EventId_1008'=1745c;; 'EventId_2147489653'=1c;; 'EventId_636'=3c;; 'EventId_2147484656'=1c;; 'EventId_2147489654'=1c;; 'EventId_640'=3c;; 'EventId_533'=1c;; + 1 .PARAMETER Warning - Used to specify a Warning threshold. In this case an ??? value. + Used to specify a Warning threshold. .PARAMETER Critical - Used to specify a Critical threshold. In this case an ??? value. + Used to specify a Critical threshold. .PARAMETER LogName Used to specify a certain log. .PARAMETER IncludeEventId @@ -42,11 +51,13 @@ Import-IcingaLib icinga\plugin; .PARAMETER ExcludeMessage Used to specify an array of messages within the eventlog to be excluded. .PARAMETER After - ??? + Used to specify a date like dd.mm.yyyy and every eventlog entry after that date will be considered. .PARAMETER Before - ??? + Used to specify a date like dd.mm.yyyy and every eventlog entry before that date will be considered. .PARAMETER DisableTimeCache Switch to disable the time cache on a check. If this parameter is set the time cache is disabled. + After the check has been run once, the next check instance will filter through the eventlog from the point the last check ended. + This is due to the time cache, when disabled the whole eventlog is checked instead. .INPUTS System.String .OUTPUTS diff --git a/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 b/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 index e771716..50726ec 100644 --- a/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 +++ b/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 @@ -5,20 +5,19 @@ Import-IcingaLib icinga\plugin; Performs checks on various performance counter .DESCRIPTION Invoke-IcingaCheckDirectory returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. - e.g + Use "Show-IcingaPerformanceCounterCategories" to see all performance counter categories available. + To gain insight on an specific performance counter use "Show-IcingaPerformanceCounters " + e.g ' More Information on https://github.com/LordHepipud/icinga-module-windows .FUNCTIONALITY This module is intended to be used to perform checks on different performance counter. Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. .EXAMPLE - PS> -.EXAMPLE - PS> -.EXAMPLE - PS> -.EXAMPLE - PS> + PS> Invoke-IcingaCheckPerfCounter -PerfCounter '\processor(*)\% processor time' -Warning 60 -Critical 90 + [WARNING]: Check package "Performance Counter" is [WARNING] + | 'processor1_processor_time'=68.95;60;90 'processor3_processor_time'=4.21;60;90 'processor5_processor_time'=9.5;60;90 'processor_Total_processor_time'=20.6;60;90 'processor0_processor_time'=5.57;60;90 'processor2_processor_time'=0;60;90 'processor4_processor_time'=6.66;60;90 + 1 .PARAMETER Warning Used to specify a Warning threshold. In this case an ??? value. .PARAMETER Critical diff --git a/lib/plugins/Invoke-IcingaCheckUptime.psm1 b/lib/plugins/Invoke-IcingaCheckUptime.psm1 index f71a871..c4da1ac 100644 --- a/lib/plugins/Invoke-IcingaCheckUptime.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUptime.psm1 @@ -12,15 +12,14 @@ Import-IcingaLib core\tools; .FUNCTIONALITY This module is intended to check how long a Windows system has been up for. Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. - .EXAMPLE PS> Invoke-IcingaCheckUptime -Warning 18d -Critical 20d [WARNING]: Check package "Windows Uptime: Days: 19 Hours: 13 Minutes: 48 Seconds: 29" is [WARNING] | 'Windows Uptime'=1691309,539176s;1555200;1728000 -.PARAMETER IcingaCheckUsers_String_Warning +.PARAMETER Warning Used to specify a Warning threshold. In this case a string. Allowed units include: ms, s, m, h, d, w, M, y -.PARAMETER IcingaCheckUsers_String_Critical +.PARAMETER Critical Used to specify a Critical threshold. In this case a string. Allowed units include: ms, s, m, h, d, w, M, y .INPUTS From af76cd2a2843353f9940fe18e67ccc19e4081b73 Mon Sep 17 00:00:00 2001 From: Crited Date: Tue, 29 Oct 2019 16:08:27 +0100 Subject: [PATCH 180/259] Generic Conversion for Bytes --- lib/core/tools/Convert-Bytes.psm1 | 30 ++++++++++++++++++++++++++++++ 1 file changed, 30 insertions(+) create mode 100644 lib/core/tools/Convert-Bytes.psm1 diff --git a/lib/core/tools/Convert-Bytes.psm1 b/lib/core/tools/Convert-Bytes.psm1 new file mode 100644 index 0000000..445b1c4 --- /dev/null +++ b/lib/core/tools/Convert-Bytes.psm1 @@ -0,0 +1,30 @@ +function Convert-Bytes() +{ + param( + [string]$Value, + [string]$Unit + ); + + If (($Value -Match "(^[0-9]*) ?(B|b|kb|KB|kB|Kb|mb|Mb|mB|MB|Gb|gB|gb|GB|tb|Tb|tB|TB|PT|pt|pT|Pt)")) { + [single]$CurrentValue = $Matches[1]; + [string]$CurrentUnit = $Matches[2]; + + $CurrentValue = ConvertTo-Byte $CurrentValue $CurrentUnit; + + switch ($Unit) { + { 'B' -contains $_} { $FinalValue = ConvertTo-Byte $CurrentValue -Unit B; $boolOption = $true;} + { 'KB' -contains $_} { $FinalValue = ConvertTo-KiloByte $CurrentValue -Unit B; $boolOption = $true;} + { 'MB' -contains $_} { $FinalValue = ConvertTo-MegaByte $CurrentValue -Unit B; $boolOption = $true;} + { 'GB' -contains $_} { $FinalValue = ConvertTo-GigaByte $CurrentValue -Unit B; $boolOption = $true;} + { 'TB' -contains $_} { $FinalValue = ConvertTo-TeraByte $CurrentValue -Unit B; $boolOption = $true;} + { 'PT' -contains $_} { $FinalValue = ConvertTo-PetaByte $CurrentValue -Unit B; $boolOption = $true;} + default { + if (-Not $boolOption) { + Throw 'Invalid input'; + } + } + } + return $FinalValue; + } + Throw 'Invalid input'; +} \ No newline at end of file From dddbec62311dca33f6e9cfd32574c483992f6b7d Mon Sep 17 00:00:00 2001 From: Crited Date: Tue, 29 Oct 2019 16:39:44 +0100 Subject: [PATCH 181/259] Add Memory-Check, with extension for memory-provider (pagefile) --- lib/plugins/Invoke-IcingaCheckMemory.psm1 | 63 +++++++++++++++++++ .../Get-IcingaMemoryPerformanceCounter.psm1 | 14 +++++ 2 files changed, 77 insertions(+) create mode 100644 lib/plugins/Invoke-IcingaCheckMemory.psm1 diff --git a/lib/plugins/Invoke-IcingaCheckMemory.psm1 b/lib/plugins/Invoke-IcingaCheckMemory.psm1 new file mode 100644 index 0000000..a28f03f --- /dev/null +++ b/lib/plugins/Invoke-IcingaCheckMemory.psm1 @@ -0,0 +1,63 @@ +Import-IcingaLib provider\memory; + +<# +.SYNOPSIS + Checks on memory usage +.DESCRIPTION + Invoke-IcingaCheckMemory returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. + e.g memory is currently at 60% usage, WARNING is set to 50, CRITICAL is set to 90. In this case the check will return WARNING. + + More Information on https://github.com/LordHepipud/icinga-module-windows +.FUNCTIONALITY + This module is intended to be used to check on memory usage. + Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. +.EXAMPLE + PS>Invoke-IcingaCheckMemory -Verbosity 3 -Warning 60 -Critical 80 + [WARNING]: % Memory Check 78.74 is greater than 60 + 1 +.EXAMPLE + PS> Invoke-IcingaCheckMemory -Verbosity 3 -Warning 60 -Critical 80 -PageFile + [OK]: % Memory Check is 10.99 + 0 +.PARAMETER Warning + Used to specify a Warning threshold. In this case an integer value. +.PARAMETER Critical + Used to specify a Critical threshold. In this case an integer value. +.PARAMETER Pagefile + Switch which determines whether the pagefile should be used instead. + If not set memory will be checked. +.INPUTS + System.String +.OUTPUTS + System.String +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> + +function Invoke-IcingaCheckMemory() +{ + param( + $Critical = $null, + $Warning = $null, + [switch]$PageFile, + [ValidateSet(0, 1, 2, 3)] + [int]$Verbosity = 0 + ); + + if ($PageFile -eq $TRUE) { + $MemoryData = (Get-IcingaPageFilePerformanceCounter).'(*)\% usage'.'\Paging File(_Total)\% usage'.value + } else { + $MemoryData = (Get-IcingaMemoryPerformanceCounter).'% committed bytes in use'.value; + } + + $MemoryCheck = New-IcingaCheck -Name '% Memory Check' -Value $MemoryData -NoPerfData; + + $MemoryCheck.WarnOutOfRange( + ($Warning) + ).CritOutOfRange( + ($Critical) + ) | Out-Null; + + return (New-IcingaCheckresult -Check $MemoryCheck -NoPerfData $TRUE -Compile); +} \ No newline at end of file diff --git a/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 b/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 index fdbf42b..28ed1ae 100644 --- a/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 +++ b/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 @@ -11,3 +11,17 @@ function Get-IcingaMemoryPerformanceCounter() return $Result; } + +function Get-IcingaPageFilePerformanceCounter() +{ + $PageFileStart = (Show-IcingaPerformanceCounters -CounterCategory 'Paging File'); + $PageFileCounter = New-IcingaPerformanceCounterArray -Counter $PageFileStart; + [hashtable]$Result = @{}; + + foreach ($item in $PageFileCounter.Keys) { + $counter = $item.trimstart('\Paging File\'); + $Result.Add($counter, $PageFileCounter[$item]); + } + + return $Result; +} \ No newline at end of file From 63301e666d2fc5d5f88ca6b7466dd858730b9114 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Tue, 29 Oct 2019 17:55:40 +0100 Subject: [PATCH 182/259] Fixes broken service check due to content validation --- lib/plugins/Invoke-IcingaCheckService.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckService.psm1 b/lib/plugins/Invoke-IcingaCheckService.psm1 index 73de9ba..16049fb 100644 --- a/lib/plugins/Invoke-IcingaCheckService.psm1 +++ b/lib/plugins/Invoke-IcingaCheckService.psm1 @@ -59,11 +59,11 @@ function Invoke-IcingaCheckService() $FoundService = Get-IcingaServices -Service $Service; $ServiceName = Get-IcingaServiceCheckName -ServiceInput $Service -Service $FoundService; - $Status = ConvertTo-ServiceStatusCode -Status $Status; + $IntStatus = ConvertTo-ServiceStatusCode -Status $Status; $StatusRaw = $FoundService.Values.configuration.Status.raw; $IcingaCheck = New-IcingaCheck -Name $ServiceName -Value $StatusRaw -ObjectExists $FoundService -Translation $ProviderEnums.ServiceStatusName; - $IcingaCheck.CritIfNotMatch($Status) | Out-Null; + $IcingaCheck.CritIfNotMatch($IntStatus) | Out-Null; $ServicesPackage.AddCheck($IcingaCheck); } From 7aafed9d44fbf6acbf4a41aec17b6dcf72c627de Mon Sep 17 00:00:00 2001 From: Crited Date: Wed, 30 Oct 2019 08:37:24 +0100 Subject: [PATCH 183/259] Changes to Memory Check to support GB and Percentage --- lib/plugins/Invoke-IcingaCheckMemory.psm1 | 29 ++++++++++--------- .../Get-IcingaMemoryPerformanceCounter.psm1 | 22 +++++--------- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckMemory.psm1 b/lib/plugins/Invoke-IcingaCheckMemory.psm1 index a28f03f..b714d59 100644 --- a/lib/plugins/Invoke-IcingaCheckMemory.psm1 +++ b/lib/plugins/Invoke-IcingaCheckMemory.psm1 @@ -40,24 +40,27 @@ function Invoke-IcingaCheckMemory() param( $Critical = $null, $Warning = $null, + $CriticalPercent = $null, + $WarningPercent = $null, [switch]$PageFile, [ValidateSet(0, 1, 2, 3)] [int]$Verbosity = 0 ); - if ($PageFile -eq $TRUE) { - $MemoryData = (Get-IcingaPageFilePerformanceCounter).'(*)\% usage'.'\Paging File(_Total)\% usage'.value - } else { - $MemoryData = (Get-IcingaMemoryPerformanceCounter).'% committed bytes in use'.value; - } + $MemoryPackage = New-IcingaCheckPackage -Name 'Memory Usage' -OperatorAnd -Verbos $Verbosity; + $MemoryData = (Get-IcingaMemoryPerformanceCounterFormated); + - $MemoryCheck = New-IcingaCheck -Name '% Memory Check' -Value $MemoryData -NoPerfData; + $MemoryPerc = New-IcingaCheck -Name 'Memory Percent' -Value $MemoryData.'Memory %' -NoPerfData; + $MemoryByte = New-IcingaCheck -Name 'Memory GigaByte' -Value $MemoryData.'Memory GigaByte' -NoPerfData; + $PageFile = New-IcingaCheck -Name 'PageFile Percent' -Value $MemoryData.'PageFile %' -NoPerfData; - $MemoryCheck.WarnOutOfRange( - ($Warning) - ).CritOutOfRange( - ($Critical) - ) | Out-Null; - - return (New-IcingaCheckresult -Check $MemoryCheck -NoPerfData $TRUE -Compile); + # PageFile To-Do + $MemoryPerc.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; + $MemoryByte.WarnOutOfRange($WarningPercent).CritOutOfRange($CriticalPercent) | Out-Null; + + $MemoryPackage.AddCheck($MemoryPerc); + $MemoryPackage.AddCheck($MemoryByte); + + return (New-IcingaCheckResult -Check $MemoryPackage -NoPerfData $TRUE -Compile); } \ No newline at end of file diff --git a/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 b/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 index 28ed1ae..9fcf04b 100644 --- a/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 +++ b/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 @@ -1,27 +1,21 @@ function Get-IcingaMemoryPerformanceCounter() { - $MemoryStart = (Show-IcingaPerformanceCounters -CounterCategory 'Memory'); - $MemoryCounter = New-IcingaPerformanceCounterArray -Counter $MemoryStart; + $MemoryPercent = New-IcingaPerformanceCounterArray -Counter "\Memory\% committed bytes in use","\Memory\committed bytes","\Paging File(_Total)\% usage" [hashtable]$Result = @{}; - foreach ($item in $MemoryCounter.Keys) { - $counter = $item.trimstart('\Memory\'); - $Result.Add($counter, $MemoryCounter[$item]); + foreach ($item in $MemoryPercent.Keys) { + $Result.Add($item, $MemoryPercent[$item]); } return $Result; } -function Get-IcingaPageFilePerformanceCounter() +function Get-IcingaMemoryPerformanceCounterFormated() { - $PageFileStart = (Show-IcingaPerformanceCounters -CounterCategory 'Paging File'); - $PageFileCounter = New-IcingaPerformanceCounterArray -Counter $PageFileStart; [hashtable]$Result = @{}; - - foreach ($item in $PageFileCounter.Keys) { - $counter = $item.trimstart('\Paging File\'); - $Result.Add($counter, $PageFileCounter[$item]); - } - + $Result.Add('Memory %', (Get-IcingaMemoryPerformanceCounter).'\Memory\% committed bytes in use'.value); + $Result.Add('Memory GigaByte', (ConvertTo-GigaByte ([decimal](Get-IcingaMemoryPerformanceCounter).'\Memory\committed bytes'.value) -Unit Byte)); + $Result.Add('PageFile %', (Get-IcingaMemoryPerformanceCounter).'\Paging File(_Total)\% usage'.value); + return $Result; } \ No newline at end of file From 34d33e9b8862a0ef35ca8dbe78ad7bc805fe6a70 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 30 Oct 2019 09:32:22 +0100 Subject: [PATCH 184/259] Add NoPerfData and Units to Memory check --- lib/plugins/Invoke-IcingaCheckMemory.psm1 | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckMemory.psm1 b/lib/plugins/Invoke-IcingaCheckMemory.psm1 index b714d59..6c5ecc3 100644 --- a/lib/plugins/Invoke-IcingaCheckMemory.psm1 +++ b/lib/plugins/Invoke-IcingaCheckMemory.psm1 @@ -44,16 +44,17 @@ function Invoke-IcingaCheckMemory() $WarningPercent = $null, [switch]$PageFile, [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 + [int]$Verbosity = 0, + [switch]$NoPerfData ); $MemoryPackage = New-IcingaCheckPackage -Name 'Memory Usage' -OperatorAnd -Verbos $Verbosity; $MemoryData = (Get-IcingaMemoryPerformanceCounterFormated); - $MemoryPerc = New-IcingaCheck -Name 'Memory Percent' -Value $MemoryData.'Memory %' -NoPerfData; - $MemoryByte = New-IcingaCheck -Name 'Memory GigaByte' -Value $MemoryData.'Memory GigaByte' -NoPerfData; - $PageFile = New-IcingaCheck -Name 'PageFile Percent' -Value $MemoryData.'PageFile %' -NoPerfData; + $MemoryPerc = New-IcingaCheck -Name 'Memory Percent' -Value $MemoryData['Memory %'] -Unit '%'; + $MemoryByte = New-IcingaCheck -Name 'Memory GigaByte' -Value $MemoryData['Memory GigaByte'] -Unit 'GB'; + $PageFileCheck = New-IcingaCheck -Name 'PageFile Percent' -Value $MemoryData['PageFile %'] -Unit '%'; # PageFile To-Do $MemoryPerc.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; @@ -61,6 +62,7 @@ function Invoke-IcingaCheckMemory() $MemoryPackage.AddCheck($MemoryPerc); $MemoryPackage.AddCheck($MemoryByte); + $MemoryPackage.AddCheck($PageFileCheck); - return (New-IcingaCheckResult -Check $MemoryPackage -NoPerfData $TRUE -Compile); -} \ No newline at end of file + return (New-IcingaCheckResult -Check $MemoryPackage -NoPerfData $NoPerfData -Compile); +} From d2ef01eae5af7ad04a92421570df2ba0905806b3 Mon Sep 17 00:00:00 2001 From: Crited Date: Wed, 30 Oct 2019 10:44:44 +0100 Subject: [PATCH 185/259] Fix for IcingaMemoryCheck; Improve speed, changed provider --- lib/plugins/Invoke-IcingaCheckMemory.psm1 | 57 ++++++++++++++----- .../Get-IcingaMemoryPerformanceCounter.psm1 | 23 ++++---- 2 files changed, 53 insertions(+), 27 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckMemory.psm1 b/lib/plugins/Invoke-IcingaCheckMemory.psm1 index 6c5ecc3..4ec252a 100644 --- a/lib/plugins/Invoke-IcingaCheckMemory.psm1 +++ b/lib/plugins/Invoke-IcingaCheckMemory.psm1 @@ -1,4 +1,5 @@ Import-IcingaLib provider\memory; +Import-IcingaLib core\tools; <# .SYNOPSIS @@ -16,20 +17,44 @@ Import-IcingaLib provider\memory; [WARNING]: % Memory Check 78.74 is greater than 60 1 .EXAMPLE - PS> Invoke-IcingaCheckMemory -Verbosity 3 -Warning 60 -Critical 80 -PageFile - [OK]: % Memory Check is 10.99 - 0 + PS> Invoke-IcingaCheckMemory -Unit GB -Critical 1850000KB -Warning 2500000KB -CriticalPercent 80 -WarningPercent 30 -Verbosity 3 + [Warning]: Check package "Memory Usage" is [Warning] (Match All) + \_ [WARNING]: Memory Percent 35.95% is greater than 30% + \_ [OK]: PageFile Percent is 16.42% + | 'Memory_Percent'=35.95%;30;80;0;100 'Used_Bytes_in_GB'=3.44;2.5;1.85 'PageFile_Percent'=16.42%;;;0;100 + 1 .PARAMETER Warning - Used to specify a Warning threshold. In this case an integer value. + Used to specify a Warning threshold. In this case an string value. + + The string has to be like, "20B", "20KB", "20MB", "20GB", "20TB", "20TB" .PARAMETER Critical - Used to specify a Critical threshold. In this case an integer value. + Used to specify a Critical threshold. In this case an string value. + + The string has to be like, "20B", "20KB", "20MB", "20GB", "20TB", "20TB" + .PARAMETER Pagefile Switch which determines whether the pagefile should be used instead. If not set memory will be checked. + +.PARAMETER CriticalPercent + Used to specify a Critical threshold. In this case an integer value. + + Like 30 for 30%. If memory usage is above 30%, the check will return CRITICAL. + +.PARAMETER CriticalPercent + Used to specify a Critical threshold. In this case an integer value. + + Like 30 for 30%. If memory usage is above 30%, the check will return Warning. + +.PARAMETER Unit + Determines output Unit. Allowed Units: 'B', 'KB', 'MB', 'GB', 'TB', 'PB' + .INPUTS System.String + .OUTPUTS System.String + .LINK https://github.com/LordHepipud/icinga-module-windows .NOTES @@ -38,8 +63,9 @@ Import-IcingaLib provider\memory; function Invoke-IcingaCheckMemory() { param( - $Critical = $null, - $Warning = $null, + [string]$Critical = $null, + [string]$Warning = $null, + [string]$Unit = 'B', $CriticalPercent = $null, $WarningPercent = $null, [switch]$PageFile, @@ -48,21 +74,24 @@ function Invoke-IcingaCheckMemory() [switch]$NoPerfData ); + $CrticalConverted = Convert-Bytes $Critical -Unit $Unit + $WarningConverted = Convert-Bytes $Warning -Unit $Unit + $MemoryPackage = New-IcingaCheckPackage -Name 'Memory Usage' -OperatorAnd -Verbos $Verbosity; - $MemoryData = (Get-IcingaMemoryPerformanceCounterFormated); + $MemoryData = (Get-IcingaMemoryPerformanceCounter); - $MemoryPerc = New-IcingaCheck -Name 'Memory Percent' -Value $MemoryData['Memory %'] -Unit '%'; - $MemoryByte = New-IcingaCheck -Name 'Memory GigaByte' -Value $MemoryData['Memory GigaByte'] -Unit 'GB'; - $PageFileCheck = New-IcingaCheck -Name 'PageFile Percent' -Value $MemoryData['PageFile %'] -Unit '%'; + $MemoryPerc = New-IcingaCheck -Name 'Memory Percent' -Value $MemoryData['Memory Used %'] -Unit '%'; + $MemoryByte = New-IcingaCheck -Name "Used Bytes in $Unit" -Value (Convert-Bytes ([string]::Format('{0}B', $MemoryData['Memory used Bytes'])) -Unit $Unit); + #$PageFileCheck = New-IcingaCheck -Name 'PageFile Percent' -Value $MemoryData['PageFile %'] -Unit '%'; # PageFile To-Do - $MemoryPerc.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; - $MemoryByte.WarnOutOfRange($WarningPercent).CritOutOfRange($CriticalPercent) | Out-Null; + $MemoryByte.WarnOutOfRange($WarningConverted).CritOutOfRange($CrticalConverted) | Out-Null; + $MemoryPerc.WarnOutOfRange($WarningPercent).CritOutOfRange($CriticalPercent) | Out-Null; $MemoryPackage.AddCheck($MemoryPerc); $MemoryPackage.AddCheck($MemoryByte); - $MemoryPackage.AddCheck($PageFileCheck); + #$MemoryPackage.AddCheck($PageFileCheck); return (New-IcingaCheckResult -Check $MemoryPackage -NoPerfData $NoPerfData -Compile); } diff --git a/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 b/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 index 9fcf04b..e0fafc8 100644 --- a/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 +++ b/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 @@ -1,21 +1,18 @@ function Get-IcingaMemoryPerformanceCounter() { - $MemoryPercent = New-IcingaPerformanceCounterArray -Counter "\Memory\% committed bytes in use","\Memory\committed bytes","\Paging File(_Total)\% usage" - [hashtable]$Result = @{}; + $MemoryPercent = New-IcingaPerformanceCounterArray -Counter "\Memory\% committed bytes in use","\Memory\Available Bytes","\Paging File(_Total)\% usage" + [hashtable]$Initial = @{}; + [hashtable]$MemoryData = @{}; foreach ($item in $MemoryPercent.Keys) { - $Result.Add($item, $MemoryPercent[$item]); + $Initial.Add($item, $MemoryPercent[$item]); } - return $Result; -} + $MemoryData.Add('Memory Available Bytes', [decimal]($Initial.'\Memory\Available Bytes'.value)); + $MemoryData.Add('Memory Total Bytes', (Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory); + $MemoryData.Add('Memory Used Bytes', $MemoryData.'Memory Total Bytes' - $MemoryData.'Memory Available Bytes'); + $MemoryData.Add('Memory Used %', $MemoryData.'Memory Available Bytes' / $MemoryData.'Memory Total Bytes' * 100); + $MemoryData.Add('PageFile %', $Initial.'\Paging File(_Total)\% usage'.value); -function Get-IcingaMemoryPerformanceCounterFormated() -{ - [hashtable]$Result = @{}; - $Result.Add('Memory %', (Get-IcingaMemoryPerformanceCounter).'\Memory\% committed bytes in use'.value); - $Result.Add('Memory GigaByte', (ConvertTo-GigaByte ([decimal](Get-IcingaMemoryPerformanceCounter).'\Memory\committed bytes'.value) -Unit Byte)); - $Result.Add('PageFile %', (Get-IcingaMemoryPerformanceCounter).'\Paging File(_Total)\% usage'.value); - - return $Result; + return $MemoryData; } \ No newline at end of file From 57df8e1424d08e16bcd89cdc3a0440b869ec7de2 Mon Sep 17 00:00:00 2001 From: Crited Date: Wed, 30 Oct 2019 13:52:37 +0100 Subject: [PATCH 186/259] Add Conversion for both IEC and SI Byte-Suffix (10^X & 2^X) --- lib/core/tools/Convert-Bytes.psm1 | 16 +- lib/core/tools/ConvertTo-ByteUnitIEC.psm1 | 143 ++++++++++++++++++ ...yteUnit.psm1 => ConvertTo-ByteUnitSI.psm1} | 2 +- 3 files changed, 157 insertions(+), 4 deletions(-) create mode 100644 lib/core/tools/ConvertTo-ByteUnitIEC.psm1 rename lib/core/tools/{ConvertTo-ByteUnit.psm1 => ConvertTo-ByteUnitSI.psm1} (99%) diff --git a/lib/core/tools/Convert-Bytes.psm1 b/lib/core/tools/Convert-Bytes.psm1 index 445b1c4..3fc538f 100644 --- a/lib/core/tools/Convert-Bytes.psm1 +++ b/lib/core/tools/Convert-Bytes.psm1 @@ -5,19 +5,29 @@ function Convert-Bytes() [string]$Unit ); - If (($Value -Match "(^[0-9]*) ?(B|b|kb|KB|kB|Kb|mb|Mb|mB|MB|Gb|gB|gb|GB|tb|Tb|tB|TB|PT|pt|pT|Pt)")) { + If (($Value -Match "(^[0-9]*) ?(B|KB|MB|GB|TB|PT|Kibi|Mibi|Gibi|Tibi|Pibi)")) { [single]$CurrentValue = $Matches[1]; [string]$CurrentUnit = $Matches[2]; - $CurrentValue = ConvertTo-Byte $CurrentValue $CurrentUnit; + switch ($CurrentUnit) { + { 'KiBi', 'Mibi', 'Gibi', 'Tibi', 'Pibi' -contains $_} { $CurrentValue = ConvertTo-ByteIEC $CurrentValue $CurrentUnit; $boolOption = $true;} + { 'KB', 'MB', 'GB', 'TB', 'PB' -contains $_} { $CurrentValue = ConvertTo-ByteSI $CurrentValue $CurrentUnit; $boolOption = $true;} + } + switch ($Unit) { - { 'B' -contains $_} { $FinalValue = ConvertTo-Byte $CurrentValue -Unit B; $boolOption = $true;} + #{ 'B' -contains $_} { $FinalValue = ConvertTo-ByteSI $CurrentValue -Unit B; $boolOption = $true;} { 'KB' -contains $_} { $FinalValue = ConvertTo-KiloByte $CurrentValue -Unit B; $boolOption = $true;} { 'MB' -contains $_} { $FinalValue = ConvertTo-MegaByte $CurrentValue -Unit B; $boolOption = $true;} { 'GB' -contains $_} { $FinalValue = ConvertTo-GigaByte $CurrentValue -Unit B; $boolOption = $true;} { 'TB' -contains $_} { $FinalValue = ConvertTo-TeraByte $CurrentValue -Unit B; $boolOption = $true;} { 'PT' -contains $_} { $FinalValue = ConvertTo-PetaByte $CurrentValue -Unit B; $boolOption = $true;} + { 'Kibi' -contains $_} { $FinalValue = ConvertTo-KibiByte $CurrentValue -Unit B; $boolOption = $true;} + { 'Mibi' -contains $_} { $FinalValue = ConvertTo-MibiByte $CurrentValue -Unit B; $boolOption = $true;} + { 'Gibi' -contains $_} { $FinalValue = ConvertTo-GibiByte $CurrentValue -Unit B; $boolOption = $true;} + { 'Tibi' -contains $_} { $FinalValue = ConvertTo-TibiByte $CurrentValue -Unit B; $boolOption = $true;} + { 'Piti' -contains $_} { $FinalValue = ConvertTo-PetaByte $CurrentValue -Unit B; $boolOption = $true;} + default { if (-Not $boolOption) { Throw 'Invalid input'; diff --git a/lib/core/tools/ConvertTo-ByteUnitIEC.psm1 b/lib/core/tools/ConvertTo-ByteUnitIEC.psm1 new file mode 100644 index 0000000..ec9256c --- /dev/null +++ b/lib/core/tools/ConvertTo-ByteUnitIEC.psm1 @@ -0,0 +1,143 @@ +function ConvertTo-ByteIEC() +{ + param( + [single]$Value, + [string]$Unit + ); + + switch ($Unit) { + { 'B', 'Byte' -contains $_ } { $result = $Value; $boolOption = $true; } + { 'Kibi', 'KibiByte' -contains $_ } { $result = ($Value * [math]::Pow(2, 10)); $boolOption = $true; } + { 'Mibi', 'MibiByte' -contains $_ } { $result = ($Value * [math]::Pow(2, 20)); $boolOption = $true; } + { 'Gibi', 'GibiByte' -contains $_ } { $result = ($Value * [math]::Pow(2, 30)); $boolOption = $true; } + { 'Tibi', 'TibiByte' -contains $_ } { $result = ($Value * [math]::Pow(2, 40)); $boolOption = $true; } + { 'Piti', 'PitiByte' -contains $_ } { $result = ($Value * [math]::Pow(2, 50)); $boolOption = $true; } + default { + if (-Not $boolOption) { + Throw 'Invalid input'; + } + } + } + + return $result; +} + +function ConvertTo-KibiByte() +{ + param( + [single]$Value, + [string]$Unit + ); + + switch ($Unit) { + { 'B', 'Byte' -contains $_ } { $result = ($Value / [math]::Pow(2, 10)); $boolOption = $true; } + { 'Kibi', 'KibiByte' -contains $_ } { $result = $Value; $boolOption = $true; } + { 'Mibi', 'MibiByte' -contains $_ } { $result = ($Value * [math]::Pow(2, 10)); $boolOption = $true; } + { 'Gibi', 'GibiByte' -contains $_ } { $result = ($Value * [math]::Pow(2, 20)); $boolOption = $true; } + { 'Tibi', 'TibiByte' -contains $_ } { $result = ($Value * [math]::Pow(2, 30)); $boolOption = $true; } + { 'Piti', 'PitiByte' -contains $_ } { $result = ($Value * [math]::Pow(2, 40)); $boolOption = $true; } + default { + if (-Not $boolOption) { + Throw 'Invalid input'; + } + } + } + + return $result; +} + +function ConvertTo-MibiByte() +{ + param( + [single]$Value, + [string]$Unit + ); + + switch ($Unit) { + { 'B', 'Byte' -contains $_ } { $result = ($Value / [math]::Pow(2, 20)); $boolOption = $true; } + { 'Kibi', 'KibiByte' -contains $_ } { $result = ($Value / [math]::Pow(2, 10)); $boolOption = $true; } + { 'Mibi', 'MibiByte' -contains $_ } { $result = $Value; $boolOption = $true; } + { 'Gibi', 'GibiByte' -contains $_ } { $result = ($Value * [math]::Pow(2, 10)); $boolOption = $true; } + { 'Tibi', 'TibiByte' -contains $_ } { $result = ($Value * [math]::Pow(2, 20)); $boolOption = $true; } + { 'Piti', 'PitiByte' -contains $_ } { $result = ($Value * [math]::Pow(2, 30)); $boolOption = $true; } + default { + if (-Not $boolOption) { + Throw 'Invalid input'; + } + } + } + + return $result; +} + +function ConvertTo-GibiByte() +{ + param( + [single]$Value, + [string]$Unit + ); + + switch ($Unit) { + { 'B', 'Byte' -contains $_ } { $result = ($Value / [math]::Pow(2, 30)); $boolOption = $true; } + { 'Kibi', 'KibiByte' -contains $_ } { $result = ($Value / [math]::Pow(2, 20)); $boolOption = $true; } + { 'Mibi', 'MibiByte' -contains $_ } { $result = ($Value / [math]::Pow(2, 10)); $boolOption = $true; } + { 'Gibi', 'GibiByte' -contains $_ } { $result = $Value; $boolOption = $true; } + { 'Tibi', 'TibiByte' -contains $_ } { $result = ($Value * [math]::Pow(2, 10)); $boolOption = $true; } + { 'Piti', 'PitiByte' -contains $_ } { $result = ($Value * [math]::Pow(2, 20)); $boolOption = $true; } + default { + if (-Not $boolOption) { + Throw 'Invalid input'; + } + } + } + + return $result; +} + +function ConvertTo-TibiByte() +{ + param( + [single]$Value, + [string]$Unit + ); + + switch ($Unit) { + { 'B', 'Byte' -contains $_ } { $result = ($Value / [math]::Pow(2, 40)); $boolOption = $true; } + { 'Kibi', 'KibiByte' -contains $_ } { $result = ($Value / [math]::Pow(2, 30)); $boolOption = $true; } + { 'Mibi', 'MibiByte' -contains $_ } { $result = ($Value / [math]::Pow(2, 20)); $boolOption = $true; } + { 'Gibi', 'GibiByte' -contains $_ } { $result = ($Value / [math]::Pow(2, 10)); $boolOption = $true; } + { 'Tibi', 'TibiByte' -contains $_ } { $result = $Value; $boolOption = $true; } + { 'Piti', 'PitiByte' -contains $_ } { $result = ($Value * [math]::Pow(2, 10)); $boolOption = $true; } + default { + if (-Not $boolOption) { + Throw 'Invalid input'; + } + } + } + + return $result; +} + +function ConvertTo-PitiByte() +{ + param( + [single]$Value, + [string]$Unit + ); + + switch ($Unit) { + { 'B', 'Byte' -contains $_ } { $result = ($Value / [math]::Pow(2, 50)); $boolOption = $true; } + { 'Kibi', 'KibiByte' -contains $_ } { $result = ($Value / [math]::Pow(2, 40)); $boolOption = $true; } + { 'Mibi', 'MibiByte' -contains $_ } { $result = ($Value / [math]::Pow(2, 30)); $boolOption = $true; } + { 'Gibi', 'GibiByte' -contains $_ } { $result = ($Value / [math]::Pow(2, 20)); $boolOption = $true; } + { 'Tibi', 'TibiByte' -contains $_ } { $result = ($Value / [math]::Pow(2, 10)); $boolOption = $true; } + { 'Piti', 'PitiByte' -contains $_ } { $result = $Value; $boolOption = $true; } + default { + if (-Not $boolOption) { + Throw 'Invalid input'; + } + } + } + + return $result; +} diff --git a/lib/core/tools/ConvertTo-ByteUnit.psm1 b/lib/core/tools/ConvertTo-ByteUnitSI.psm1 similarity index 99% rename from lib/core/tools/ConvertTo-ByteUnit.psm1 rename to lib/core/tools/ConvertTo-ByteUnitSI.psm1 index 67c8c33..107dc42 100644 --- a/lib/core/tools/ConvertTo-ByteUnit.psm1 +++ b/lib/core/tools/ConvertTo-ByteUnitSI.psm1 @@ -14,7 +14,7 @@ .NOTES #> -function ConvertTo-Byte() +function ConvertTo-ByteSI() { param( [single]$Value, From f3c2d2a9d52a7624e117b2f9f12107bda2a11a7c Mon Sep 17 00:00:00 2001 From: Crited Date: Wed, 30 Oct 2019 14:44:44 +0100 Subject: [PATCH 187/259] Reverse thresholds for memory --- lib/core/tools/Convert-Bytes.psm1 | 4 +- lib/plugins/Invoke-IcingaCheckMemory.psm1 | 54 +++++++++---------- .../Get-IcingaMemoryPerformanceCounter.psm1 | 2 +- 3 files changed, 28 insertions(+), 32 deletions(-) diff --git a/lib/core/tools/Convert-Bytes.psm1 b/lib/core/tools/Convert-Bytes.psm1 index 3fc538f..2799f18 100644 --- a/lib/core/tools/Convert-Bytes.psm1 +++ b/lib/core/tools/Convert-Bytes.psm1 @@ -5,7 +5,7 @@ function Convert-Bytes() [string]$Unit ); - If (($Value -Match "(^[0-9]*) ?(B|KB|MB|GB|TB|PT|Kibi|Mibi|Gibi|Tibi|Pibi)")) { + If (($Value -Match "(^[\d\.]*) ?(B|KB|MB|GB|TB|PT|Kibi|Mibi|Gibi|Tibi|Pibi)")) { [single]$CurrentValue = $Matches[1]; [string]$CurrentUnit = $Matches[2]; @@ -16,7 +16,7 @@ function Convert-Bytes() switch ($Unit) { - #{ 'B' -contains $_} { $FinalValue = ConvertTo-ByteSI $CurrentValue -Unit B; $boolOption = $true;} + { 'B' -contains $_} { $FinalValue = $CurrentValue; $boolOption = $true;} { 'KB' -contains $_} { $FinalValue = ConvertTo-KiloByte $CurrentValue -Unit B; $boolOption = $true;} { 'MB' -contains $_} { $FinalValue = ConvertTo-MegaByte $CurrentValue -Unit B; $boolOption = $true;} { 'GB' -contains $_} { $FinalValue = ConvertTo-GigaByte $CurrentValue -Unit B; $boolOption = $true;} diff --git a/lib/plugins/Invoke-IcingaCheckMemory.psm1 b/lib/plugins/Invoke-IcingaCheckMemory.psm1 index 4ec252a..1a101c5 100644 --- a/lib/plugins/Invoke-IcingaCheckMemory.psm1 +++ b/lib/plugins/Invoke-IcingaCheckMemory.psm1 @@ -17,17 +17,12 @@ Import-IcingaLib core\tools; [WARNING]: % Memory Check 78.74 is greater than 60 1 .EXAMPLE - PS> Invoke-IcingaCheckMemory -Unit GB -Critical 1850000KB -Warning 2500000KB -CriticalPercent 80 -WarningPercent 30 -Verbosity 3 - [Warning]: Check package "Memory Usage" is [Warning] (Match All) - \_ [WARNING]: Memory Percent 35.95% is greater than 30% - \_ [OK]: PageFile Percent is 16.42% - | 'Memory_Percent'=35.95%;30;80;0;100 'Used_Bytes_in_GB'=3.44;2.5;1.85 'PageFile_Percent'=16.42%;;;0;100 - 1 -.PARAMETER Warning + PS> +.PARAMETER WarningBytes Used to specify a Warning threshold. In this case an string value. The string has to be like, "20B", "20KB", "20MB", "20GB", "20TB", "20TB" -.PARAMETER Critical +.PARAMETER CriticalBytes Used to specify a Critical threshold. In this case an string value. The string has to be like, "20B", "20KB", "20MB", "20GB", "20TB", "20TB" @@ -39,22 +34,19 @@ Import-IcingaLib core\tools; .PARAMETER CriticalPercent Used to specify a Critical threshold. In this case an integer value. - Like 30 for 30%. If memory usage is above 30%, the check will return CRITICAL. + Like 30 for 30%. If memory usage is below 30%, the check will return CRITICAL. .PARAMETER CriticalPercent Used to specify a Critical threshold. In this case an integer value. - Like 30 for 30%. If memory usage is above 30%, the check will return Warning. - -.PARAMETER Unit - Determines output Unit. Allowed Units: 'B', 'KB', 'MB', 'GB', 'TB', 'PB' + Like 30 for 30%. If memory usage is below 30%, the check will return Warning. .INPUTS System.String .OUTPUTS System.String - + .LINK https://github.com/LordHepipud/icinga-module-windows .NOTES @@ -63,34 +55,38 @@ Import-IcingaLib core\tools; function Invoke-IcingaCheckMemory() { param( - [string]$Critical = $null, - [string]$Warning = $null, - [string]$Unit = 'B', - $CriticalPercent = $null, - $WarningPercent = $null, + [string]$CriticalBytes = $null, + [string]$WarningBytes = $null, + $CriticalPercent = $null, + $WarningPercent = $null, [switch]$PageFile, [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0, + [int]$Verbosity = 0, [switch]$NoPerfData ); - $CrticalConverted = Convert-Bytes $Critical -Unit $Unit - $WarningConverted = Convert-Bytes $Warning -Unit $Unit - + If ([string]::IsNullOrEmpty($CriticalBytes) -eq $FALSE) { + [decimal]$CrticalConverted = Convert-Bytes $CriticalBytes -Unit B + } + If ([string]::IsNullOrEmpty($WarningBytes) -eq $FALSE) { + [decimal]$WarningConverted = Convert-Bytes $WarningBytes -Unit B + } $MemoryPackage = New-IcingaCheckPackage -Name 'Memory Usage' -OperatorAnd -Verbos $Verbosity; $MemoryData = (Get-IcingaMemoryPerformanceCounter); - - $MemoryPerc = New-IcingaCheck -Name 'Memory Percent' -Value $MemoryData['Memory Used %'] -Unit '%'; - $MemoryByte = New-IcingaCheck -Name "Used Bytes in $Unit" -Value (Convert-Bytes ([string]::Format('{0}B', $MemoryData['Memory used Bytes'])) -Unit $Unit); + $MemoryPerc = New-IcingaCheck -Name 'Memory Percent Available' -Value $MemoryData['Memory Available %'] -Unit '%'; + $MemoryByteUsed = New-IcingaCheck -Name "Used Bytes" -Value $MemoryData['Memory Used Bytes'] -Unit 'B'; + $MemoryByteAvailable = New-IcingaCheck -Name "Available Bytes" -Value $MemoryData['Memory Available Bytes'] -Unit 'B'; #$PageFileCheck = New-IcingaCheck -Name 'PageFile Percent' -Value $MemoryData['PageFile %'] -Unit '%'; # PageFile To-Do - $MemoryByte.WarnOutOfRange($WarningConverted).CritOutOfRange($CrticalConverted) | Out-Null; - $MemoryPerc.WarnOutOfRange($WarningPercent).CritOutOfRange($CriticalPercent) | Out-Null; + $MemoryByteAvailable.WarnIfLowerThan($WarningConverted).CritIfLowerThan($CrticalConverted) | Out-Null; + $MemoryPerc.WarnIfLowerThan($WarningPercent).CritIfLowerThan($CriticalPercent) | Out-Null; $MemoryPackage.AddCheck($MemoryPerc); - $MemoryPackage.AddCheck($MemoryByte); + $MemoryPackage.AddCheck($MemoryByteAvailable); + $MemoryPackage.AddCheck($MemoryByteUsed); + #$MemoryPackage.AddCheck($PageFileCheck); return (New-IcingaCheckResult -Check $MemoryPackage -NoPerfData $NoPerfData -Compile); diff --git a/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 b/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 index e0fafc8..d1103bd 100644 --- a/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 +++ b/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 @@ -11,7 +11,7 @@ function Get-IcingaMemoryPerformanceCounter() $MemoryData.Add('Memory Available Bytes', [decimal]($Initial.'\Memory\Available Bytes'.value)); $MemoryData.Add('Memory Total Bytes', (Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory); $MemoryData.Add('Memory Used Bytes', $MemoryData.'Memory Total Bytes' - $MemoryData.'Memory Available Bytes'); - $MemoryData.Add('Memory Used %', $MemoryData.'Memory Available Bytes' / $MemoryData.'Memory Total Bytes' * 100); + $MemoryData.Add('Memory Available %', 100 - ($MemoryData.'Memory Available Bytes' / $MemoryData.'Memory Total Bytes' * 100)); $MemoryData.Add('PageFile %', $Initial.'\Paging File(_Total)\% usage'.value); return $MemoryData; From 11e791a498eb5872acf4e6b28e513349beef8347 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 30 Oct 2019 17:50:07 +0100 Subject: [PATCH 188/259] Fixes variable naming and perf data output --- lib/plugins/Invoke-IcingaCheckDirectory.psm1 | 13 +++++----- .../directory/Icinga_Provider_Directory.psm1 | 26 +++++++++---------- 2 files changed, 20 insertions(+), 19 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckDirectory.psm1 b/lib/plugins/Invoke-IcingaCheckDirectory.psm1 index c20ecba..4223eea 100644 --- a/lib/plugins/Invoke-IcingaCheckDirectory.psm1 +++ b/lib/plugins/Invoke-IcingaCheckDirectory.psm1 @@ -64,15 +64,16 @@ function Invoke-IcingaCheckDirectory() [switch]$Recurse, $Critical = $null, $Warning = $null, - [string]$YoungerThen, - [string]$OlderThen, + [string]$YoungerThan, + [string]$OlderThan, [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 + [int]$Verbosity = 0, + [switch]$NoPerfData ); $DirectoryData = Get-IcingaDirectoryAll -Path $Path -FileNames $FileNames ` - -Recurse $Recurse -YoungerThen $YoungerThen -OlderThen $OlderThen; - $DirectoryCheck = New-IcingaCheck -Name $Path -Value $DirectoryData.Count -NoPerfData; + -Recurse $Recurse -YoungerThan $YoungerThan -OlderThan $OlderThan; + $DirectoryCheck = New-IcingaCheck -Name 'File Count' -Value $DirectoryData.Count; $DirectoryCheck.WarnOutOfRange( ($Warning) @@ -82,5 +83,5 @@ function Invoke-IcingaCheckDirectory() $DirectoryPackage = New-IcingaCheckPackage -Name $Path -OperatorAnd -Checks $DirectoryCheck -Verbose $Verbosity; - return (New-IcingaCheckresult -Check $DirectoryPackage -NoPerfData $TRUE -Compile); + return (New-IcingaCheckresult -Check $DirectoryPackage -NoPerfData $NoPerfData -Compile); } \ No newline at end of file diff --git a/lib/provider/directory/Icinga_Provider_Directory.psm1 b/lib/provider/directory/Icinga_Provider_Directory.psm1 index e4d187c..b9994ca 100644 --- a/lib/provider/directory/Icinga_Provider_Directory.psm1 +++ b/lib/provider/directory/Icinga_Provider_Directory.psm1 @@ -6,8 +6,8 @@ function Get-IcingaDirectoryAll() [string]$Path, [array]$FileNames, [bool]$Recurse, - [string]$YoungerThen, - [string]$OlderThen + [string]$YoungerThan, + [string]$OlderThan ); if ($Recurse -eq $TRUE) { @@ -16,17 +16,17 @@ function Get-IcingaDirectoryAll() $DirectoryData = Get-ChildItem -Path $Path -Include $FileNames; } - if ([string]::IsNullOrEmpty($OlderThen) -eq $FALSE -And [string]::IsNullOrEmpty($YoungerThen) -eq $FALSE) { - $OlderThen = Set-NumericNegative (ConvertTo-Seconds $OlderThen); - $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -lt (Get-Date).AddSeconds($OlderThen)}) - $YoungerThen = Set-NumericNegative (ConvertTo-Seconds $YoungerThen); - $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -gt (Get-Date).AddSeconds($YoungerThen)}) - } elseif ([string]::IsNullOrEmpty($OlderThen) -eq $FALSE) { - $OlderThen = Set-NumericNegative (ConvertTo-Seconds $OlderThen); - $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -lt (Get-Date).AddSeconds($OlderThen)}) - } elseif ([string]::IsNullOrEmpty($YoungerThen) -eq $FALSE) { - $YoungerThen = Set-NumericNegative (ConvertTo-Seconds $YoungerThen); - $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -gt ((Get-Date).AddSeconds($YoungerThen))}) + if ([string]::IsNullOrEmpty($OlderThan) -eq $FALSE -And [string]::IsNullOrEmpty($YoungerThan) -eq $FALSE) { + $OlderThan = Set-NumericNegative (ConvertTo-Seconds $OlderThan); + $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -lt (Get-Date).AddSeconds($OlderThan)}) + $YoungerThan = Set-NumericNegative (ConvertTo-Seconds $YoungerThan); + $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -gt (Get-Date).AddSeconds($YoungerThan)}) + } elseif ([string]::IsNullOrEmpty($OlderThan) -eq $FALSE) { + $OlderThan = Set-NumericNegative (ConvertTo-Seconds $OlderThan); + $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -lt (Get-Date).AddSeconds($OlderThan)}) + } elseif ([string]::IsNullOrEmpty($YoungerThan) -eq $FALSE) { + $YoungerThan = Set-NumericNegative (ConvertTo-Seconds $YoungerThan); + $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -gt ((Get-Date).AddSeconds($YoungerThan))}) } return $DirectoryData; From 60e7ff7907b94cb4328f0021554e3d72e8f780d8 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 30 Oct 2019 17:50:24 +0100 Subject: [PATCH 189/259] Fixed check naming for users --- lib/plugins/Invoke-IcingaCheckUsers.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckUsers.psm1 b/lib/plugins/Invoke-IcingaCheckUsers.psm1 index 20ca89b..2fc1871 100644 --- a/lib/plugins/Invoke-IcingaCheckUsers.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUsers.psm1 @@ -56,14 +56,14 @@ function Invoke-IcingaCheckUsers() $LoginCount = $LoggedOnUsers.users.$User.count; } - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Logged On User "{0}"', $User)) -Value $LoginCount; + $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Logged On Users "{0}"', $User)) -Value $LoginCount; $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; $UsersPackage.AddCheck($IcingaCheck); } } else { foreach ($User in $LoggedOnUsers.users.Keys) { $UsersPackage.AddCheck( - (New-IcingaCheck -Name ([string]::Format('Logged On User "{0}"', $User)) -Value $LoggedOnUsers.users.$User.count) + (New-IcingaCheck -Name ([string]::Format('Logged On Users "{0}"', $User)) -Value $LoggedOnUsers.users.$User.count) ); } $IcingaCheck = New-IcingaCheck -Name 'Logged On Users' -Value $LoggedOnUsers.count; From 57af086055719367822e134292c06b76317b370b Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 30 Oct 2019 17:50:42 +0100 Subject: [PATCH 190/259] Improves naming of uptime check result --- lib/plugins/Invoke-IcingaCheckUptime.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckUptime.psm1 b/lib/plugins/Invoke-IcingaCheckUptime.psm1 index c4da1ac..1635539 100644 --- a/lib/plugins/Invoke-IcingaCheckUptime.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUptime.psm1 @@ -42,9 +42,9 @@ function Invoke-IcingaCheckUptime() ); $WindowsData = Get-IcingaWindows; - $Name = ([string]::Format('Windows Uptime: {0}', (ConvertFrom-TimeSpan -Seconds $WindowsData.windows.metadata.uptime.value))); + $Name = ([string]::Format('System Uptime: {0}', (ConvertFrom-TimeSpan -Seconds $WindowsData.windows.metadata.uptime.value))); - $IcingaCheck = New-IcingaCheck -Name 'Windows Uptime' -Value $WindowsData.windows.metadata.uptime.value -Unit 's'; + $IcingaCheck = New-IcingaCheck -Name 'System Uptime' -Value $WindowsData.windows.metadata.uptime.value -Unit 's'; $IcingaCheck.WarnOutOfRange( (ConvertTo-SecondsFromIcingaThresholds -Threshold $Warning) ).CritOutOfRange( From 75ff1061de77f955d8d35264e3166e32c6dba707 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 30 Oct 2019 17:51:02 +0100 Subject: [PATCH 191/259] Improves naming of Windows update check result --- lib/plugins/Invoke-IcingaCheckUpdates.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/plugins/Invoke-IcingaCheckUpdates.psm1 b/lib/plugins/Invoke-IcingaCheckUpdates.psm1 index 33d81a5..531a0fe 100644 --- a/lib/plugins/Invoke-IcingaCheckUpdates.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUpdates.psm1 @@ -75,7 +75,7 @@ function Invoke-IcingaCheckUpdates() $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; $UpdateCount.AddCheck($IcingaCheck); - $UpdatePackage = New-IcingaCheckPackage -Name 'Updates' -OperatorAnd -Verbose $Verbosity -Checks @( + $UpdatePackage = New-IcingaCheckPackage -Name 'Windows Updates' -OperatorAnd -Verbose $Verbosity -Checks @( $UpdateCount ); From 1644d6cd41055c6150dd2455274138087b177c9a Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 30 Oct 2019 17:51:30 +0100 Subject: [PATCH 192/259] Improves BIOS serial check result naming --- lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 b/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 index 14793f0..d4cc69e 100644 --- a/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 +++ b/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 @@ -22,6 +22,6 @@ Import-IcingaLib provider\bios; function Invoke-IcingaCheckBiosSerial() { $Bios = Get-IcingaBiosSerialNumber; - $BiosCheck = New-IcingaCheck -Name $Bios.Name -Value $Bios.Value -NoPerfData; + $BiosCheck = New-IcingaCheck -Name ([string]::Format('BIOS {0}', $Bios.Name)) -Value $Bios.Value -NoPerfData; return (New-IcingaCheckresult -Check $BiosCheck -NoPerfData $TRUE -Compile); } From 006c809f568b46bfb0c255e5dda003275b4298a0 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 30 Oct 2019 17:51:58 +0100 Subject: [PATCH 193/259] Improves performance data output by using lower case only --- lib/icinga/plugin/New-IcingaPerformanceDataEntry.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/icinga/plugin/New-IcingaPerformanceDataEntry.psm1 b/lib/icinga/plugin/New-IcingaPerformanceDataEntry.psm1 index f0eeb74..79c6235 100644 --- a/lib/icinga/plugin/New-IcingaPerformanceDataEntry.psm1 +++ b/lib/icinga/plugin/New-IcingaPerformanceDataEntry.psm1 @@ -32,7 +32,7 @@ function New-IcingaPerformanceDataEntry() return ([string]::Format( "'{0}'={1}{2};{3};{4}{5}{6} ", - $LabelName, + $LabelName.ToLower(), (Format-IcingaPerfDataValue $PerfValue), $PerfDataObject.unit, (Format-IcingaPerfDataValue $PerfDataObject.warning), From b2a228e38910a5ec271ba8398adee5e9deb9fee7 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 30 Oct 2019 17:52:53 +0100 Subject: [PATCH 194/259] Add gigabyte (GB) unit for valid input --- doc/developerguide/01-NewIcingaCheck.md | 1 + lib/icinga/enums/Icinga_IcingaEnums.psm1 | 1 + 2 files changed, 2 insertions(+) diff --git a/doc/developerguide/01-NewIcingaCheck.md b/doc/developerguide/01-NewIcingaCheck.md index 965ec62..649c06d 100644 --- a/doc/developerguide/01-NewIcingaCheck.md +++ b/doc/developerguide/01-NewIcingaCheck.md @@ -44,6 +44,7 @@ For performance metrics you can provide a `Unit` to ensure your graphing is disp | B | Bytes | The input is indicated as quantity in bytes | | KB | Kilobytes | The input is indicated as quantity in kilobytes | | MB | Megabytes | The input is indicated as quantity in megabytes | +| GB | Gigabytes | The input is indicated as quantity in gigabytes | | TB | Terabytes | The input is indicated as quantity in terabytes | | c | Counter | A continues counter increasing values over time | diff --git a/lib/icinga/enums/Icinga_IcingaEnums.psm1 b/lib/icinga/enums/Icinga_IcingaEnums.psm1 index e0267ae..c3fcd0f 100644 --- a/lib/icinga/enums/Icinga_IcingaEnums.psm1 +++ b/lib/icinga/enums/Icinga_IcingaEnums.psm1 @@ -26,6 +26,7 @@ 'B' = 'bytes'; 'KB' = 'kilobytes'; 'MB' = 'megabytes'; + 'GB' = 'gigabytes'; 'TB' = 'terabytes'; 'c' = 'counter'; }; From 9876e509c845e18a5e3db835226552eaf6ff4d20 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 30 Oct 2019 17:53:31 +0100 Subject: [PATCH 195/259] Fixes spacing for checks within check packages --- lib/core/tools/New-StringTree.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/tools/New-StringTree.psm1 b/lib/core/tools/New-StringTree.psm1 index 43e06d7..9f3b01a 100644 --- a/lib/core/tools/New-StringTree.psm1 +++ b/lib/core/tools/New-StringTree.psm1 @@ -8,7 +8,7 @@ function New-StringTree() return ''; } - [string]$spaces = ' \_ '; + [string]$spaces = '\_ '; while ($Spacing -gt 1) { $Spacing -= 1; From 70855ea0fbbc128d347135933a9d7e4159744834 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 30 Oct 2019 17:53:57 +0100 Subject: [PATCH 196/259] Fixes time span date output --- lib/core/tools/ConvertFrom-TimeSpan.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/tools/ConvertFrom-TimeSpan.psm1 b/lib/core/tools/ConvertFrom-TimeSpan.psm1 index 0369ece..d6cc444 100644 --- a/lib/core/tools/ConvertFrom-TimeSpan.psm1 +++ b/lib/core/tools/ConvertFrom-TimeSpan.psm1 @@ -9,7 +9,7 @@ function ConvertFrom-TimeSpan() $TimeSpan = [TimeSpan]::FromSeconds($Seconds); return [string]::Format( - 'Days: {0} Hours: {1} Minutes: {2} Seconds: {3}', + '{0}d {1}h {2}m {3}s', $TimeSpan.Days, $TimeSpan.Hours, $TimeSpan.Minutes, From fcce0f4fb105663e21b18bfdf0cd567c64a1ecfb Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 30 Oct 2019 17:57:36 +0100 Subject: [PATCH 197/259] Fixes Unix time by always using UTC --- lib/core/tools/Get-IcingaUnixTime.psm1 | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/lib/core/tools/Get-IcingaUnixTime.psm1 b/lib/core/tools/Get-IcingaUnixTime.psm1 index dd61e8c..68923a5 100644 --- a/lib/core/tools/Get-IcingaUnixTime.psm1 +++ b/lib/core/tools/Get-IcingaUnixTime.psm1 @@ -1,4 +1,6 @@ function Get-IcingaUnixTime() { - return [int][double]::Parse((Get-Date -UFormat %s)) + return [int][double]::Parse( + (Get-Date -UFormat %s -Date (Get-Date).ToUniversalTime()) + ); } From 64fb6d44609a60113de9b1e8d6c6ed8aa2927d60 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 30 Oct 2019 18:17:39 +0100 Subject: [PATCH 198/259] Improves plugin check output and visibility --- lib/icinga/plugin/New-IcingaCheck.psm1 | 87 +++++++--- lib/icinga/plugin/New-IcingaCheckPackage.psm1 | 151 +++++++++++++----- 2 files changed, 177 insertions(+), 61 deletions(-) diff --git a/lib/icinga/plugin/New-IcingaCheck.psm1 b/lib/icinga/plugin/New-IcingaCheck.psm1 index 2524d77..3c7ee48 100644 --- a/lib/icinga/plugin/New-IcingaCheck.psm1 +++ b/lib/icinga/plugin/New-IcingaCheck.psm1 @@ -15,28 +15,33 @@ function New-IcingaCheck() ); $Check = New-Object -TypeName PSObject; - $Check | Add-Member -membertype NoteProperty -name 'name' -value $Name; - $Check | Add-Member -membertype NoteProperty -name 'verbose' -value 0; - $Check | Add-Member -membertype NoteProperty -name 'messages' -value @(); - $Check | Add-Member -membertype NoteProperty -name 'oks' -value @(); - $Check | Add-Member -membertype NoteProperty -name 'warnings' -value @(); - $Check | Add-Member -membertype NoteProperty -name 'criticals' -value @(); - $Check | Add-Member -membertype NoteProperty -name 'unknowns' -value @(); - $Check | Add-Member -membertype NoteProperty -name 'value' -value $Value; - $Check | Add-Member -membertype NoteProperty -name 'exitcode' -value -1; - $Check | Add-Member -membertype NoteProperty -name 'unit' -value $Unit; - $Check | Add-Member -membertype NoteProperty -name 'spacing' -value 0; - $Check | Add-Member -membertype NoteProperty -name 'compiled' -value $FALSE; - $Check | Add-Member -membertype NoteProperty -name 'perfdata' -value (-Not $NoPerfData); - $Check | Add-Member -membertype NoteProperty -name 'warning' -value ''; - $Check | Add-Member -membertype NoteProperty -name 'critical' -value ''; - $Check | Add-Member -membertype NoteProperty -name 'minimum' -value $Minimum; - $Check | Add-Member -membertype NoteProperty -name 'maximum' -value $Maximum; - $Check | Add-Member -membertype NoteProperty -name 'objectexists' -value $ObjectExists; - $Check | Add-Member -membertype NoteProperty -name 'translation' -value $Translation; - $Check | Add-Member -membertype NoteProperty -name 'checks' -value $null; - $Check | Add-Member -membertype NoteProperty -name 'completed' -value $FALSE; - $Check | Add-Member -membertype NoteProperty -name 'checkcommand' -value ''; + $Check | Add-Member -membertype NoteProperty -name 'name' -value $Name; + $Check | Add-Member -membertype NoteProperty -name 'verbose' -value 0; + $Check | Add-Member -membertype NoteProperty -name 'messages' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'oks' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'warnings' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'criticals' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'unknowns' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'okchecks' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'warningchecks' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'criticalchecks' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'unknownchecks' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'value' -value $Value; + $Check | Add-Member -membertype NoteProperty -name 'exitcode' -value -1; + $Check | Add-Member -membertype NoteProperty -name 'unit' -value $Unit; + $Check | Add-Member -membertype NoteProperty -name 'spacing' -value 0; + $Check | Add-Member -membertype NoteProperty -name 'compiled' -value $FALSE; + $Check | Add-Member -membertype NoteProperty -name 'perfdata' -value (-Not $NoPerfData); + $Check | Add-Member -membertype NoteProperty -name 'warning' -value ''; + $Check | Add-Member -membertype NoteProperty -name 'critical' -value ''; + $Check | Add-Member -membertype NoteProperty -name 'minimum' -value $Minimum; + $Check | Add-Member -membertype NoteProperty -name 'maximum' -value $Maximum; + $Check | Add-Member -membertype NoteProperty -name 'objectexists' -value $ObjectExists; + $Check | Add-Member -membertype NoteProperty -name 'translation' -value $Translation; + $Check | Add-Member -membertype NoteProperty -name 'checks' -value $null; + $Check | Add-Member -membertype NoteProperty -name 'completed' -value $FALSE; + $Check | Add-Member -membertype NoteProperty -name 'checkcommand' -value ''; + $Check | Add-Member -membertype NoteProperty -name 'checkpackage' -value $FALSE; $Check | Add-Member -membertype ScriptMethod -name 'HandleDaemon' -value { # Only apply this once the checkcommand is set @@ -77,6 +82,18 @@ function New-IcingaCheck() $this.HandleDaemon(); } + $Check | Add-Member -membertype ScriptMethod -name 'GetWarnings' -value { + return $this.warningchecks; + } + + $Check | Add-Member -membertype ScriptMethod -name 'GetCriticals' -value { + return $this.criticalchecks; + } + + $Check | Add-Member -membertype ScriptMethod -name 'GetUnknowns' -value { + return $this.unknownchecks; + } + $Check | Add-Member -membertype ScriptMethod -name 'WarnOutOfRange' -value { param($warning); @@ -503,7 +520,7 @@ function New-IcingaCheck() param($message, [int]$exitcode); [string]$outputMessage = [string]::Format( - '{0}: {1}', + '{0} {1}', $IcingaEnums.IcingaExitCodeText[$exitcode], $message ); @@ -529,6 +546,27 @@ function New-IcingaCheck() } } + $Check | Add-Member -membertype ScriptMethod -name 'AddCheckStateArrays' -value { + switch ([int]$this.exitcode) { + $IcingaEnums.IcingaExitCode.Ok { + $this.okchecks += $this.name; + break; + }; + $IcingaEnums.IcingaExitCode.Warning { + $this.warningchecks += $this.name; + break; + }; + $IcingaEnums.IcingaExitCode.Critical { + $this.criticalchecks += $this.name; + break; + }; + $IcingaEnums.IcingaExitCode.Unknown { + $this.unknownchecks += $this.name; + break; + }; + } + } + $Check | Add-Member -membertype ScriptMethod -name 'PrintOkMessages' -value { param([string]$spaces); $this.OutputMessageArray($this.oks, $spaces); @@ -649,6 +687,7 @@ function New-IcingaCheck() $this.AddOkOutput(); $this.compiled = $TRUE; + $this.AddCheckStateArrays(); } $Check | Add-Member -membertype ScriptMethod -name 'Compile' -value { @@ -665,6 +704,8 @@ function New-IcingaCheck() $this.PrintOutputMessages(); } + $this.AddCheckStateArrays(); + return $this.exitcode; } diff --git a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 index 9c2b33e..f941c05 100644 --- a/lib/icinga/plugin/New-IcingaCheckPackage.psm1 +++ b/lib/icinga/plugin/New-IcingaCheckPackage.psm1 @@ -16,20 +16,25 @@ function New-IcingaCheckPackage() ); $Check = New-Object -TypeName PSObject; - $Check | Add-Member -membertype NoteProperty -name 'name' -value $Name; - $Check | Add-Member -membertype NoteProperty -name 'exitcode' -value -1; - $Check | Add-Member -membertype NoteProperty -name 'verbose' -value $Verbose; - $Check | Add-Member -membertype NoteProperty -name 'hidden' -value $Hidden; - $Check | Add-Member -membertype NoteProperty -name 'checks' -value $Checks; - $Check | Add-Member -membertype NoteProperty -name 'opand' -value $OperatorAnd; - $Check | Add-Member -membertype NoteProperty -name 'opor' -value $OperatorOr; - $Check | Add-Member -membertype NoteProperty -name 'opnone' -value $OperatorNone; - $Check | Add-Member -membertype NoteProperty -name 'opmin' -value $OperatorMin; - $Check | Add-Member -membertype NoteProperty -name 'opmax' -value $OperatorMax; - $Check | Add-Member -membertype NoteProperty -name 'spacing' -value 0; - $Check | Add-Member -membertype NoteProperty -name 'compiled' -value $FALSE; - $Check | Add-Member -membertype NoteProperty -name 'perfdata' -value $FALSE; - $Check | Add-Member -membertype NoteProperty -name 'checkcommand' -value ''; + $Check | Add-Member -membertype NoteProperty -name 'name' -value $Name; + $Check | Add-Member -membertype NoteProperty -name 'exitcode' -value -1; + $Check | Add-Member -membertype NoteProperty -name 'verbose' -value $Verbose; + $Check | Add-Member -membertype NoteProperty -name 'hidden' -value $Hidden; + $Check | Add-Member -membertype NoteProperty -name 'checks' -value $Checks; + $Check | Add-Member -membertype NoteProperty -name 'opand' -value $OperatorAnd; + $Check | Add-Member -membertype NoteProperty -name 'opor' -value $OperatorOr; + $Check | Add-Member -membertype NoteProperty -name 'opnone' -value $OperatorNone; + $Check | Add-Member -membertype NoteProperty -name 'opmin' -value $OperatorMin; + $Check | Add-Member -membertype NoteProperty -name 'opmax' -value $OperatorMax; + $Check | Add-Member -membertype NoteProperty -name 'spacing' -value 0; + $Check | Add-Member -membertype NoteProperty -name 'compiled' -value $FALSE; + $Check | Add-Member -membertype NoteProperty -name 'perfdata' -value $FALSE; + $Check | Add-Member -membertype NoteProperty -name 'checkcommand' -value ''; + $Check | Add-Member -membertype NoteProperty -name 'headermsg' -value ''; + $Check | Add-Member -membertype NoteProperty -name 'checkpackage' -value $TRUE; + $Check | Add-Member -membertype NoteProperty -name 'warningchecks' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'criticalchecks' -value @(); + $Check | Add-Member -membertype NoteProperty -name 'unknownchecks' -value @(); $Check | Add-Member -membertype ScriptMethod -name 'Initialise' -value { foreach ($check in $this.checks) { @@ -68,6 +73,30 @@ function New-IcingaCheckPackage() $this.checks += $check; } + $Check | Add-Member -membertype ScriptMethod -name 'GetWarnings' -value { + foreach ($check in $this.checks) { + $this.warningchecks += $check.GetWarnings(); + } + + return $this.warningchecks; + } + + $Check | Add-Member -membertype ScriptMethod -name 'GetCriticals' -value { + foreach ($check in $this.checks) { + $this.criticalchecks += $check.GetCriticals(); + } + + return $this.criticalchecks; + } + + $Check | Add-Member -membertype ScriptMethod -name 'GetUnknowns' -value { + foreach ($check in $this.checks) { + $this.unknownchecks += $check.GetUnknowns(); + } + + return $this.unknownchecks; + } + $Check | Add-Member -membertype ScriptMethod -name 'AssignCheckCommand' -value { param($CheckCommand); @@ -219,13 +248,19 @@ function New-IcingaCheckPackage() } } - $Check | Add-Member -membertype ScriptMethod -name 'WriteAllOutput' -value { - if ($this.hidden) { + $Check | Add-Member -membertype ScriptMethod -name 'PrintOutputMessageSorted' -value { + param($skipHidden, $skipExitCode); + + if ($this.hidden -And $skipHidden) { return; } [hashtable]$MessageOrdering = @{}; foreach ($check in $this.checks) { + if ([int]$check.exitcode -eq $skipExitCode -And $skipExitCode -ne -1) { + continue; + } + if ($MessageOrdering.ContainsKey($check.Name) -eq $FALSE) { $MessageOrdering.Add($check.name, $check); } else { @@ -248,31 +283,24 @@ function New-IcingaCheckPackage() } } + $Check | Add-Member -membertype ScriptMethod -name 'WriteAllOutput' -value { + $this.PrintOutputMessageSorted($TRUE, -1); + } + $Check | Add-Member -membertype ScriptMethod -name 'PrintAllMessages' -value { $this.WritePackageOutputStatus(); $this.WriteAllOutput(); } $Check | Add-Member -membertype ScriptMethod -name 'WriteCheckErrors' -value { - [hashtable]$MessageOrdering = @{}; - foreach ($check in $this.checks) { - if ([int]$check.exitcode -ne $IcingaEnums.IcingaExitCode.Ok) { - $MessageOrdering.Add($check.name, $check); - } - } - - $SortedArray = $MessageOrdering.GetEnumerator() | Sort-Object name; - - foreach ($entry in $SortedArray) { - $entry.Value.PrintAllMessages(); - } + $this.PrintOutputMessageSorted($FALSE, $IcingaEnums.IcingaExitCode.Ok); } $Check | Add-Member -membertype ScriptMethod -name 'PrintNoChecksConfigured' -value { if ($this.checks.Count -eq 0) { Write-IcingaPluginOutput ( [string]::Format( - '{0}{1}: No checks configured for package "{2}"', + '{0}{1} No checks configured for package "{2}"', (New-StringTree ($this.spacing + 1)), $IcingaEnums.IcingaExitCodeText.($this.exitcode), $this.name @@ -287,31 +315,37 @@ function New-IcingaCheckPackage() return; } - [string]$outputMessage = '{0}{1}: Check package "{2}" is {1}'; + [string]$outputMessage = '{0}{1} Check package "{2}"'; if ($this.verbose -ne 0) { $outputMessage += ' ({3})'; } + if ($this.exitcode -ne 0 -And $this.spacing -eq 0) { + $outputMessage += ' - {4}'; + } + Write-IcingaPluginOutput ( [string]::Format( $outputMessage, (New-StringTree $this.spacing), $IcingaEnums.IcingaExitCodeText.($this.exitcode), $this.name, - $this.GetPackageConfigMessage() + $this.GetPackageConfigMessage(), + $this.headermsg ) ); } $Check | Add-Member -membertype ScriptMethod -name 'PrintOutputMessages' -value { - [bool]$printDetails = $FALSE; [bool]$printAll = $FALSE; switch ($this.verbose) { - 0 { break; }; - 1 { break; }; - 2 { - $printDetails = $TRUE; + 0 { + # Default value. Only print a package but not the services include + break; + }; + 1 { + # Include the Operator into the check package result break; }; Default { @@ -325,8 +359,7 @@ function New-IcingaCheckPackage() if ($printAll) { $this.WriteAllOutput(); $this.PrintNoChecksConfigured(); - } elseif ($printDetails) { - # Now print Non-Ok Check outputs in case our package is not Ok + } else { if ([int]$this.exitcode -ne $IcingaEnums.IcingaExitCode.Ok) { $this.WriteCheckErrors(); $this.PrintNoChecksConfigured(); @@ -334,15 +367,57 @@ function New-IcingaCheckPackage() } } + $Check | Add-Member -membertype ScriptMethod -name 'AddUniqueSortedChecksToHeader' -value { + param($checkarray, $state); + + [hashtable]$CheckHash = @{}; + + foreach ($entry in $checkarray) { + if ($CheckHash.ContainsKey($entry) -eq $FALSE) { + $CheckHash.Add($entry, $TRUE); + } + } + + [array]$SortedCheckArray = $CheckHash.GetEnumerator() | Sort-Object name; + + if ($SortedCheckArray.Count -ne 0) { + $this.headermsg += [string]::Format( + '{0} {1} ', + $IcingaEnums.IcingaExitCodeText[$state], + [string]::Join(', ', $SortedCheckArray.Key) + ); + } + } + $Check | Add-Member -membertype ScriptMethod -name 'GetWorstExitCode' -value { if ([int]$this.exitcode -eq [int]$IcingaEnums.IcingaExitCode.Unknown) { return; } + foreach ($check in $this.checks) { if ([int]$this.exitcode -lt $check.exitcode) { $this.exitcode = $check.exitcode; } + + $this.criticalchecks += $check.GetCriticals(); + $this.warningchecks += $check.GetWarnings(); + $this.unknownchecks += $check.GetUnknowns(); } + + # Only apply this to our top package + if ($this.spacing -ne 0) { + return; + } + + $this.AddUniqueSortedChecksToHeader( + $this.criticalchecks, $IcingaEnums.IcingaExitCode.Critical + ); + $this.AddUniqueSortedChecksToHeader( + $this.warningchecks, $IcingaEnums.IcingaExitCode.Warning + ); + $this.AddUniqueSortedChecksToHeader( + $this.unknownchecks, $IcingaEnums.IcingaExitCode.Unknown + ); } $Check | Add-Member -membertype ScriptMethod -name 'GetPerfData' -value { From c257beab9b6049ee817dece95239e977ee6e1964 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 30 Oct 2019 18:19:08 +0100 Subject: [PATCH 199/259] Improved basket check command config generator * Add support for dynamic list creation * Fixes plenty of static code definitions --- .../tools/Get-IcingaCheckCommandConfig.psm1 | 197 +++++++----------- 1 file changed, 71 insertions(+), 126 deletions(-) diff --git a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 index 7542201..e8f7bc7 100644 --- a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 +++ b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 @@ -26,7 +26,7 @@ ############################################################ .EXAMPLE - Get-IcingaCheckCommandConfig -OutFile 'C:\Users\icinga\config-exports' + Get-IcingaCheckCommandConfig -OutDirectory 'C:\Users\icinga\config-exports' The following commands have been exported: - 'Invoke-IcingaCheckBiosSerial' - 'Invoke-IcingaCheckCPU' @@ -39,7 +39,7 @@ JSON export created in 'C:\Users\icinga\config-exports\PowerShell_CheckCommands_09-13-2019-10-55-1989.json' .EXAMPLE - Get-IcingaCheckCommandConfig Invoke-IcingaCheckBiosSerial, Invoke-IcingaCheckCPU -OutFile 'C:\Users\icinga\config-exports' + Get-IcingaCheckCommandConfig Invoke-IcingaCheckBiosSerial, Invoke-IcingaCheckCPU -OutDirectory 'C:\Users\icinga\config-exports' The following commands have been exported: - 'Invoke-IcingaCheckBiosSerial' - 'Invoke-IcingaCheckCPU' @@ -66,7 +66,7 @@ function Get-IcingaCheckCommandConfig() param( [Parameter(ValueFromPipeline)] [array]$CheckName, - [string]$OutFile + [string]$OutDirectory ); # Check whether all Checks will be exported or just the ones specified @@ -102,7 +102,7 @@ function Get-IcingaCheckCommandConfig() ); # "Verbose" gets added to all Checks build and exported no matter what, so we add it from the start - if ($Basket.DataList.ContainsKey('PowerShell Verbose') -eq $FALSE) { + <#if ($Basket.DataList.ContainsKey('PowerShell Verbose') -eq $FALSE) { $Basket.DataList.Add( 'PowerShell Verbose', @{ 'list_name' = 'PowerShell Verbose'; @@ -136,13 +136,16 @@ function Get-IcingaCheckCommandConfig() ); } ); - } + }#> # Loop through ${CheckName}, to get information on every command specified/all commands. foreach ($check in $CheckName) { # Get necessary syntax-information and more through cmdlet "Get-Help" - $Data = (Get-Help $check) + $Data = (Get-Help $check); + $ParameterList = (Get-Command -Name $check).Parameters; + $PluginNameSpace = $Data.Name.Replace('Invoke-', ''); + $IsDataList = $FALSE; # Add command Structure $Basket.Command.Add( @@ -172,12 +175,12 @@ function Get-IcingaCheckCommandConfig() [string]$Order = 99 } - $IcingaCustomVariable = [string]::Format('$PowerShell_{0}_{1}$', (Get-Culture).TextInfo.ToTitleCase($parameter.type.name), $parameter.Name); + $IcingaCustomVariable = [string]::Format('${0}_{1}_{2}$', $PluginNameSpace, (Get-Culture).TextInfo.ToTitleCase($parameter.type.name), $parameter.Name); # Todo: Should we improve this? Actually the handling would be identical, we just need to assign # the proper field for this - if ($IcingaCustomVariable -eq '$PowerShell_Int32_Verbose$' -Or $IcingaCustomVariable -eq '$PowerShell_Int_Verbose$') { - $IcingaCustomVariable = '$PowerShell_Object_Verbose$'; + if ($IcingaCustomVariable -like '*_Int32_Verbose$' -Or $IcingaCustomVariable -like '*_Int_Verbose$' -Or $IcingaCustomVariable -like '*_Object_Verbose$') { + $IcingaCustomVariable = [string]::Format('${0}_Int_Verbose$', $PluginNameSpace); } # Add arguments to a given command @@ -217,12 +220,6 @@ function Get-IcingaCheckCommandConfig() 'order' = $Order; } ); - - if ($parameter.name -ne 'Verbose') { - $Basket.Command[$Data.Name].vars.Add($parameter.Name, '$$null'); - } else { - $Basket.Command[$Data.Name].vars.Add($parameter.Name, "0"); - } } # Determine wether a parameter is required based on given syntax-information @@ -232,12 +229,12 @@ function Get-IcingaCheckCommandConfig() $Required = 'n'; } - $IcingaCustomVariable = [string]::Format('PowerShell_{0}_{1}', (Get-Culture).TextInfo.ToTitleCase($parameter.type.name), $parameter.Name); + $IcingaCustomVariable = [string]::Format('{0}_{1}_{2}', $PluginNameSpace, (Get-Culture).TextInfo.ToTitleCase($parameter.type.name), $parameter.Name); # Todo: Should we improve this? Actually the handling would be identical, we just need to assign # the proper field for this - if ($IcingaCustomVariable -eq 'PowerShell_Int32_Verbose' -Or $IcingaCustomVariable -eq 'PowerShell_Int_Verbose') { - $IcingaCustomVariable = 'PowerShell_Object_Verbose'; + if ($IcingaCustomVariable -like '*_Int32_Verbose' -Or $IcingaCustomVariable -like '*_Int_Verbose' -Or $IcingaCustomVariable -like '*_Object_Verbose') { + $IcingaCustomVariable = [string]::Format('{0}_Int_Verbose', $PluginNameSpace); } [bool]$ArgumentKnown = $FALSE; @@ -253,56 +250,26 @@ function Get-IcingaCheckCommandConfig() continue; } - $DataListName = [string]::Format('PowerShell {0}', $parameter.Name) + $DataListName = [string]::Format('{0} {1}', $PluginNameSpace, $parameter.Name); - if ($parameter.type.name -eq 'switch') { - $IcingaDataType='Boolean'; + if ($null -ne $ParameterList[$parameter.Name].Attributes.ValidValues) { + $IcingaDataType = 'Datalist'; + Add-PowerShellDataList -Name $DataListName -Basket $Basket -Arguments $ParameterList[$parameter.Name].Attributes.ValidValues; + $IsDataList = $TRUE; + } elseif ($parameter.type.name -eq 'SwitchParameter') { + $IcingaDataType = 'Boolean'; } elseif ($parameter.type.name -eq 'Object') { - if ($parameter.Name -eq 'Verbose') { - $IcingaDataType='Datalist' - } - - $IcingaDataType='String'; - + $IcingaDataType = 'String'; } elseif ($parameter.type.name -eq 'Array') { - $IcingaDataType='Array'; + $IcingaDataType = 'Array'; + } elseif ($parameter.type.name -eq 'Int' -Or $parameter.type.name -eq 'Int32') { + $IcingaDataType = 'Number'; } else { - $IcingaDataType='String'; - } - - if($Basket.Datafield.ContainsKey('0') -eq $FALSE){ - $Basket.Datafield.Add( - '0', @{ - 'varname' = 'PowerShell_Switch_NoPerfData'; - 'caption' = 'Ignore Performance Data'; - 'description' = 'Specifies if the plugin will return performance data output or not'; - 'datatype' = 'Icinga\Module\Director\DataType\DataTypeBoolean'; - 'format' = $NULL; - 'originalId' = '0'; - } - ); - } - - if($Basket.Datafield.ContainsKey('1') -eq $FALSE){ - $Basket.Datafield.Add( - '1', @{ - 'varname' = 'PowerShell_Object_Verbose'; - 'caption' = 'Verbose'; - 'description' = 'Specifies if the plugin will return performance data output or not'; - 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; - 'format' = $NULL; - 'originalId' = '1'; - 'settings' = @{ - 'datalist' = 'PowerShell Verbose'; - 'datatype' = 'string'; - 'behavior' = 'strict'; - } - } - ); + $IcingaDataType = 'String'; } $IcingaDataType = [string]::Format('Icinga\Module\Director\DataType\DataType{0}', $IcingaDataType) - + if ($Basket.Datafield.Values.varname -ne $IcingaCustomVariable) { $Basket.Datafield.Add( [string]$FieldID, @{ @@ -315,18 +282,12 @@ function Get-IcingaCheckCommandConfig() } ); - if ($parameter.Name -eq 'Verbose') { + if ($IsDataList) { $Basket.Datafield[[string]$FieldID].Add( 'settings', @{ - 'behavior' = 'strict'; - 'datatype' = 'string'; 'datalist' = $DataListName; - } - ); - } elseif ($parameter.type.name -eq 'Object') { - $Basket.Datafield[[string]$FieldID].Add( - 'settings', @{ - 'visbility' = 'visible'; + 'datatype' = 'string'; + 'behavior' = 'strict'; } ); } else { @@ -344,64 +305,21 @@ function Get-IcingaCheckCommandConfig() # Increment FieldNumeration, so unique fields for a given command are added. [int]$FieldNumeration = [int]$FieldNumeration + 1; } - - # Check whether or not noperfdata and verbose is set and add it if necessary - if ($Basket.Command[$Data.Name].arguments.ContainsKey('-Verbose') -eq $FALSE) { - $Basket.Command[$Data.Name].arguments.Add( - '-Verbose', @{ - 'value' = '$PowerShell_Object_Verbose$'; - 'order' = '99'; - } - ); - - $Basket.Command[$Data.Name].vars.Add( - 'PowerShell_Object_Verbose', "0" - ); - - if ($Basket.Datafield.Values.varname -eq $IcingaCustomVariable) { - } else { - $Basket.Datafield.Add( - [string]$FieldID, @{ - 'varname' = 'PowerShell_Object_Verbose'; - 'caption' = 'Verbose'; - 'description' = 'Specifies if the plugin will return performance data output or not'; - 'datatype' = 'Icinga\Module\Director\DataType\DataTypeDatalist'; - 'format' = $NULL; - 'originalId' = [string]$FieldID; - 'settings' = @{ - 'behavior' = 'strict'; - 'data_type' = 'string'; - 'datalist' = 'PowerShell Verbose' - } - } - ); - } - } - - if ($Basket.Command[$Data.Name].arguments.ContainsKey('-NoPerfData') -eq $FALSE) { - $Basket.Command[$Data.Name].arguments.Add( - '-NoPerfData', @{ - 'set_if' = '$PowerShell_Switch_NoPerfData$'; - 'set_if_format' = 'string'; - 'order' = '99'; - } - ); - $Basket.Command[$Data.Name].vars.Add('PowerShell_Switch_NoPerfData', $FALSE); - } } foreach ($check in $CheckName) { [int]$FieldNumeration = 0; - $Data = (Get-Help $check) + $Data = (Get-Help $check) + $PluginNameSpace = $Data.Name.Replace('Invoke-', ''); foreach ($parameter in $Data.parameters.parameter) { - $IcingaCustomVariable = [string]::Format('PowerShell_{0}_{1}', (Get-Culture).TextInfo.ToTitleCase($parameter.type.name), $parameter.Name); + $IcingaCustomVariable = [string]::Format('{0}_{1}_{2}', $PluginNameSpace, (Get-Culture).TextInfo.ToTitleCase($parameter.type.name), $parameter.Name); # Todo: Should we improve this? Actually the handling would be identical, we just need to assign # the proper field for this - if ($IcingaCustomVariable -eq 'PowerShell_Int32_Verbose' -Or $IcingaCustomVariable -eq 'PowerShell_Int_Verbose') { - $IcingaCustomVariable = 'PowerShell_Object_Verbose'; + if ($IcingaCustomVariable -like '*_Int32_Verbose' -Or $IcingaCustomVariable -like '*_Int_Verbose' -Or $IcingaCustomVariable -like '*_Object_Verbose') { + $IcingaCustomVariable = [string]::Format('{0}_Int_Verbose', $PluginNameSpace); } foreach ($DataFieldID in $Basket.Datafield.Keys) { @@ -424,25 +342,25 @@ function Get-IcingaCheckCommandConfig() # Generate JSON Output from Hashtable $output = ConvertTo-Json -Depth 100 $Basket -Compress; - # Determine whether json output via powershell or in file (based on param -OutFile) - if ([string]::IsNullOrEmpty($OutFile) -eq $false) { - $OutFile = (Join-Path -Path $OutFile -ChildPath $FileName); - if ((Test-Path($OutFile)) -eq $false) { - New-Item -Path $OutFile -Force | Out-Null; + # Determine whether json output via powershell or in file (based on param -OutDirectory) + if ([string]::IsNullOrEmpty($OutDirectory) -eq $false) { + $OutDirectory = (Join-Path -Path $OutDirectory -ChildPath $FileName); + if ((Test-Path($OutDirectory)) -eq $false) { + New-Item -Path $OutDirectory -Force | Out-Null; } - if ((Test-Path($OutFile)) -eq $false) { + if ((Test-Path($OutDirectory)) -eq $false) { throw 'Failed to create specified directory. Please try again or use a different target location.'; } - Set-Content -Path $OutFile -Value $output; + Set-Content -Path $OutDirectory -Value $output; # Output-Text Write-Host "The following commands have been exported:" foreach ($check in $CheckName) { Write-Host "- '$check'"; } - Write-Host "JSON export created in '${OutFile}'" + Write-Host "JSON export created in '${OutDirectory}'" return; } @@ -454,3 +372,30 @@ function Get-IcingaCheckCommandConfig() return $output; } + +function Add-PowerShellDataList() +{ + param( + $Name, + $Basket, + $Arguments + ); + + $Basket.DataList.Add( + $Name, @{ + 'list_name' = $Name; + 'owner' = $env:username; + 'originalId' = '2'; + 'entries' = @(); + } + ); + + foreach ($entry in $Arguments) { + $Basket.DataList[$Name]['entries'] += @{ + 'entry_name' = $entry; + 'entry_value' = $entry; + 'format' = 'string'; + 'allowed_roles' = $NULL; + }; + } +} From 58ba229c4fac190fdc14eae203b18e62a81981be Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 30 Oct 2019 18:20:27 +0100 Subject: [PATCH 200/259] Fixes doc for changed basket file output handling --- doc/icingaintegration/01-DirectorBaskets.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/icingaintegration/01-DirectorBaskets.md b/doc/icingaintegration/01-DirectorBaskets.md index 88ff689..2cd7170 100644 --- a/doc/icingaintegration/01-DirectorBaskets.md +++ b/doc/icingaintegration/01-DirectorBaskets.md @@ -31,7 +31,7 @@ Get-IcingaCheckCommandConfig -CheckName Invoke-IcingaCheckBiosSerial, Invoke-Ici Last but not least you can output the JSON-Basket directly into a file. To do this, simply use the `OutFile` argument. You only require to specify a directory here, as the file including a timestamp is generated by the Cmdlet itself ```powershell -Get-IcingaCheckCommandConfig -OutFile 'C:\Users\myuser\Documents\ +Get-IcingaCheckCommandConfig -OutDirectory 'C:\Users\myuser\Documents\ ``` Once the file is exported, you can navigate to your Icinga Director Basket menu and import the generated file. Afterwards all specified Check-Commands are available and ready to use From c579180521775d9717a8092747d3cd98432c03f2 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Wed, 30 Oct 2019 18:21:17 +0100 Subject: [PATCH 201/259] Removes no longer required Cmdlet definitions --- icinga-module-windows.psd1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/icinga-module-windows.psd1 b/icinga-module-windows.psd1 index a64d8ac..fdb32d1 100644 --- a/icinga-module-windows.psd1 +++ b/icinga-module-windows.psd1 @@ -25,7 +25,7 @@ Description = 'Icinga 2 Windows Agent Module, which allows to entirely monitor t PowerShellVersion = '3.0' # Aus diesem Modul zu exportierende Funktionen. Um optimale Leistung zu erzielen, verwenden Sie keine Platzhalter und löschen den Eintrag nicht. Verwenden Sie ein leeres Array, wenn keine zu exportierenden Funktionen vorhanden sind. -FunctionsToExport = @( 'Use-Icinga', 'Import-IcingaLib', 'Get-IcingaPluginDir', 'Get-IcingaCustomPluginDir', 'Get-IcingaCacheDir', 'Get-IcingaPowerShellConfigDir', 'Start-Icinga-Checker', 'Stop-Icinga-Checker', 'Get-Icinga-Lib', 'Get-Icinga-Object', 'Get-Icinga-Service', 'Start-Icinga-Service', 'Stop-Icinga-Service', 'Restart-Icinga-Service', 'Install-Icinga-Service', 'Uninstall-Icinga-Service', 'Get-Icinga-Setup', 'Install-Icinga', 'Start-Icinga-Daemon', 'Stop-Icinga-Daemon', 'Icinga-Client', 'Get-Icinga-Command', 'New-Icinga-Monitoring', 'Get-Icinga-Counter', 'Get-Icinga-Config', 'Set-Icinga-Config', 'Remove-Icinga-Config', 'New-Icinga-Config' ) +FunctionsToExport = @( 'Use-Icinga', 'Import-IcingaLib', 'Publish-IcingaModuleManifests', 'Get-IcingaPluginDir', 'Get-IcingaCustomPluginDir', 'Get-IcingaCacheDir', 'Get-IcingaPowerShellConfigDir' ) # Aus diesem Modul zu exportierende Cmdlets. Um optimale Leistung zu erzielen, verwenden Sie keine Plat'zhalter und löschen den Eintrag nicht. Verwenden Sie ein leeres Array, wenn keine zu exportierenden Cmdlets vorhanden sind. CmdletsToExport = @() From cee8ef178a653c04727786a9ff4ab34038ba0a97 Mon Sep 17 00:00:00 2001 From: Crited Date: Thu, 31 Oct 2019 09:43:13 +0100 Subject: [PATCH 202/259] Convert-Bytes returns hash with former and current unit --- lib/core/tools/Convert-Bytes.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/tools/Convert-Bytes.psm1 b/lib/core/tools/Convert-Bytes.psm1 index 2799f18..421b8a5 100644 --- a/lib/core/tools/Convert-Bytes.psm1 +++ b/lib/core/tools/Convert-Bytes.psm1 @@ -34,7 +34,7 @@ function Convert-Bytes() } } } - return $FinalValue; + return @{'value' = $FinalValue; 'pastunit' = $CurrentUnit; 'endunit' = $Unit}; } Throw 'Invalid input'; } \ No newline at end of file From 13b90ce2b32f6fbd4ddc4fcbb1a70a08c3b1a31f Mon Sep 17 00:00:00 2001 From: Crited Date: Thu, 31 Oct 2019 09:43:49 +0100 Subject: [PATCH 203/259] Directory Check now supports file size --- lib/plugins/Invoke-IcingaCheckDirectory.psm1 | 5 +++- .../directory/Icinga_Provider_Directory.psm1 | 30 +++++++++++++------ 2 files changed, 25 insertions(+), 10 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckDirectory.psm1 b/lib/plugins/Invoke-IcingaCheckDirectory.psm1 index 4223eea..76d1092 100644 --- a/lib/plugins/Invoke-IcingaCheckDirectory.psm1 +++ b/lib/plugins/Invoke-IcingaCheckDirectory.psm1 @@ -66,13 +66,16 @@ function Invoke-IcingaCheckDirectory() $Warning = $null, [string]$YoungerThan, [string]$OlderThan, + [string]$FileSizeGreaterThan, + [string]$FileSizeSmallerThan, [ValidateSet(0, 1, 2, 3)] [int]$Verbosity = 0, [switch]$NoPerfData ); $DirectoryData = Get-IcingaDirectoryAll -Path $Path -FileNames $FileNames ` - -Recurse $Recurse -YoungerThan $YoungerThan -OlderThan $OlderThan; + -Recurse $Recurse -YoungerThan $YoungerThan -OlderThan $OlderThan ` + -FileSizeGreaterThan $FileSizeGreaterThan -FileSizeSmallerThan $FileSizeSmallerThan; $DirectoryCheck = New-IcingaCheck -Name 'File Count' -Value $DirectoryData.Count; $DirectoryCheck.WarnOutOfRange( diff --git a/lib/provider/directory/Icinga_Provider_Directory.psm1 b/lib/provider/directory/Icinga_Provider_Directory.psm1 index b9994ca..3332b56 100644 --- a/lib/provider/directory/Icinga_Provider_Directory.psm1 +++ b/lib/provider/directory/Icinga_Provider_Directory.psm1 @@ -7,7 +7,9 @@ function Get-IcingaDirectoryAll() [array]$FileNames, [bool]$Recurse, [string]$YoungerThan, - [string]$OlderThan + [string]$OlderThan, + [string]$FileSizeGreaterThan, + [string]$FileSizeSmallerThan ); if ($Recurse -eq $TRUE) { @@ -17,16 +19,26 @@ function Get-IcingaDirectoryAll() } if ([string]::IsNullOrEmpty($OlderThan) -eq $FALSE -And [string]::IsNullOrEmpty($YoungerThan) -eq $FALSE) { - $OlderThan = Set-NumericNegative (ConvertTo-Seconds $OlderThan); - $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -lt (Get-Date).AddSeconds($OlderThan)}) - $YoungerThan = Set-NumericNegative (ConvertTo-Seconds $YoungerThan); - $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -gt (Get-Date).AddSeconds($YoungerThan)}) + $OlderThan = Set-NumericNegative (ConvertTo-Seconds $OlderThan); + $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -lt (Get-Date).AddSeconds($OlderThan)}) + $YoungerThan = Set-NumericNegative (ConvertTo-Seconds $YoungerThan); + $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -gt (Get-Date).AddSeconds($YoungerThan)}) } elseif ([string]::IsNullOrEmpty($OlderThan) -eq $FALSE) { - $OlderThan = Set-NumericNegative (ConvertTo-Seconds $OlderThan); - $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -lt (Get-Date).AddSeconds($OlderThan)}) + $OlderThan = Set-NumericNegative (ConvertTo-Seconds $OlderThan); + $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -lt (Get-Date).AddSeconds($OlderThan)}) } elseif ([string]::IsNullOrEmpty($YoungerThan) -eq $FALSE) { - $YoungerThan = Set-NumericNegative (ConvertTo-Seconds $YoungerThan); - $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -gt ((Get-Date).AddSeconds($YoungerThan))}) + $YoungerThan = Set-NumericNegative (ConvertTo-Seconds $YoungerThan); + $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -gt ((Get-Date).AddSeconds($YoungerThan))}) + } + + if ([string]::IsNullOrEmpty($FileSizeGreaterThan) -eq $FALSE) { + $FileSizeGreaterThanValue = (Convert-Bytes $FileSizeGreaterThan -Unit B).value + $DirectoryData = ($DirectoryData | Where-Object {$_.Length -gt $FileSizeGreaterThanValue}) + } + + if ([string]::IsNullOrEmpty($FileSizeSmallerThan) -eq $FALSE) { + $FileSizeSmallerThanValue = (Convert-Bytes $FileSizeSmallerThan -Unit B).value + $DirectoryData = ($DirectoryData | Where-Object {$_.Length -gt $FileSizeSmallerThanValue}) } return $DirectoryData; From 2d9b37e272aa55f7e349bb61df20319f0c1d4cc1 Mon Sep 17 00:00:00 2001 From: Crited Date: Thu, 31 Oct 2019 09:44:28 +0100 Subject: [PATCH 204/259] Memory check uses Used Memory again (Auto-Detect: Draft for Unit Size) --- lib/plugins/Invoke-IcingaCheckMemory.psm1 | 63 +++++++++++++------ .../Get-IcingaMemoryPerformanceCounter.psm1 | 2 +- 2 files changed, 46 insertions(+), 19 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckMemory.psm1 b/lib/plugins/Invoke-IcingaCheckMemory.psm1 index 1a101c5..230f510 100644 --- a/lib/plugins/Invoke-IcingaCheckMemory.psm1 +++ b/lib/plugins/Invoke-IcingaCheckMemory.psm1 @@ -52,6 +52,10 @@ Import-IcingaLib core\tools; .NOTES #> +<# +if ($bytes > 1099511627776) { return sprintf('%.2f TB', $bytes / 1099511627776); } elseif ($bytes > 1073741824) { return sprintf('%.2f GB', $bytes / 1073741824); } elseif ($bytes > 1048576) { return sprintf('%.2f MB', $bytes / 1048576); } else { return sprintf('%.2f KB', $bytes / 1024); +#> + function Invoke-IcingaCheckMemory() { param( @@ -59,35 +63,58 @@ function Invoke-IcingaCheckMemory() [string]$WarningBytes = $null, $CriticalPercent = $null, $WarningPercent = $null, - [switch]$PageFile, +# [switch]$PageFile, [ValidateSet(0, 1, 2, 3)] [int]$Verbosity = 0, [switch]$NoPerfData ); If ([string]::IsNullOrEmpty($CriticalBytes) -eq $FALSE) { - [decimal]$CrticalConverted = Convert-Bytes $CriticalBytes -Unit B + $CrticalConvertedAll = Convert-Bytes $CriticalBytes -Unit B + [decimal]$CriticalConverted = $CriticalConvertedAll.value + } If ([string]::IsNullOrEmpty($WarningBytes) -eq $FALSE) { - [decimal]$WarningConverted = Convert-Bytes $WarningBytes -Unit B + $WarningConvertedAll = Convert-Bytes $WarningBytes -Unit B + [decimal]$WarningConverted = $WarningConvertedAll.value } - $MemoryPackage = New-IcingaCheckPackage -Name 'Memory Usage' -OperatorAnd -Verbos $Verbosity; - $MemoryData = (Get-IcingaMemoryPerformanceCounter); + + $MemoryPackage = New-IcingaCheckPackage -Name 'Memory Usage' -OperatorAnd -Verbos $Verbosity; + $MemoryData = (Get-IcingaMemoryPerformanceCounter); + + # Auto-Detect? + If (($MemoryData['Memory Total Bytes'] / [math]::Pow(2, 50)) -ge 1) { + $Unit = "PB" + } elseif (($MemoryData['Memory Total Bytes'] / [math]::Pow(2, 40)) -ge 1) { + $Unit = "TB" + } elseif (($MemoryData['Memory Total Bytes'] / [math]::Pow(2, 30)) -ge 1) { + $Unit = "GB" + } elseif (($MemoryData['Memory Total Bytes'] / [math]::Pow(2, 20)) -ge 1) { + $Unit = "MB" + } elseif (($MemoryData['Memory Total Bytes'] / [math]::Pow(2, 10)) -ge 1) { + $Unit = "KB" + } else { + $Unit = "B" + } + + Write-Host $Unit - $MemoryPerc = New-IcingaCheck -Name 'Memory Percent Available' -Value $MemoryData['Memory Available %'] -Unit '%'; - $MemoryByteUsed = New-IcingaCheck -Name "Used Bytes" -Value $MemoryData['Memory Used Bytes'] -Unit 'B'; - $MemoryByteAvailable = New-IcingaCheck -Name "Available Bytes" -Value $MemoryData['Memory Available Bytes'] -Unit 'B'; - #$PageFileCheck = New-IcingaCheck -Name 'PageFile Percent' -Value $MemoryData['PageFile %'] -Unit '%'; + $MemoryPerc = New-IcingaCheck -Name 'Memory Percent Used' -Value $MemoryData['Memory Used %'] -Unit '%'; + $MemoryByteUsed = New-IcingaCheck -Name "Used Bytes" -Value $MemoryData['Memory Used Bytes'] -Unit 'B'; + #$MemoryByteAvailable = New-IcingaCheck -Name "Available Bytes" -Value $MemoryData['Memory Available Bytes'] -Unit 'B'; + #$PageFileCheck = New-IcingaCheck -Name 'PageFile Percent' -Value $MemoryData['PageFile %'] -Unit '%'; - # PageFile To-Do - $MemoryByteAvailable.WarnIfLowerThan($WarningConverted).CritIfLowerThan($CrticalConverted) | Out-Null; - $MemoryPerc.WarnIfLowerThan($WarningPercent).CritIfLowerThan($CriticalPercent) | Out-Null; - - $MemoryPackage.AddCheck($MemoryPerc); - $MemoryPackage.AddCheck($MemoryByteAvailable); - $MemoryPackage.AddCheck($MemoryByteUsed); - #$MemoryPackage.AddCheck($PageFileCheck); + #Kommastellen bedenken! + # PageFile To-Do + $MemoryByteUsed.WarnOutOfRange($WarningConverted).CritOutOfRange($CrticalConverted) | Out-Null; + $MemoryPerc.WarnOutOfRange($WarningPercent).CritOutOfRange($CriticalPercent) | Out-Null; + + $MemoryPackage.AddCheck($MemoryPerc); + #$MemoryPackage.AddCheck($MemoryByteAvailable); + $MemoryPackage.AddCheck($MemoryByteUsed); + + #$MemoryPackage.AddCheck($PageFileCheck); - return (New-IcingaCheckResult -Check $MemoryPackage -NoPerfData $NoPerfData -Compile); + return (New-IcingaCheckResult -Check $MemoryPackage -NoPerfData $NoPerfData -Compile); } diff --git a/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 b/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 index d1103bd..81eedf9 100644 --- a/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 +++ b/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 @@ -11,7 +11,7 @@ function Get-IcingaMemoryPerformanceCounter() $MemoryData.Add('Memory Available Bytes', [decimal]($Initial.'\Memory\Available Bytes'.value)); $MemoryData.Add('Memory Total Bytes', (Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory); $MemoryData.Add('Memory Used Bytes', $MemoryData.'Memory Total Bytes' - $MemoryData.'Memory Available Bytes'); - $MemoryData.Add('Memory Available %', 100 - ($MemoryData.'Memory Available Bytes' / $MemoryData.'Memory Total Bytes' * 100)); + $MemoryData.Add('Memory Used %', 100 - ($MemoryData.'Memory Available Bytes' / $MemoryData.'Memory Total Bytes' * 100)); $MemoryData.Add('PageFile %', $Initial.'\Paging File(_Total)\% usage'.value); return $MemoryData; From 55f5b25e589eaf82688fa5f080f6b3574540f9a0 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 31 Oct 2019 10:12:25 +0100 Subject: [PATCH 205/259] Improves initial setup wizard with more default values --- .../Get-IcingaAgentInstallerAnswerInput.psm1 | 9 ++++++ .../getters/Get-IcingaAgentMSIPackage.psm1 | 2 +- .../misc/Start-IcingaAgentInstallWizard.psm1 | 32 ++++++++++++------- 3 files changed, 30 insertions(+), 13 deletions(-) diff --git a/lib/core/icingaagent/getters/Get-IcingaAgentInstallerAnswerInput.psm1 b/lib/core/icingaagent/getters/Get-IcingaAgentInstallerAnswerInput.psm1 index 9dfe228..6f5473b 100644 --- a/lib/core/icingaagent/getters/Get-IcingaAgentInstallerAnswerInput.psm1 +++ b/lib/core/icingaagent/getters/Get-IcingaAgentInstallerAnswerInput.psm1 @@ -4,6 +4,7 @@ function Get-IcingaAgentInstallerAnswerInput() $Prompt, [ValidateSet("y","n","v")] $Default, + $DefaultInput = '', [switch]$Secure ); @@ -13,6 +14,10 @@ function Get-IcingaAgentInstallerAnswerInput() $DefaultAnswer = ' (Y/n)'; } elseif ($Default -eq 'n') { $DefaultAnswer = ' (y/N)'; + } elseif ($Default -eq 'v') { + if ([string]::IsNullOrEmpty($DefaultInput) -eq $FALSE) { + $DefaultAnswer = [string]::Format(' (Default: "{0}")', $DefaultInput); + } } if (-Not $Secure) { @@ -37,6 +42,10 @@ function Get-IcingaAgentInstallerAnswerInput() } } + if ([string]::IsNullOrEmpty($answer)) { + $answer = $DefaultInput; + } + return @{ 'result' = 2; 'answer' = $answer; diff --git a/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 b/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 index 9939742..f4b9ed5 100644 --- a/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 +++ b/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 @@ -61,7 +61,7 @@ function Get-IcingaAgentMSIPackage() if ($SkipDownload -eq $FALSE) { $DownloadPath = Join-Path $Env:TEMP -ChildPath $UsePackage; - Write-Host ([string]::Format('Download Icinga 2 Agent installer "{0}" into temp directory "{1}"', $UsePackage, $DownloadPath)); + Write-Host ([string]::Format('Downloading Icinga 2 Agent installer "{0}" into temp directory "{1}"', $UsePackage, $DownloadPath)); Invoke-WebRequest -Uri ([string]::Format('{0}/{1}', $Source, $UsePackage)) -OutFile $DownloadPath; } diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index 60a5551..40f6c08 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -130,14 +130,31 @@ function Start-IcingaAgentInstallWizard() $InstallerArguments += ("-Endpoints " + ([string]::Join(',', $Endpoints))); } + if ($null -eq $CAPort) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Are you using a different port than 5665 for Icinga communications?' -Default 'n').result -eq 0) { + $CAPort = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the port for Icinga 2 communication' -Default 'v').answer; + $InstallerArguments += "-CAPort $CAPort"; + } else { + $InstallerArguments += "-CAPort 5665"; + $CAPort = 5665; + } + } + if ($EndpointConnections.Count -eq 0 -And $AcceptConnections -eq 1) { - $ArrayString = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the network destinations this agent will connect to ("," separated, like: "[127.0.0.1], [127.0.0.2]")' -Default 'v').answer; + $NetworkDefault = ''; + foreach ($Endpoint in $Endpoints) { + $NetworkDefault += [string]::Format('[{0}]:{1},', $Endpoint, $CAPort); + } + if ([string]::IsNullOrEmpty($NetworkDefault) -eq $FALSE) { + $NetworkDefault = $NetworkDefault.Substring(0, $NetworkDefault.Length - 1); + } + $ArrayString = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the network destinations this agent will connect to, separated by ","' -Default 'v' -DefaultInput $NetworkDefault).answer; $EndpointConnections = ($ArrayString.Replace(' ', '')).Split(','); $InstallerArguments += ("-EndpointConnections " + ([string]::Join(',', $EndpointConnections))); } if ([string]::IsNullOrEmpty($ParentZone)) { - $ParentZone = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the parent zone this agent will connect to' -Default 'v').answer; + $ParentZone = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the parent zone this agent will connect to' -Default 'v' -DefaultInput 'master').answer; $InstallerArguments += "-ParentZone $ParentZone"; } @@ -193,18 +210,9 @@ function Start-IcingaAgentInstallWizard() if ($CanConnectToParent) { if ([string]::IsNullOrEmpty($CAEndpoint)) { - $CAEndpoint = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the FQDN for either ONE of your Icinga parent node/nodes or your Icinga 2 CA master (if you can connect to it)' -Default 'v').answer; + $CAEndpoint = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the FQDN for either ONE of your Icinga parent node/nodes or your Icinga 2 CA master' -Default 'v' -DefaultInput $Endpoints[0]).answer; $InstallerArguments += "-CAEndpoint $CAEndpoint"; } - if ($null -eq $CAPort) { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Are you using a different port then 5665 for Icinga communications?' -Default 'n').result -eq 0) { - $CAPort = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter your port to communicate with the Icinga 2 CA' -Default 'v').answer; - $InstallerArguments += "-CAPort $CAPort"; - } else { - $InstallerArguments += "-CAPort 5665"; - $CAPort = 5665; - } - } if ($null -eq $Ticket) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you have a Icinga Ticket available to sign your certificate?' -Default 'y').result -eq 1) { $Ticket = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter your Icinga Ticket' -Default 'v').answer; From 77d99ae7c2aecd594516165f55f97c3570ff321d Mon Sep 17 00:00:00 2001 From: Crited Date: Thu, 31 Oct 2019 11:16:33 +0100 Subject: [PATCH 206/259] Add Creation Filter & seperated into multiple functions (modular enhancement) --- .../directory/Icinga_Provider_Directory.psm1 | 162 +++++++++++++++--- 1 file changed, 140 insertions(+), 22 deletions(-) diff --git a/lib/provider/directory/Icinga_Provider_Directory.psm1 b/lib/provider/directory/Icinga_Provider_Directory.psm1 index 3332b56..f33af95 100644 --- a/lib/provider/directory/Icinga_Provider_Directory.psm1 +++ b/lib/provider/directory/Icinga_Provider_Directory.psm1 @@ -6,44 +6,58 @@ function Get-IcingaDirectoryAll() [string]$Path, [array]$FileNames, [bool]$Recurse, - [string]$YoungerThan, - [string]$OlderThan, + [string]$ChangeTimeEqual, + [string]$ChangeYoungerThan, + [string]$ChangeOlderThan, + [string]$CreationTimeEqual, + [string]$CreationOlderThan, + [string]$CreationYoungerThan, [string]$FileSizeGreaterThan, [string]$FileSizeSmallerThan ); if ($Recurse -eq $TRUE) { - $DirectoryData = Get-ChildItem -Recurse -Path $Path -Include $FileNames; + $DirectoryData = Get-IcingaDirectoryRecurse -Path $Path -FileNames $FileNames; } else { - $DirectoryData = Get-ChildItem -Path $Path -Include $FileNames; - } - - if ([string]::IsNullOrEmpty($OlderThan) -eq $FALSE -And [string]::IsNullOrEmpty($YoungerThan) -eq $FALSE) { - $OlderThan = Set-NumericNegative (ConvertTo-Seconds $OlderThan); - $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -lt (Get-Date).AddSeconds($OlderThan)}) - $YoungerThan = Set-NumericNegative (ConvertTo-Seconds $YoungerThan); - $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -gt (Get-Date).AddSeconds($YoungerThan)}) - } elseif ([string]::IsNullOrEmpty($OlderThan) -eq $FALSE) { - $OlderThan = Set-NumericNegative (ConvertTo-Seconds $OlderThan); - $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -lt (Get-Date).AddSeconds($OlderThan)}) - } elseif ([string]::IsNullOrEmpty($YoungerThan) -eq $FALSE) { - $YoungerThan = Set-NumericNegative (ConvertTo-Seconds $YoungerThan); - $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -gt ((Get-Date).AddSeconds($YoungerThan))}) + $DirectoryData = Get-IcingaDirectory -Path $Path -FileNames $FileNames; } + if ([string]::IsNullOrEmpty($ChangeTimeEqual) -eq $FALSE) { + $DirectoryData = Get-IcingaDirectoryChangeTimeEqual -ChangeTimeEqual $ChangeTimeEqual -DirectoryData $DirectoryData; + } + + if ([string]::IsNullOrEmpty($CreationTimeEqual) -eq $FALSE) { + $DirectoryData = Get-IcingaDirectoryCreationTimeEqual -CreationTimeEqual $CreationTimeEqual -DirectoryData $DirectoryData; + } + + If ([string]::IsNullOrEmpty($ChangeTimeEqual) -eq $TRUE -Or [string]::IsNullOrEmpty($CreationTimeEqual) -eq $TRUE) { + if ([string]::IsNullOrEmpty($ChangeOlderThan) -eq $FALSE) { + $DirectoryData = Get-IcingaDirectoryChangeOlderThan -ChangeOlderThan $ChangeOlderThan -DirectoryData $DirectoryData; + } + if ([string]::IsNullOrEmpty($ChangeYoungerThan) -eq $FALSE) { + $DirectoryData = Get-IcingaDirectoryChangeYoungerThan -ChangeYoungerThan $ChangeYoungerThan -DirectoryData $DirectoryData; + } + if ([string]::IsNullOrEmpty($CreationOlderThan) -eq $FALSE) { + $DirectoryData = Get-IcingaDirectoryCreationOlderThan -CreationOlderThan $CreationOlderThan -DirectoryData $DirectoryData; + } + if ([string]::IsNullOrEmpty($CreationYoungerThan) -eq $FALSE) { + $DirectoryData = Get-IcingaDirectoryCreationYoungerThan -CreationYoungerThan $CreationYoungerThan -DirectoryData $DirectoryData; + } + } if ([string]::IsNullOrEmpty($FileSizeGreaterThan) -eq $FALSE) { - $FileSizeGreaterThanValue = (Convert-Bytes $FileSizeGreaterThan -Unit B).value - $DirectoryData = ($DirectoryData | Where-Object {$_.Length -gt $FileSizeGreaterThanValue}) + $DirectoryData = (Get-IcingaDirectorySizeGreaterThan -FileSizeGreaterThan $FileSizeGreaterThan -DirectoryData $DirectoryData); } - if ([string]::IsNullOrEmpty($FileSizeSmallerThan) -eq $FALSE) { - $FileSizeSmallerThanValue = (Convert-Bytes $FileSizeSmallerThan -Unit B).value - $DirectoryData = ($DirectoryData | Where-Object {$_.Length -gt $FileSizeSmallerThanValue}) + $DirectoryData = (Get-IcingaDirectorySizeSmallerThan -FileSizeSmallerThan $FileSizeSmallerThan -DirectoryData $DirectoryData); } return $DirectoryData; } + + +# RECURSE + function Get-IcingaDirectory() { param( @@ -65,5 +79,109 @@ function Get-IcingaDirectoryRecurse() $DirectoryData = Get-ChildItem -Recurse -Include $FileNames -Path $Path; + return $DirectoryData; +} + +# FILE SIZE + +function Get-IcingaDirectorySizeGreaterThan() +{ + param( + [string]$FileSizeGreaterThan, + $DirectoryData + ); + $FileSizeGreaterThanValue = (Convert-Bytes $FileSizeGreaterThan -Unit B).value + $DirectoryData = ($DirectoryData | Where-Object {$_.Length -gt $FileSizeGreaterThanValue}) + + return $DirectoryData; +} + +function Get-IcingaDirectorySizeSmallerThan() +{ + param( + [string]$FileSizeSmallerThan, + $DirectoryData + ); + $FileSizeSmallerThanValue = (Convert-Bytes $FileSizeSmallerThan -Unit B).value + $DirectoryData = ($DirectoryData | Where-Object {$_.Length -gt $FileSizeSmallerThanValue}) + + return $DirectoryData; +} + +# TIME BASED CHANGE + +function Get-IcingaDirectoryChangeOlderThan() +{ + param ( + [string]$ChangeOlderThan, + $DirectoryData + ) + $ChangeOlderThan = Set-NumericNegative (ConvertTo-Seconds $ChangeOlderThan); + $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -lt (Get-Date).AddSeconds($ChangeOlderThan)}) + + return $DirectoryData; +} + +function Get-IcingaDirectoryChangeYoungerThan() +{ + param ( + [string]$ChangeYoungerThan, + $DirectoryData + ) + $ChangeYoungerThan = Set-NumericNegative (ConvertTo-Seconds $ChangeYoungerThan); + $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -gt (Get-Date).AddSeconds($ChangeYoungerThan)}) + + return $DirectoryData; +} + +function Get-IcingaDirectoryChangeTimeEqual() +{ + param ( + [string]$ChangeTimeEqual, + $DirectoryData + ) + $ChangeTimeEqual = Set-NumericNegative (ConvertTo-Seconds $ChangeTimeEqual); + $ChangeTimeEqual = (Get-Date).AddSeconds($ChangeTimeEqual); + $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime.Day -eq $ChangeTimeEqual.Day -And $_.LastWriteTime.Month -eq $ChangeTimeEqual.Month -And $_.LastWriteTime.Year -eq $ChangeTimeEqual.Year}) + + return $DirectoryData; +} + +# TIME BASED CREATION + +function Get-IcingaDirectoryCreationYoungerThan() +{ + param ( + [string]$CreationYoungerThan, + $DirectoryData + ) + $CreationYoungerThan = Set-NumericNegative (ConvertTo-Seconds $CreationYoungerThan); + $DirectoryData = ($DirectoryData | Where-Object {$_.CreationTime -gt (Get-Date).AddSeconds($CreationYoungerThan)}) + + return $DirectoryData; +} + +function Get-IcingaDirectoryCreationOlderThan() +{ + param ( + [string]$CreationOlderThan, + $DirectoryData + ) + $CreationOlderThan = Set-NumericNegative (ConvertTo-Seconds $CreationOlderThan); + $DirectoryData = ($DirectoryData | Where-Object {$_.CreationTime -lt (Get-Date).AddSeconds($CreationOlderThan)}) + + return $DirectoryData; +} + +function Get-IcingaDirectoryCreationTimeEqual() +{ + param ( + [string]$CreationTimeEqual, + $DirectoryData + ) + $CreationTimeEqual = Set-NumericNegative (ConvertTo-Seconds $CreationTimeEqual); + $CreationTimeEqual = (Get-Date).AddSeconds($CreationTimeEqual); + $DirectoryData = ($DirectoryData | Where-Object {$_.CreationTime.Day -eq $CreationTimeEqual.Day -And $_.CreationTime.Month -eq $CreationTimeEqual.Month -And $_.CreationTime.Year -eq $CreationTimeEqual.Year}) + return $DirectoryData; } \ No newline at end of file From 1940fefd4e7286f884fc2e2025a5c0aa00d1cd42 Mon Sep 17 00:00:00 2001 From: Crited Date: Thu, 31 Oct 2019 11:17:12 +0100 Subject: [PATCH 207/259] Changes to directory check accordingly, based on provider, Creation time added. --- lib/plugins/Invoke-IcingaCheckDirectory.psm1 | 45 +++++++++++++++----- 1 file changed, 35 insertions(+), 10 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckDirectory.psm1 b/lib/plugins/Invoke-IcingaCheckDirectory.psm1 index 76d1092..9e2be91 100644 --- a/lib/plugins/Invoke-IcingaCheckDirectory.psm1 +++ b/lib/plugins/Invoke-IcingaCheckDirectory.psm1 @@ -19,7 +19,7 @@ Import-IcingaLib provider\directory; [WARNING]: Check package "C:\Users\Icinga\Downloads" is [WARNING] (Match All) \_ [WARNING]: C:\Users\Icinga\Downloads is 24 .EXAMPLE - PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -Warning 20 -Critical 30 -Verbosity 3 -YoungerThen 20d -OlderThen 10d + PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -Warning 20 -Critical 30 -Verbosity 3 -ChangeYoungerThen 20d -ChangeOlderThen 10d [OK]: Check package "C:\Users\Icinga\Downloads" is [OK] (Match All) \_ [OK]: C:\Users\Icinga\Downloads is 1 .EXAMPLE @@ -39,14 +39,34 @@ Import-IcingaLib provider\directory; e.g '*.txt', '*.sql' # Fiends all files ending with .txt and .sql .PARAMETER Recurse A switch, which can be set to filter through directories recursively. -.PARAMETER YoungerThen +.PARAMETER ChangeYoungerThen String that expects input format like "20d", which translates to 20 days. Allowed units: ms, s, m, h, d, w, M, y. - Thereby all files younger then 20 days are considered within the check -.PARAMETER OlderThen + Thereby all files which have a change date younger then 20 days are considered within the check. +.PARAMETER ChangeOlderThen String that expects input format like "20d", which translates to 20 days. Allowed units: ms, s, m, h, d, w, M, y. - Thereby all files older then 20 days are considered within the check + Thereby all files which have a change date older then 20 days are considered within the check. +.PARAMETER CreationYoungerThen + String that expects input format like "20d", which translates to 20 days. Allowed units: ms, s, m, h, d, w, M, y. + + Thereby all files which have a creation date younger then 20 days are considered within the check. +.PARAMETER CreationOlderThen + String that expects input format like "20d", which translates to 20 days. Allowed units: ms, s, m, h, d, w, M, y. + + Thereby all files which have a creation date older then 20 days are considered within the check. + +.PARAMETER ChangeTimeEqual + String that expects input format like "20d", which translates to 20 days. Allowed units: ms, s, m, h, d, w, M, y. + + Thereby all files which have been changed 20 days ago are considered within the check. + +.PARAMETER CreationTimeEqual + String that expects input format like "20d", which translates to 20 days. Allowed units: ms, s, m, h, d, w, M, y. + + Thereby all files which have been created 20 days ago are considered within the check. + + .INPUTS System.String .OUTPUTS @@ -64,8 +84,12 @@ function Invoke-IcingaCheckDirectory() [switch]$Recurse, $Critical = $null, $Warning = $null, - [string]$YoungerThan, - [string]$OlderThan, + [string]$ChangeTimeEqual, + [string]$ChangeYoungerThan, + [string]$ChangeOlderThan, + [string]$CreationTimeEqual, + [string]$CreationOlderThan, + [string]$CreationYoungerThan, [string]$FileSizeGreaterThan, [string]$FileSizeSmallerThan, [ValidateSet(0, 1, 2, 3)] @@ -73,9 +97,10 @@ function Invoke-IcingaCheckDirectory() [switch]$NoPerfData ); - $DirectoryData = Get-IcingaDirectoryAll -Path $Path -FileNames $FileNames ` - -Recurse $Recurse -YoungerThan $YoungerThan -OlderThan $OlderThan ` - -FileSizeGreaterThan $FileSizeGreaterThan -FileSizeSmallerThan $FileSizeSmallerThan; + $DirectoryData = Get-IcingaDirectoryAll -Path $Path -FileNames $FileNames -Recurse $Recurse ` + -ChangeYoungerThan $ChangeYoungerThan -ChangeOlderThan $ChangeOlderThan ` + -CreationYoungerThan $CreationYoungerThan -CreationOlderThan $CreationOlderThan ` + -CreationTimeEqual $CreationTimeEqual -ChangeTimeEqual $ChangeTimeEqual; $DirectoryCheck = New-IcingaCheck -Name 'File Count' -Value $DirectoryData.Count; $DirectoryCheck.WarnOutOfRange( From 54476cbb6d08013109d9934e1f87b250e14037da Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 31 Oct 2019 13:41:05 +0100 Subject: [PATCH 208/259] Add support to keep PowerShell open while running as daemon --- lib/daemon/Start-IcingaPowerShellDaemon.psm1 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/daemon/Start-IcingaPowerShellDaemon.psm1 b/lib/daemon/Start-IcingaPowerShellDaemon.psm1 index 4fe858c..87bbc53 100644 --- a/lib/daemon/Start-IcingaPowerShellDaemon.psm1 +++ b/lib/daemon/Start-IcingaPowerShellDaemon.psm1 @@ -1,5 +1,9 @@ function Start-IcingaPowerShellDaemon() { + param( + [switch]$RunAsService + ); + $ScriptBlock = { param($IcingaDaemonData); @@ -32,4 +36,10 @@ function Start-IcingaPowerShellDaemon() $global:IcingaDaemonData.Add('Config', (Read-IcingaPowerShellConfig)); New-IcingaThreadInstance -Name "Icinga_PowerShell_Background_Daemon" -ThreadPool $IcingaDaemonData.IcingaThreadPool.BackgroundPool -ScriptBlock $ScriptBlock -Arguments @( $global:IcingaDaemonData ) -Start; + + if ($RunAsService) { + while ($TRUE) { + Start-Sleep -Seconds 100; + } + } } From 4ec3d795ff2cd075d1b70b84862b9d7816a56a98 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 31 Oct 2019 13:41:42 +0100 Subject: [PATCH 209/259] Add support to specify a service for changing the user for --- .../icingaagent/setters/Set-IcingaAgentServiceUser.psm1 | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 b/lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 index 6779bf8..d627efe 100644 --- a/lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 +++ b/lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 @@ -2,7 +2,8 @@ function Set-IcingaAgentServiceUser() { param( [string]$User, - [securestring]$Password + [securestring]$Password, + [string]$Service = 'icinga2' ); if ([string]::IsNullOrEmpty($User)) { @@ -14,14 +15,14 @@ function Set-IcingaAgentServiceUser() $User = [string]::Format('.\{0}', $User); } - $ArgString = 'config icinga2 obj= "{0}" password="{1}"'; + $ArgString = 'config {0} obj= "{1}" password="{2}"'; if($null -eq $Password) { - $ArgString = 'config icinga2 obj= "{0}"{1}'; + $ArgString = 'config {0} obj= "{1}"{2}'; } $Output = Start-IcingaProcess ` -Executable 'sc.exe' ` - -Arguments ([string]::Format($ArgString, $User, (ConvertFrom-IcingaSecureString $Password))) ` + -Arguments ([string]::Format($ArgString, $Service, $User, (ConvertFrom-IcingaSecureString $Password))) ` -FlushNewLines $TRUE; if ($Output.ExitCode -eq 0) { From f7f56abedd6ecd9bbff52cd977a051b8037a0388 Mon Sep 17 00:00:00 2001 From: Crited Date: Thu, 31 Oct 2019 13:43:09 +0100 Subject: [PATCH 210/259] Remove unnecessary code from services and add new performance counter --- lib/plugins/Invoke-IcingaCheckService.psm1 | 49 +++++++++++++++------- 1 file changed, 35 insertions(+), 14 deletions(-) diff --git a/lib/plugins/Invoke-IcingaCheckService.psm1 b/lib/plugins/Invoke-IcingaCheckService.psm1 index 16049fb..3afa6c1 100644 --- a/lib/plugins/Invoke-IcingaCheckService.psm1 +++ b/lib/plugins/Invoke-IcingaCheckService.psm1 @@ -37,12 +37,14 @@ function Invoke-IcingaCheckService() [ValidateSet('Stopped', 'StartPending', 'StopPending', 'Running', 'ContinuePending', 'PausePending', 'Paused')] [string]$Status = 'Running', [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 + [int]$Verbosity = 0, + [switch]$NoPerfData ); - $ServicesPackage = New-IcingaCheckPackage -Name 'Services' -OperatorAnd -Verbose $Verbosity; + $ServicesPackage = New-IcingaCheckPackage -Name 'Services' -OperatorAnd -Verbose $Verbosity; + $ServicesCountPackage = New-IcingaCheckPackage -Name 'Count Services' -OperatorAnd -Verbose $Verbosity -Hidden; - if ($Service.Count -ne 1) { + [int]$StoppedCount,[int]$StartPendingCount,[int]$StopPendingCount,[int]$RunningCount,[int]$ContinuePendingCount,[int]$PausePendingCount,[int]$PausedCount,[int]$ServicesCounted = 0 foreach ($services in $Service) { $IcingaCheck = $null; @@ -50,22 +52,41 @@ function Invoke-IcingaCheckService() $ServiceName = Get-IcingaServiceCheckName -ServiceInput $services -Service $FoundService; $ConvertedStatus = ConvertTo-ServiceStatusCode -Status $Status; $StatusRaw = $FoundService.Values.configuration.Status.raw; - + $IcingaCheck = New-IcingaCheck -Name $ServiceName -Value $StatusRaw -ObjectExists $FoundService -Translation $ProviderEnums.ServiceStatusName; $IcingaCheck.CritIfNotMatch($ConvertedStatus) | Out-Null; $ServicesPackage.AddCheck($IcingaCheck) + + switch($StatusRaw) { + {1 -contains $_} { $StoppedCount++; $ServicesCounted++} + {2 -contains $_} { $StartPendingCount++; $ServicesCounted++} + {3 -contains $_} { $StopPendingCount++; $ServicesCounted++} + {4 -contains $_} { $RunningCount++; $ServicesCounted++} + {5 -contains $_} { $ContinuePendingCount++; $ServicesCounted++} + {6 -contains $_} { $PausePendingCount++; $ServicesCounted++} + {7 -contains $_} { $PausedCount++; $ServicesCounted++} + } } - } else { + $IcingaStopped = New-IcingaCheck -Name 'stopped services' -Value $StoppedCount; + $IcingaStartPending = New-IcingaCheck -Name 'pending started services' -Value $StartPendingCount; + $IcingaStopPending = New-IcingaCheck -Name 'pending stopped services' -Value $StopPendingCount; + $IcingaRunning = New-IcingaCheck -Name 'running services' -Value $RunningCount; + $IcingaContinuePending = New-IcingaCheck -Name 'pending continued services' -Value $ContinuePendingCount; + $IcingaPausePending = New-IcingaCheck -Name 'pending paused services' -Value $PausePendingCount; + $IcingaPaused = New-IcingaCheck -Name 'paused services' -Value $PausePendingCount; + + $IcingaCount = New-IcingaCheck -Name 'service count' -Value $ServicesCounted; - $FoundService = Get-IcingaServices -Service $Service; - $ServiceName = Get-IcingaServiceCheckName -ServiceInput $Service -Service $FoundService; - $IntStatus = ConvertTo-ServiceStatusCode -Status $Status; - $StatusRaw = $FoundService.Values.configuration.Status.raw; + $ServicesCountPackage.AddCheck($IcingaStopped) + $ServicesCountPackage.AddCheck($IcingaStartPending) + $ServicesCountPackage.AddCheck($IcingaStopPending) + $ServicesCountPackage.AddCheck($IcingaRunning) + $ServicesCountPackage.AddCheck($IcingaContinuePending) + $ServicesCountPackage.AddCheck($IcingaPausePending) + $ServicesCountPackage.AddCheck($IcingaPaused) - $IcingaCheck = New-IcingaCheck -Name $ServiceName -Value $StatusRaw -ObjectExists $FoundService -Translation $ProviderEnums.ServiceStatusName; - $IcingaCheck.CritIfNotMatch($IntStatus) | Out-Null; - $ServicesPackage.AddCheck($IcingaCheck); + $ServicesCountPackage.AddCheck($IcingaCount) + $ServicesPackage.AddCheck($ServicesCountPackage) - } - return (New-IcingaCheckResult -Name 'Services' -Check $ServicesPackage -NoPerfData $TRUE -Compile); + return (New-IcingaCheckResult -Name 'Services' -Check $ServicesPackage -NoPerfData $NoPerfData -Compile); } From 0de69ee83077e0ea527d5fb5d562379411eb73ac Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 31 Oct 2019 13:43:20 +0100 Subject: [PATCH 211/259] Add support to download and install PowerShell service --- icinga-module-windows.psd1 | 2 +- icinga-module-windows.psm1 | 5 +++ .../framework/Expand-IcingaZipArchive.psm1 | 23 ++++++++++ .../Get-IcingaFrameworkServiceBinary.psm1 | 43 +++++++++++++++++++ .../Install-IcingaPowerShellService.psm1 | 26 +++++++++++ .../Test-IcingaZipBinaryChecksum.psm1 | 23 ++++++++++ 6 files changed, 121 insertions(+), 1 deletion(-) create mode 100644 lib/core/framework/Expand-IcingaZipArchive.psm1 create mode 100644 lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 create mode 100644 lib/core/framework/Install-IcingaPowerShellService.psm1 create mode 100644 lib/core/framework/Test-IcingaZipBinaryChecksum.psm1 diff --git a/icinga-module-windows.psd1 b/icinga-module-windows.psd1 index fdb32d1..e8e36fe 100644 --- a/icinga-module-windows.psd1 +++ b/icinga-module-windows.psd1 @@ -25,7 +25,7 @@ Description = 'Icinga 2 Windows Agent Module, which allows to entirely monitor t PowerShellVersion = '3.0' # Aus diesem Modul zu exportierende Funktionen. Um optimale Leistung zu erzielen, verwenden Sie keine Platzhalter und löschen den Eintrag nicht. Verwenden Sie ein leeres Array, wenn keine zu exportierenden Funktionen vorhanden sind. -FunctionsToExport = @( 'Use-Icinga', 'Import-IcingaLib', 'Publish-IcingaModuleManifests', 'Get-IcingaPluginDir', 'Get-IcingaCustomPluginDir', 'Get-IcingaCacheDir', 'Get-IcingaPowerShellConfigDir' ) +FunctionsToExport = @( 'Use-Icinga', 'Import-IcingaLib', 'Publish-IcingaModuleManifests', 'Get-IcingaPluginDir', 'Get-IcingaCustomPluginDir', 'Get-IcingaCacheDir', 'Get-IcingaPowerShellConfigDir', 'Get-IcingaPowerShellModuleFile' ) # Aus diesem Modul zu exportierende Cmdlets. Um optimale Leistung zu erzielen, verwenden Sie keine Plat'zhalter und löschen den Eintrag nicht. Verwenden Sie ein leeres Array, wenn keine zu exportierenden Cmdlets vorhanden sind. CmdletsToExport = @() diff --git a/icinga-module-windows.psm1 b/icinga-module-windows.psm1 index c50c163..77f45d8 100644 --- a/icinga-module-windows.psm1 +++ b/icinga-module-windows.psm1 @@ -165,3 +165,8 @@ function Get-IcingaPowerShellConfigDir() { return (Join-Path -Path $PSScriptRoot -ChildPath 'config'); } + +function Get-IcingaPowerShellModuleFile() +{ + return (Join-Path -Path $PSScriptRoot -ChildPath 'icinga-module-windows.psm1'); +} diff --git a/lib/core/framework/Expand-IcingaZipArchive.psm1 b/lib/core/framework/Expand-IcingaZipArchive.psm1 new file mode 100644 index 0000000..658e63a --- /dev/null +++ b/lib/core/framework/Expand-IcingaZipArchive.psm1 @@ -0,0 +1,23 @@ +function Expand-IcingaZipArchive() +{ + param( + $Path, + $Destination + ); + + if ((Test-Path $Path) -eq $FALSE -Or (Test-Path $Destination) -eq $FALSE) { + Write-Host 'The path to the zip archive or the destination path do not exist'; + return $FALSE; + } + + Add-Type -AssemblyName System.IO.Compression.FileSystem; + + try { + [System.IO.Compression.ZipFile]::ExtractToDirectory($Path, $Destination); + return $TRUE; + } catch { + throw $_.Exception; + } + + return $FALSE; +} diff --git a/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 b/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 new file mode 100644 index 0000000..a80cc72 --- /dev/null +++ b/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 @@ -0,0 +1,43 @@ +function Get-IcingaFrameworkServiceBinary() +{ + param( + [string]$DownloadUrl, + [string]$InstallDir + ); + + $ProgressPreference = "SilentlyContinue"; + + if ([string]::IsNullOrEmpty($DownloadUrl)) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you provide a custom source of the service binary?' -Default 'n').result -eq 1) { + $LatestRelease = (Invoke-WebRequest -Uri 'https://github.com/LordHepipud/icinga-windows-service/releases/latest' -UseBasicParsing).BaseResponse.ResponseUri.AbsoluteUri; + $DownloadUrl = $LatestRelease.Replace('/tag/', '/download/'); + $Tag = $DownloadUrl.Split('/')[-1]; + $DownloadUrl = [string]::Format('{0}/icinga-service-{1}.zip', $DownloadUrl, $Tag); + } else { + $DownloadUrl = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the full path to your service binary repository' -Default 'v').answer; + } + } + + if ([string]::IsNullOrEmpty($InstallDir)) { + $InstallDir = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the path you wish to install the service to' -Default 'v' -DefaultInput 'C:\Program Files\icinga-framework-service\').answer; + } + + if ((Test-Path $InstallDir) -eq $FALSE) { + New-Item -Path $InstallDir -Force -ItemType Directory | Out-Null; + } + + $ZipArchive = Join-Path -Path $InstallDir -ChildPath ($DownloadUrl.Split('/')[-1]); + $ServiceBin = Join-Path -Path $InstallDir -ChildPath 'icinga-service.exe'; + + Invoke-WebRequest -Uri $DownloadUrl -UseBasicParsing -OutFile $ZipArchive; + + if ((Expand-IcingaZipArchive -Path $ZipArchive -Destination $InstallDir) -eq $FALSE) { + throw 'Failed to expand the downloaded ZIP archive'; + } + + if ((Test-IcingaZipBinaryChecksum -Path $ServiceBin) -eq $FALSE) { + throw 'The checksum of the downloaded file and the required MD5 hash are not matching'; + } + + return $ServiceBin; +} diff --git a/lib/core/framework/Install-IcingaPowerShellService.psm1 b/lib/core/framework/Install-IcingaPowerShellService.psm1 new file mode 100644 index 0000000..cd1e2da --- /dev/null +++ b/lib/core/framework/Install-IcingaPowerShellService.psm1 @@ -0,0 +1,26 @@ +function Install-IcingaPowerShellService() +{ + param( + $Path, + $Username, + [SecureString]$Password + ); + + if ((Test-Path $Path) -eq $FALSE) { + throw 'Please specify the path directly to the service binary'; + } + + $Path = [string]::Format( + '{0} \"{1}\"', + $Path, + (Get-IcingaPowerShellModuleFile) + ); + + $ServiceCreation = Start-IcingaProcess -Executable 'sc.exe' -Arguments ([string]::Format('create icingapowershell binPath= "{0}" DisplayName= "Icinga PowerShell Service" start= auto', $Path)); + + if ($ServiceCreation.ExitCode -ne 0) { + throw ([string]::Format('Failed to install Icinga PowerShell Service: {0}{1}', $ServiceCreation.Message, $ServiceCreation.Error)); + } + + return (Set-IcingaAgentServiceUser -User $Username -Password $Password -Service 'icingapowershell'); +} diff --git a/lib/core/framework/Test-IcingaZipBinaryChecksum.psm1 b/lib/core/framework/Test-IcingaZipBinaryChecksum.psm1 new file mode 100644 index 0000000..94612fa --- /dev/null +++ b/lib/core/framework/Test-IcingaZipBinaryChecksum.psm1 @@ -0,0 +1,23 @@ +function Test-IcingaZipBinaryChecksum() +{ + param( + $Path + ); + + $MD5Path = [string]::Format('{0}.md5', $Path); + + if ((Test-Path $MD5Path) -eq $FALSE) { + return $TRUE; + } + + [string]$MD5Checksum = Get-Content $MD5Path; + $MD5Checksum = ($MD5Checksum.Split(' ')[0]).ToLower(); + + $FileHash = ((Get-FileHash $Path -Algorithm MD5).Hash).ToLower(); + + if ($MD5Checksum -ne $FileHash) { + return $FALSE; + } + + return $TRUE; +} From 891532aff2650abcbee1677a4bee90ea950dc4b7 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 31 Oct 2019 14:31:49 +0100 Subject: [PATCH 212/259] Fixes uninstall process to stop icinga service first --- lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 b/lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 index 4afea1b..cb99f8f 100644 --- a/lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 +++ b/lib/core/icingaagent/installer/Uninstall-IcingaAgent.psm1 @@ -9,6 +9,8 @@ function Uninstall-IcingaAgent() Write-Host 'Removing current installed Icinga Agent'; + Stop-IcingaService 'icinga2'; + $Uninstaller = Start-IcingaProcess -Executable 'MsiExec.exe' -Arguments ([string]::Format('{0} /q', $IcingaData.Uninstaller)) -FlushNewLine; if ($Uninstaller.ExitCode -ne 0) { From 89a0b4a0bdcd57d4186ec35691bb05af7c27e795 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 31 Oct 2019 14:32:19 +0100 Subject: [PATCH 213/259] Add smart service interaction functions --- lib/core/framework/Restart-IcingaService.psm1 | 10 ++++++++++ lib/core/framework/Start-IcingaService.psm1 | 10 ++++++++++ lib/core/framework/Stop-IcingaService.psm1 | 10 ++++++++++ 3 files changed, 30 insertions(+) create mode 100644 lib/core/framework/Restart-IcingaService.psm1 create mode 100644 lib/core/framework/Start-IcingaService.psm1 create mode 100644 lib/core/framework/Stop-IcingaService.psm1 diff --git a/lib/core/framework/Restart-IcingaService.psm1 b/lib/core/framework/Restart-IcingaService.psm1 new file mode 100644 index 0000000..ce0f009 --- /dev/null +++ b/lib/core/framework/Restart-IcingaService.psm1 @@ -0,0 +1,10 @@ +function Restart-IcingaService() +{ + param( + $Service + ); + + if (Get-Service $Service -ErrorAction SilentlyContinue) { + Restart-Service $Service; + } +} diff --git a/lib/core/framework/Start-IcingaService.psm1 b/lib/core/framework/Start-IcingaService.psm1 new file mode 100644 index 0000000..ec4b5a7 --- /dev/null +++ b/lib/core/framework/Start-IcingaService.psm1 @@ -0,0 +1,10 @@ +function Start-IcingaService() +{ + param( + $Service + ); + + if (Get-Service $Service -ErrorAction SilentlyContinue) { + Start-Service $Service; + } +} diff --git a/lib/core/framework/Stop-IcingaService.psm1 b/lib/core/framework/Stop-IcingaService.psm1 new file mode 100644 index 0000000..ef91fa8 --- /dev/null +++ b/lib/core/framework/Stop-IcingaService.psm1 @@ -0,0 +1,10 @@ +function Stop-IcingaService() +{ + param( + $Service + ); + + if (Get-Service $Service -ErrorAction SilentlyContinue) { + Stop-Service $Service; + } +} From 4285889b52407eb74411b89408cb8c8358533e60 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 31 Oct 2019 14:32:49 +0100 Subject: [PATCH 214/259] Rename IcingaPowerShellService to IcingaFrameworkService --- ...hellService.psm1 => Install-IcingaFrameworkService.psm1} | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) rename lib/core/framework/{Install-IcingaPowerShellService.psm1 => Install-IcingaFrameworkService.psm1} (80%) diff --git a/lib/core/framework/Install-IcingaPowerShellService.psm1 b/lib/core/framework/Install-IcingaFrameworkService.psm1 similarity index 80% rename from lib/core/framework/Install-IcingaPowerShellService.psm1 rename to lib/core/framework/Install-IcingaFrameworkService.psm1 index cd1e2da..71abdb3 100644 --- a/lib/core/framework/Install-IcingaPowerShellService.psm1 +++ b/lib/core/framework/Install-IcingaFrameworkService.psm1 @@ -1,8 +1,8 @@ -function Install-IcingaPowerShellService() +function Install-IcingaFrameworkService() { param( $Path, - $Username, + $User, [SecureString]$Password ); @@ -22,5 +22,5 @@ function Install-IcingaPowerShellService() throw ([string]::Format('Failed to install Icinga PowerShell Service: {0}{1}', $ServiceCreation.Message, $ServiceCreation.Error)); } - return (Set-IcingaAgentServiceUser -User $Username -Password $Password -Service 'icingapowershell'); + return (Set-IcingaAgentServiceUser -User $User -Password $Password -Service 'icingapowershell'); } From 3b4eae6fc95317d2ef3e13d2f2c0612175d6055e Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 31 Oct 2019 14:33:56 +0100 Subject: [PATCH 215/259] Extend setup wizard with powershell framework service --- .../Get-IcingaFrameworkServiceBinary.psm1 | 38 ++++++++++--------- .../misc/Start-IcingaAgentInstallWizard.psm1 | 25 +++++++++++- 2 files changed, 44 insertions(+), 19 deletions(-) diff --git a/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 b/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 index a80cc72..97c8396 100644 --- a/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 +++ b/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 @@ -1,37 +1,37 @@ function Get-IcingaFrameworkServiceBinary() { param( - [string]$DownloadUrl, - [string]$InstallDir + [string]$FrameworkServiceUrl, + [string]$ServiceDirectory ); $ProgressPreference = "SilentlyContinue"; - if ([string]::IsNullOrEmpty($DownloadUrl)) { + if ([string]::IsNullOrEmpty($FrameworkServiceUrl)) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you provide a custom source of the service binary?' -Default 'n').result -eq 1) { - $LatestRelease = (Invoke-WebRequest -Uri 'https://github.com/LordHepipud/icinga-windows-service/releases/latest' -UseBasicParsing).BaseResponse.ResponseUri.AbsoluteUri; - $DownloadUrl = $LatestRelease.Replace('/tag/', '/download/'); - $Tag = $DownloadUrl.Split('/')[-1]; - $DownloadUrl = [string]::Format('{0}/icinga-service-{1}.zip', $DownloadUrl, $Tag); + $LatestRelease = (Invoke-WebRequest -Uri 'https://github.com/LordHepipud/icinga-windows-service/releases/latest' -UseBasicParsing).BaseResponse.ResponseUri.AbsoluteUri; + $FrameworkServiceUrl = $LatestRelease.Replace('/tag/', '/download/'); + $Tag = $FrameworkServiceUrl.Split('/')[-1]; + $FrameworkServiceUrl = [string]::Format('{0}/icinga-service-{1}.zip', $FrameworkServiceUrl, $Tag); } else { - $DownloadUrl = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the full path to your service binary repository' -Default 'v').answer; + $FrameworkServiceUrl = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the full path to your service binary repository' -Default 'v').answer; } } - if ([string]::IsNullOrEmpty($InstallDir)) { - $InstallDir = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the path you wish to install the service to' -Default 'v' -DefaultInput 'C:\Program Files\icinga-framework-service\').answer; + if ([string]::IsNullOrEmpty($ServiceDirectory)) { + $ServiceDirectory = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the path you wish to install the service to' -Default 'v' -DefaultInput 'C:\Program Files\icinga-framework-service\').answer; } - if ((Test-Path $InstallDir) -eq $FALSE) { - New-Item -Path $InstallDir -Force -ItemType Directory | Out-Null; + if ((Test-Path $ServiceDirectory) -eq $FALSE) { + New-Item -Path $ServiceDirectory -Force -ItemType Directory | Out-Null; } - $ZipArchive = Join-Path -Path $InstallDir -ChildPath ($DownloadUrl.Split('/')[-1]); - $ServiceBin = Join-Path -Path $InstallDir -ChildPath 'icinga-service.exe'; + $ZipArchive = Join-Path -Path $ServiceDirectory -ChildPath ($FrameworkServiceUrl.Split('/')[-1]); + $ServiceBin = Join-Path -Path $ServiceDirectory -ChildPath 'icinga-service.exe'; - Invoke-WebRequest -Uri $DownloadUrl -UseBasicParsing -OutFile $ZipArchive; + Invoke-WebRequest -Uri $FrameworkServiceUrl -UseBasicParsing -OutFile $ZipArchive; - if ((Expand-IcingaZipArchive -Path $ZipArchive -Destination $InstallDir) -eq $FALSE) { + if ((Expand-IcingaZipArchive -Path $ZipArchive -Destination $ServiceDirectory) -eq $FALSE) { throw 'Failed to expand the downloaded ZIP archive'; } @@ -39,5 +39,9 @@ function Get-IcingaFrameworkServiceBinary() throw 'The checksum of the downloaded file and the required MD5 hash are not matching'; } - return $ServiceBin; + return @{ + 'FrameworkServiceUrl' = $FrameworkServiceUrl; + 'ServiceDirectory' = $ServiceDirectory; + 'ServiceBin' = $ServiceBin; + }; } diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index 40f6c08..dc9cc37 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -24,7 +24,11 @@ function Start-IcingaAgentInstallWizard() [switch]$RunInstaller, [switch]$Reconfigure, [string]$ServiceUser, - [securestring]$ServicePass = $null + [securestring]$ServicePass = $null, + $InstallFrameworkService = $null, + $FrameworkServiceUrl = $null, + $ServiceDirectory = $null, + $ServiceBin = $null ); [array]$InstallerArguments = @(); @@ -249,6 +253,20 @@ function Start-IcingaAgentInstallWizard() } } + if ($null -eq $InstallFrameworkService) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to install the PowerShell Framework as Service?' -Default 'y').result -eq 1) { + $result = Get-IcingaFrameworkServiceBinary; + $InstallerArguments += "-InstallFrameworkService 1"; + $InstallerArguments += [string]::Format("-FrameworkServiceUrl '{0}'", $result.FrameworkServiceUrl); + $InstallerArguments += [string]::Format("-ServiceDirectory '{0}'", $result.ServiceDirectory); + $InstallerArguments += [string]::Format("-ServiceBin '{0}'", $result.ServiceBin); + $ServiceBin = $result.ServiceBin; + } + } elseif ($InstallFrameworkService -eq $TRUE) { + $result = Get-IcingaFrameworkServiceBinary -FrameworkServiceUrl $FrameworkServiceUrl -ServiceDirectory $ServiceDirectory; + $ServiceBin = $result.ServiceBin; + } + if ($InstallerArguments.Count -ne 0) { $InstallerArguments += "-RunInstaller"; Write-Host 'The wizard is complete. These are the configured settings:'; @@ -276,12 +294,15 @@ function Start-IcingaAgentInstallWizard() Set-IcingaAcl "$Env:ProgramData\icinga2\etc"; Set-IcingaAcl "$Env:ProgramData\icinga2\var"; Set-IcingaAcl (Get-IcingaCacheDir); + Install-IcingaFrameworkService -Path $ServiceBin -User $ServiceUser -Password $ServicePass | Out-Null; + Register-IcingaBackgroundDaemon -Command 'Start-IcingaServiceCheckDaemon'; Install-IcingaAgentBaseFeatures; Install-IcingaAgentCertificates -Hostname $Hostname -Endpoint $CAEndpoint -Port $CAPort -CACert $CAFile -Ticket $Ticket | Out-Null; Write-IcingaAgentApiConfig -Port $CAPort; Write-IcingaAgentZonesConfig -Endpoints $Endpoints -EndpointConnections $EndpointConnections -ParentZone $ParentZone -GlobalZones $GlobalZoneConfig -Hostname $Hostname; Test-IcingaAgent; - Restart-Service icinga2; + Restart-IcingaService 'icingapowershell'; + Restart-IcingaService 'icinga2'; } } } From 9893c6b4b0f36dda26ad4514fc87c7b78d6d7d33 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 31 Oct 2019 14:35:13 +0100 Subject: [PATCH 216/259] Updates Framework Kickstarter Script --- doc/installation/01-KickstartScript.md | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/doc/installation/01-KickstartScript.md b/doc/installation/01-KickstartScript.md index 7c76ec5..b3e347f 100644 --- a/doc/installation/01-KickstartScript.md +++ b/doc/installation/01-KickstartScript.md @@ -12,7 +12,10 @@ Getting Started [Net.ServicePointManager]::SecurityProtocol = "tls12, tls11"; $ProgressPreference = "SilentlyContinue"; -$Script = (Invoke-WebRequest -UseBasicParsing -Uri 'https://raw.githubusercontent.com/LordHepipud/icinga-framework-kickstart/master/script/icinga-framework-kickstart.ps1').Content; +$global:IcingaFrameworkKickstartSource = 'https://raw.githubusercontent.com/LordHepipud/icinga-framework-kickstart/master/script/icinga-framework-kickstart.ps1'; + +$Script = (Invoke-WebRequest -UseBasicParsing -Uri $global:IcingaFrameworkKickstartSource).Content; +$Script += "`r`n`r`n Start-IcingaFrameworkWizard;"; Invoke-Command -ScriptBlock ([Scriptblock]::Create($Script)); ``` From 8f0b8f820328b3d8b477f0f198eb2a4f80242417 Mon Sep 17 00:00:00 2001 From: Crited Date: Thu, 31 Oct 2019 15:01:29 +0100 Subject: [PATCH 217/259] Adds CheckSumCheck-FirstDraft/Attempt/Suggestion --- lib/plugins/Invoke-IcingaCheckCheckSum.psm1 | 65 +++++++++++++++++++++ lib/plugins/Invoke-IcingaCheckMemory.psm1 | 7 --- 2 files changed, 65 insertions(+), 7 deletions(-) create mode 100644 lib/plugins/Invoke-IcingaCheckCheckSum.psm1 diff --git a/lib/plugins/Invoke-IcingaCheckCheckSum.psm1 b/lib/plugins/Invoke-IcingaCheckCheckSum.psm1 new file mode 100644 index 0000000..1d2cc02 --- /dev/null +++ b/lib/plugins/Invoke-IcingaCheckCheckSum.psm1 @@ -0,0 +1,65 @@ +<# +.SYNOPSIS + Checks hash against filehash of a file +.DESCRIPTION + Invoke-IcingaCheckCheckSum returns either 'OK' or 'CRITICAL', whether the check matches or not. + + More Information on https://github.com/LordHepipud/icinga-module-windows +.FUNCTIONALITY + This module is intended to be used to check a hash against a filehash of a file, to determine whether changes have occured. + Based on the match result the status will change between 'OK' or 'CRITICAL'. The function will return one of these given codes. +.EXAMPLE + PS> Invoke-IcingaCheckCheckSum -Path "C:\Users\Icinga\Downloads\test.txt" + [OK] CheckSum C:\Users\Icinga\Downloads\test.txt is 008FB84A017F5DFDAF038DB2FDD6934E6E5D9CD3C7AACE2F2168D7D93AF51E4B + |0 +.EXAMPLE + PS> Invoke-IcingaCheckCheckSum -Path "C:\Users\Icinga\Downloads\test.txt" -Hash 008FB84A017F5DFDAF038DB2FDD6934E6E5D9CD3C7AACE2F2168D7D93AF51E4B + [OK] CheckSum C:\Users\Icinga\Downloads\test.txt is 008FB84A017F5DFDAF038DB2FDD6934E6E5D9CD3C7AACE2F2168D7D93AF51E4B| + 0 +.EXAMPLE + PS> Invoke-IcingaCheckCheckSum -Path "C:\Users\Icinga\Downloads\test.txt" -Hash 008FB84A017F5DFDAF038DB2FDD6934E6E5D + [CRITICAL] CheckSum C:\Users\Icinga\Downloads\test.txt 008FB84A017F5DFDAF038DB2FDD6934E6E5D9CD3C7AACE2F2168D7D93AF51E4B is not matching 008FB84A017F5DFDAF038DB2FDD6934E6E5D + | + 2 +.PARAMETER WarningBytes + Used to specify a string to the path of a file, which will be checked. + + The string has to be like "C:\Users\Icinga\test.txt" + +.PARAMETER Algorithm + Used to specify a string, which contains the algorithm to be used. + + Allowed algorithms: 'SHA1', 'SHA256', 'SHA384', 'SHA512', 'MD5' + +.INPUTS + System.String + +.OUTPUTS + System.String + +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> + +function Invoke-IcingaCheckCheckSum() +{ + param( + [string]$Path = $null, + [ValidateSet]('SHA1', 'SHA256', 'SHA384', 'SHA512', 'MD5') + [string]$Algorithm = 'SHA256', + [string]$Hash = $null, + [switch]$NoPerfData, + [ValidateSet(0, 1, 2, 3)] + [int]$Verbosity = 0 + ); + + [string]$FileHash = (Get-FileHash $Path -Algorithm $Algorithm).Hash + $CheckSumCheck = New-IcingaCheck -Name "CheckSum $Path" -Value $FileHash; + + If(([string]::IsNullOrEmpty($Hash)) -eq $FALSE){ + $CheckSumCheck.CritIfNotMatch($Hash) | Out-Null; + } + + return (New-IcingaCheckresult -Check $CheckSumCheck -NoPerfData $NoPerfData -Compile); +} \ No newline at end of file diff --git a/lib/plugins/Invoke-IcingaCheckMemory.psm1 b/lib/plugins/Invoke-IcingaCheckMemory.psm1 index 230f510..210f109 100644 --- a/lib/plugins/Invoke-IcingaCheckMemory.psm1 +++ b/lib/plugins/Invoke-IcingaCheckMemory.psm1 @@ -52,10 +52,6 @@ Import-IcingaLib core\tools; .NOTES #> -<# -if ($bytes > 1099511627776) { return sprintf('%.2f TB', $bytes / 1099511627776); } elseif ($bytes > 1073741824) { return sprintf('%.2f GB', $bytes / 1073741824); } elseif ($bytes > 1048576) { return sprintf('%.2f MB', $bytes / 1048576); } else { return sprintf('%.2f KB', $bytes / 1024); -#> - function Invoke-IcingaCheckMemory() { param( @@ -104,8 +100,6 @@ function Invoke-IcingaCheckMemory() #$MemoryByteAvailable = New-IcingaCheck -Name "Available Bytes" -Value $MemoryData['Memory Available Bytes'] -Unit 'B'; #$PageFileCheck = New-IcingaCheck -Name 'PageFile Percent' -Value $MemoryData['PageFile %'] -Unit '%'; - - #Kommastellen bedenken! # PageFile To-Do $MemoryByteUsed.WarnOutOfRange($WarningConverted).CritOutOfRange($CrticalConverted) | Out-Null; $MemoryPerc.WarnOutOfRange($WarningPercent).CritOutOfRange($CriticalPercent) | Out-Null; @@ -113,7 +107,6 @@ function Invoke-IcingaCheckMemory() $MemoryPackage.AddCheck($MemoryPerc); #$MemoryPackage.AddCheck($MemoryByteAvailable); $MemoryPackage.AddCheck($MemoryByteUsed); - #$MemoryPackage.AddCheck($PageFileCheck); return (New-IcingaCheckResult -Check $MemoryPackage -NoPerfData $NoPerfData -Compile); From dbc577ec61bf796b3ec0c308403551b5bdcd0c9b Mon Sep 17 00:00:00 2001 From: Crited Date: Thu, 31 Oct 2019 16:15:09 +0100 Subject: [PATCH 218/259] Fix typo in CheckSum, Added First-Draft/Suggestion/Attempt for Firewall-ProfileCheck --- lib/plugins/Invoke-IcingaCheckCheckSum.psm1 | 2 +- lib/plugins/Invoke-IcingaCheckFirewall.psm1 | 73 +++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) create mode 100644 lib/plugins/Invoke-IcingaCheckFirewall.psm1 diff --git a/lib/plugins/Invoke-IcingaCheckCheckSum.psm1 b/lib/plugins/Invoke-IcingaCheckCheckSum.psm1 index 1d2cc02..a11d50a 100644 --- a/lib/plugins/Invoke-IcingaCheckCheckSum.psm1 +++ b/lib/plugins/Invoke-IcingaCheckCheckSum.psm1 @@ -46,7 +46,7 @@ function Invoke-IcingaCheckCheckSum() { param( [string]$Path = $null, - [ValidateSet]('SHA1', 'SHA256', 'SHA384', 'SHA512', 'MD5') + [ValidateSet('SHA1', 'SHA256', 'SHA384', 'SHA512', 'MD5')] [string]$Algorithm = 'SHA256', [string]$Hash = $null, [switch]$NoPerfData, diff --git a/lib/plugins/Invoke-IcingaCheckFirewall.psm1 b/lib/plugins/Invoke-IcingaCheckFirewall.psm1 new file mode 100644 index 0000000..8857e4e --- /dev/null +++ b/lib/plugins/Invoke-IcingaCheckFirewall.psm1 @@ -0,0 +1,73 @@ +<# +.SYNOPSIS + Checks whether a firewall module is enabled or not +.DESCRIPTION + Invoke-IcingaCheckFirewall returns either 'OK' or 'CRITICAL', whether the check matches or not. + + More Information on https://github.com/LordHepipud/icinga-module-windows +.FUNCTIONALITY + This module is intended to be used to check the status of a firewall profile. + Based on the match result the status will change between 'OK' or 'CRITICAL'. The function will return one of these given codes. +.EXAMPLE + PS> Invoke-IcingaCheckFirewall -Profile "Domain" -Verbosity 3 + [OK] Check package "Firewall profiles" (Match All) + \_ [OK] Firewall Profile Domain is True + | 'firewall_profile_domain'=True;; + 0 +.EXAMPLE + PS> Invoke-IcingaCheckFirewall -Profile "Domain", "Private" -Verbosity 1} + [OK] Check package "Firewall profiles" (Match All) + | 'firewall_profile_domain'=True;; 'firewall_profile_private'=True;; + 0 + [array]$Profile, + [bool]$Status = $TRUE, +.PARAMETER Profile + Used to specify an array of profiles to check. + +.PARAMETER Status + Used to specify a bool value, which determines, whether the firewall profiles should be enabled or disabled. + + -Status $TRUE + translates to enabled, while + -Status $FALSE + translates to disabled. +.INPUTS + System.String + +.OUTPUTS + System.String + +.LINK + https://github.com/LordHepipud/icinga-module-windows +.NOTES +#> + +function Invoke-IcingaCheckFirewall() +{ + param( + [array]$Profile, + [bool]$Status = $TRUE, + [switch]$NoPerfData, + [int]$Verbosity = 0 + ); + + if ($Status -eq $TRUE) { + $StatusString = "true" + } else { + $StatusString = "false" + } + + $FirewallPackage = New-IcingaCheckPackage -Name 'Firewall profiles' -OperatorAnd -Verbos $Verbosity; + + foreach ($singleprofile in $Profile) { + $FirewallData = (Get-NetFirewallProfile -Name $singleprofile) + + $FirewallCheck = New-IcingaCheck -Name "Firewall Profile $singleprofile" -Value $FirewallData.Enabled; + $FirewallCheck.CritIfNotMatch($StatusString) | Out-Null; + + $FirewallPackage.AddCheck($FirewallCheck) + } + + + return (New-IcingaCheckResult -Check $FirewallPackage -NoPerfData $NoPerfData -Compile); +} \ No newline at end of file From 78a2cf44661204f2379d47baacd4d8dda7d32ce0 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 31 Oct 2019 16:35:50 +0100 Subject: [PATCH 219/259] Fixes spelling and adding default values --- .../icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index dc9cc37..c6cd715 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -68,7 +68,7 @@ function Start-IcingaAgentInstallWizard() if ($IcingaAgent.Installed -eq $FALSE) { if ([string]::IsNullOrEmpty($PackageSource)) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to install the Icinga Agent now?' -Default 'y').result -eq 1) { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to use a different package source then "https://packages.icinga.com/windows/" ?' -Default 'n').result -eq 0) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to use a different package source then "https://packages.icinga.com/windows/"?' -Default 'n').result -eq 0) { $PackageSource = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify your package source' -Default 'v').answer; $InstallerArguments += "-PackageSource '$PackageSource'"; } else { @@ -80,7 +80,7 @@ function Start-IcingaAgentInstallWizard() } if ([string]::IsNullOrEmpty($AgentVersion)) { - $AgentVersion = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the version you wish to install ("latest", "snapshot", or a version like "2.11.0")' -Default 'v').answer; + $AgentVersion = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the version you wish to install ("latest", "snapshot", or a version like "2.11.0")' -Default 'v' -DefaultInput 'latest').answer; $InstallerArguments += "-AgentVersion '$AgentVersion'"; Write-Host ([string]::Format('Installing Icinga Version: "{0}"', $AgentVersion)); @@ -254,7 +254,7 @@ function Start-IcingaAgentInstallWizard() } if ($null -eq $InstallFrameworkService) { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to install the PowerShell Framework as Service?' -Default 'y').result -eq 1) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to install the PowerShell Framework as a Service?' -Default 'y').result -eq 1) { $result = Get-IcingaFrameworkServiceBinary; $InstallerArguments += "-InstallFrameworkService 1"; $InstallerArguments += [string]::Format("-FrameworkServiceUrl '{0}'", $result.FrameworkServiceUrl); From 621af88831381c7623e25bf98e413a0b4d6cbe51 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 31 Oct 2019 16:36:55 +0100 Subject: [PATCH 220/259] Fixes crash on existing service binary file --- .../framework/Get-IcingaFrameworkServiceBinary.psm1 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 b/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 index 97c8396..071e7b7 100644 --- a/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 +++ b/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 @@ -31,6 +31,16 @@ function Get-IcingaFrameworkServiceBinary() Invoke-WebRequest -Uri $FrameworkServiceUrl -UseBasicParsing -OutFile $ZipArchive; + if ((Test-Path $ServiceBin)) { + Write-Host 'Icinga Service Binary already present. Skipping extrating'; + + return @{ + 'FrameworkServiceUrl' = $FrameworkServiceUrl; + 'ServiceDirectory' = $ServiceDirectory; + 'ServiceBin' = $ServiceBin; + }; + } + if ((Expand-IcingaZipArchive -Path $ZipArchive -Destination $ServiceDirectory) -eq $FALSE) { throw 'Failed to expand the downloaded ZIP archive'; } From fac0bdb30a52ce442f98a7f39c2b8bae82f62c34 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 31 Oct 2019 16:37:05 +0100 Subject: [PATCH 221/259] Fixes spelling --- doc/02-Installation.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/doc/02-Installation.md b/doc/02-Installation.md index 39657aa..554e7c3 100644 --- a/doc/02-Installation.md +++ b/doc/02-Installation.md @@ -1,13 +1,13 @@ Installing the Module === -Installing the module is managed by differen ways, depending on the user environment including available possibitilies +Installing the module is managed by different ways, depending on the user environment including available possibitilies Instructions --- * Install the Module with the [Kickstart Script](installation/01-KickstartScript.md) -* Install the module [manually](installation/02-ManualInstallation.md) +* Install the Module [manually](installation/02-ManualInstallation.md) Testing the installation --- From 792ba8695596555437d22040a1c4d7e37d923a17 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 31 Oct 2019 17:24:30 +0100 Subject: [PATCH 222/259] Fixes repo links and namings --- README.md | 4 ++-- doc/10-InstallService.md | 4 ++-- doc/installation/01-KickstartScript.md | 4 ++-- doc/installation/02-ManualInstallation.md | 8 +++---- ...s.psd1 => icinga-powershell-framework.psd1 | 2 +- ...s.psm1 => icinga-powershell-framework.psm1 | 13 +++++++--- .../Get-IcingaFrameworkServiceBinary.psm1 | 2 +- lib/core/tools/ConvertTo-ByteUnitSI.psm1 | 24 +++++++++---------- lib/core/tools/ConvertTo-Seconds.psm1 | 4 ++-- .../tools/Get-IcingaCheckCommandConfig.psm1 | 4 ++-- lib/core/tools/Set-NumericNegative.psm1 | 4 ++-- lib/core/tools/Test-Numeric.psm1 | 4 ++-- lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 | 4 ++-- lib/plugins/Invoke-IcingaCheckCPU.psm1 | 4 ++-- lib/plugins/Invoke-IcingaCheckCheckSum.psm1 | 4 ++-- lib/plugins/Invoke-IcingaCheckDirectory.psm1 | 4 ++-- lib/plugins/Invoke-IcingaCheckEventlog.psm1 | 4 ++-- lib/plugins/Invoke-IcingaCheckFirewall.psm1 | 4 ++-- lib/plugins/Invoke-IcingaCheckMemory.psm1 | 4 ++-- .../Invoke-IcingaCheckPerfcounter.psm1 | 4 ++-- .../Invoke-IcingaCheckProcessCount.psm1 | 4 ++-- lib/plugins/Invoke-IcingaCheckService.psm1 | 4 ++-- lib/plugins/Invoke-IcingaCheckUpdates.psm1 | 4 ++-- lib/plugins/Invoke-IcingaCheckUptime.psm1 | 4 ++-- .../Invoke-IcingaCheckUsedPartitionSpace.psm1 | 4 ++-- lib/plugins/Invoke-IcingaCheckUsers.psm1 | 4 ++-- 26 files changed, 70 insertions(+), 63 deletions(-) rename icinga-module-windows.psd1 => icinga-powershell-framework.psd1 (98%) rename icinga-module-windows.psm1 => icinga-powershell-framework.psm1 (91%) diff --git a/README.md b/README.md index cd6b33b..5654e5f 100644 --- a/README.md +++ b/README.md @@ -27,6 +27,6 @@ Contributing The Icinga Windows Module is an Open Source project and lives from your contributions. No matter whether these are feature requests, issues, translations, documentation or code. -* Please check whether a related issue alredy exists on our [Issue Tracker](https://github.com/LordHepipud/icinga-module-windows/issues) -* Send a [Pull Request](https://github.com/LordHepipud/icinga-module-windows/pulls) +* Please check whether a related issue alredy exists on our [Issue Tracker](https://github.com/Icinga/icinga-powershell-framework/issues) +* Send a [Pull Request](https://github.com/Icinga/icinga-powershell-framework/pulls) * The master branche shall never be corrupt! diff --git a/doc/10-InstallService.md b/doc/10-InstallService.md index ae05aae..92a2214 100644 --- a/doc/10-InstallService.md +++ b/doc/10-InstallService.md @@ -6,12 +6,12 @@ Requirements As PowerShell Scripts / Modules can not be installed directly as Windows Service, we will require a little assistance here. -In order to make this work, you will require the Icinga Windows Service which can be downloaded directly from the [GitHub Repository](https://github.com/LordHepipud/icinga-windows-service). +In order to make this work, you will require the Icinga Windows Service which can be downloaded directly from the [GitHub Repository](https://github.com/Icinga/icinga-windows-service). Install the Service --- -At first you will require the Service Binary from the [Icinga Windows Service GitHub Repository](https://github.com/LordHepipud/icinga-windows-service) and copy the binary locally to your system. A recommended path would be your Program Files / Program Files (x86) directory. +At first you will require the Service Binary from the [Icinga Windows Service GitHub Repository](https://github.com/Icinga/icinga-windows-service) and copy the binary locally to your system. A recommended path would be your Program Files / Program Files (x86) directory. Any other custom location is fully supported, has to be however accessable from the Windows Service Environment. diff --git a/doc/installation/01-KickstartScript.md b/doc/installation/01-KickstartScript.md index b3e347f..8ac9d1d 100644 --- a/doc/installation/01-KickstartScript.md +++ b/doc/installation/01-KickstartScript.md @@ -1,7 +1,7 @@ Install the framework with the Kickstart Script === -The easiest way to install the framework is by using the Kickstart Script provided from [this repository](https://github.com/LordHepipud/icinga-framework-kickstart). +The easiest way to install the framework is by using the Kickstart Script provided from [this repository](https://github.com/Icinga/icinga-framework-kickstart). The code provided there will ask questions on where to install the framework and where the framework files are provided from. The code below is a straight copy of the initial required code-block. Simply open a PowerShell instance as administrator and copy the following code block into it: @@ -12,7 +12,7 @@ Getting Started [Net.ServicePointManager]::SecurityProtocol = "tls12, tls11"; $ProgressPreference = "SilentlyContinue"; -$global:IcingaFrameworkKickstartSource = 'https://raw.githubusercontent.com/LordHepipud/icinga-framework-kickstart/master/script/icinga-framework-kickstart.ps1'; +$global:IcingaFrameworkKickstartSource = 'https://raw.githubusercontent.com/Icinga/icinga-framework-kickstart/master/script/icinga-framework-kickstart.ps1'; $Script = (Invoke-WebRequest -UseBasicParsing -Uri $global:IcingaFrameworkKickstartSource).Content; $Script += "`r`n`r`n Start-IcingaFrameworkWizard;"; diff --git a/doc/installation/02-ManualInstallation.md b/doc/installation/02-ManualInstallation.md index 8515229..d87b865 100644 --- a/doc/installation/02-ManualInstallation.md +++ b/doc/installation/02-ManualInstallation.md @@ -19,13 +19,13 @@ To be able to use the module, you will require to have named the folder **exactl Example folder path: ```powershell -C:\Program Files\WindowsPowerShell\Modules\icinga-module-windows +C:\Program Files\WindowsPowerShell\Modules\icinga-powershell-framework ``` To validate if the module is installed properly, you can start a **new** PowerShell instance and type the following command ```powershell -Get-Module -ListAvailable -Name icinga-module-windows +Get-Module -ListAvailable -Name icinga-powershell-framework ``` If you receive an output stating that the module is installed, you are fine to continue. @@ -35,10 +35,10 @@ Execution Policies and File Blocking In order to be able to run the module on certain Windows Hosts, it might be required to either update the execution policies and/or unblock the module script files. -The prefered way is to simply unblock the script files, allowing them to be executed on the system. This can be done by running a PowerShell instance as **Administrator** and enter the following command (we assume the module is installed at `C:\Program Files\WindowsPowershell\Modules\icinga-module-windows`. If not, please modify the command with the correct location) +The prefered way is to simply unblock the script files, allowing them to be executed on the system. This can be done by running a PowerShell instance as **Administrator** and enter the following command (we assume the module is installed at `C:\Program Files\WindowsPowershell\Modules\icinga-powershell-framework`. If not, please modify the command with the correct location) ```powershell -Get-ChildItem -Path 'C:\Program Files\WindowsPowershell\Modules\icinga-module-windows' -Recurse | Unblock-File +Get-ChildItem -Path 'C:\Program Files\WindowsPowershell\Modules\icinga-powershell-framework' -Recurse | Unblock-File ``` Once done, please try again if you are now able to run the module on your host. If you are still not able to run the module and/or its scripts, please have a look on the Microsoft documentation for the [Set-Execution-Policy](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-6) Cmdlet to modify the Execution Policy for running PowerShell modules on your host, matching your internal guidelines. diff --git a/icinga-module-windows.psd1 b/icinga-powershell-framework.psd1 similarity index 98% rename from icinga-module-windows.psd1 rename to icinga-powershell-framework.psd1 index e8e36fe..236f170 100644 --- a/icinga-module-windows.psd1 +++ b/icinga-powershell-framework.psd1 @@ -1,7 +1,7 @@ @{ # Script module or binary module file associated with this manifest. -ModuleToProcess = 'icinga-module-windows.psm1' +ModuleToProcess = 'icinga-powershell-framework.psm1' # Module version number ModuleVersion = '0.0.1' diff --git a/icinga-module-windows.psm1 b/icinga-powershell-framework.psm1 similarity index 91% rename from icinga-module-windows.psm1 rename to icinga-powershell-framework.psm1 index 77f45d8..9cfdf0f 100644 --- a/icinga-module-windows.psm1 +++ b/icinga-powershell-framework.psm1 @@ -2,7 +2,7 @@ .Synopsis Icinga PowerShell Module - Powerfull PowerShell Framework for monitoring Windows Systems .DESCRIPTION - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .EXAMPLE Install-Icinga .NOTES @@ -51,7 +51,8 @@ function Import-IcingaLib() # possible development changes without having to create new PowerShell environments [Switch]$ForceReload, [switch]$Init, - [switch]$Custom + [switch]$Custom, + [switch]$WriteManifests ); # This is just to only allow a global loading of the module. Import-IcingaLib is ignored on every other @@ -85,6 +86,9 @@ function Import-IcingaLib() } } else { Import-Module ([string]::Format('{0}', $modulePath)) -Global; + if ($WriteManifests) { + Publish-IcingaModuleManifests -Module $moduleName; + } } } } else { @@ -98,6 +102,9 @@ function Import-IcingaLib() } Import-Module ([string]::Format('{0}.psm1', $module)) -Global; + if ($WriteManifests) { + Publish-IcingaModuleManifests -Module $moduleName; + } } } @@ -168,5 +175,5 @@ function Get-IcingaPowerShellConfigDir() function Get-IcingaPowerShellModuleFile() { - return (Join-Path -Path $PSScriptRoot -ChildPath 'icinga-module-windows.psm1'); + return (Join-Path -Path $PSScriptRoot -ChildPath 'icinga-powershell-framework.psm1'); } diff --git a/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 b/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 index 071e7b7..18a12f7 100644 --- a/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 +++ b/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 @@ -9,7 +9,7 @@ function Get-IcingaFrameworkServiceBinary() if ([string]::IsNullOrEmpty($FrameworkServiceUrl)) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you provide a custom source of the service binary?' -Default 'n').result -eq 1) { - $LatestRelease = (Invoke-WebRequest -Uri 'https://github.com/LordHepipud/icinga-windows-service/releases/latest' -UseBasicParsing).BaseResponse.ResponseUri.AbsoluteUri; + $LatestRelease = (Invoke-WebRequest -Uri 'https://github.com/Icinga/icinga-windows-service/releases/latest' -UseBasicParsing).BaseResponse.ResponseUri.AbsoluteUri; $FrameworkServiceUrl = $LatestRelease.Replace('/tag/', '/download/'); $Tag = $FrameworkServiceUrl.Split('/')[-1]; $FrameworkServiceUrl = [string]::Format('{0}/icinga-service-{1}.zip', $FrameworkServiceUrl, $Tag); diff --git a/lib/core/tools/ConvertTo-ByteUnitSI.psm1 b/lib/core/tools/ConvertTo-ByteUnitSI.psm1 index 107dc42..2602611 100644 --- a/lib/core/tools/ConvertTo-ByteUnitSI.psm1 +++ b/lib/core/tools/ConvertTo-ByteUnitSI.psm1 @@ -5,12 +5,12 @@ This module converts a given unit size to byte. e.g Kilobyte to Byte. - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .EXAMPLE PS> ConvertTo-Byte -Unit TB 200 200000000000000 .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> @@ -45,12 +45,12 @@ function ConvertTo-ByteSI() This module converts a given unit size to kilobyte. e.g byte to kilobyte. - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .EXAMPLE PS> ConvertTo-KiloByte -Unit TB 200 200000000000 .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> @@ -85,12 +85,12 @@ function ConvertTo-KiloByte() This module converts a given unit size to megabyte. e.g byte to megabyte. - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .EXAMPLE PS> ConvertTo-KiloByte -Unit TB 200 200000000 .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> @@ -125,12 +125,12 @@ function ConvertTo-MegaByte() This module converts a given unit size to gigabyte. e.g byte to gigabyte. - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .EXAMPLE PS> ConvertTo-GigaByte -Unit TB 200 200000 .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> @@ -165,12 +165,12 @@ function ConvertTo-GigaByte() This module converts a given unit size to terabyte. e.g byte to terabyte. - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .EXAMPLE PS> ConvertTo-TeraByte -Unit GB 2000000 2000 .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> @@ -205,12 +205,12 @@ function ConvertTo-TeraByte() This module converts a given unit size to petabyte. e.g byte to petabyte. - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .EXAMPLE PS> ConvertTo-PetaByte -Unit GB 2000000 2 .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> diff --git a/lib/core/tools/ConvertTo-Seconds.psm1 b/lib/core/tools/ConvertTo-Seconds.psm1 index 7553361..6472e51 100644 --- a/lib/core/tools/ConvertTo-Seconds.psm1 +++ b/lib/core/tools/ConvertTo-Seconds.psm1 @@ -7,7 +7,7 @@ Import-IcingaLib core\tools; This module converts a given time unit to seconds. e.g hours to seconds. - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .PARAMETER Value Specify unit to be converted to seconds. Allowed units: ms, s, m, h, d, w, M, y @@ -18,7 +18,7 @@ Import-IcingaLib core\tools; PS> ConvertTo-Seconds 30d 2592000 .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> diff --git a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 index e8f7bc7..5aa347c 100644 --- a/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 +++ b/lib/core/tools/Get-IcingaCheckCommandConfig.psm1 @@ -6,7 +6,7 @@ Get-IcingaCheckCommandConfig returns a JSON-file of one or all 'Invoke-IcingaCheck'-Commands, which can be imported via Icinga-Director When no single command is specified all commands will be exported, and vice versa. - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .FUNCTIONALITY This module is intended to be used to export one or all PowerShell-Modules with the namespace 'Invoke-IcingaCheck'. @@ -56,7 +56,7 @@ System.String .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> diff --git a/lib/core/tools/Set-NumericNegative.psm1 b/lib/core/tools/Set-NumericNegative.psm1 index 2ae24d9..1f898ca 100644 --- a/lib/core/tools/Set-NumericNegative.psm1 +++ b/lib/core/tools/Set-NumericNegative.psm1 @@ -5,12 +5,12 @@ This module sets a numeric value to be negative. e.g 12 to -12 - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .EXAMPLE PS> Set-NumericNegative 32 -32 .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> diff --git a/lib/core/tools/Test-Numeric.psm1 b/lib/core/tools/Test-Numeric.psm1 index ad67b36..6ba75a6 100644 --- a/lib/core/tools/Test-Numeric.psm1 +++ b/lib/core/tools/Test-Numeric.psm1 @@ -4,12 +4,12 @@ .DESCRIPTION This module tests whether a value is numeric - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .EXAMPLE PS> Test-Numeric 32 True .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> function Test-Numeric ($number) { diff --git a/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 b/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 index d4cc69e..2d13871 100644 --- a/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 +++ b/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 @@ -5,7 +5,7 @@ Import-IcingaLib provider\bios; Finds out the Bios Serial .DESCRIPTION Invoke-IcingaCheckBiosSerial returns either the Bios Serial or nothing. - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .FUNCTIONALITY This module is intended to be used to find out the Bios Serial of a given system Either the a Bios Serial is returned or not. Thereby the Check is always okay. @@ -15,7 +15,7 @@ Import-IcingaLib provider\bios; .OUTPUTS System.String .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> diff --git a/lib/plugins/Invoke-IcingaCheckCPU.psm1 b/lib/plugins/Invoke-IcingaCheckCPU.psm1 index 6f0d968..ad1fa53 100644 --- a/lib/plugins/Invoke-IcingaCheckCPU.psm1 +++ b/lib/plugins/Invoke-IcingaCheckCPU.psm1 @@ -8,7 +8,7 @@ Import-IcingaLib icinga\plugin; .DESCRIPTION Invoke-IcingaCheckCPU returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. e.g A system has 4 cores, each running at 60% usage, WARNING is set to 50%, CRITICAL is set to 75%. In this case the check will return WARNING. - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .FUNCTIONALITY This module is intended to be used to check on the current cpu usage of a specified core. Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. @@ -31,7 +31,7 @@ Import-IcingaLib icinga\plugin; .OUTPUTS System.String .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> diff --git a/lib/plugins/Invoke-IcingaCheckCheckSum.psm1 b/lib/plugins/Invoke-IcingaCheckCheckSum.psm1 index a11d50a..c399184 100644 --- a/lib/plugins/Invoke-IcingaCheckCheckSum.psm1 +++ b/lib/plugins/Invoke-IcingaCheckCheckSum.psm1 @@ -4,7 +4,7 @@ .DESCRIPTION Invoke-IcingaCheckCheckSum returns either 'OK' or 'CRITICAL', whether the check matches or not. - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .FUNCTIONALITY This module is intended to be used to check a hash against a filehash of a file, to determine whether changes have occured. Based on the match result the status will change between 'OK' or 'CRITICAL'. The function will return one of these given codes. @@ -38,7 +38,7 @@ System.String .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> diff --git a/lib/plugins/Invoke-IcingaCheckDirectory.psm1 b/lib/plugins/Invoke-IcingaCheckDirectory.psm1 index 9e2be91..c030596 100644 --- a/lib/plugins/Invoke-IcingaCheckDirectory.psm1 +++ b/lib/plugins/Invoke-IcingaCheckDirectory.psm1 @@ -6,7 +6,7 @@ Import-IcingaLib provider\directory; .DESCRIPTION Invoke-IcingaCheckDirectory returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. e.g 'C:\Users\Icinga\Backup' contains 200 files, WARNING is set to 150, CRITICAL is set to 300. In this case the check will return CRITICAL - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .FUNCTIONALITY This module is intended to be used to check how many files and directories are within are specified path. Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. @@ -72,7 +72,7 @@ Import-IcingaLib provider\directory; .OUTPUTS System.String .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> diff --git a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 index 1cea274..18b8ccc 100644 --- a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 +++ b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 @@ -7,7 +7,7 @@ Import-IcingaLib icinga\plugin; Invoke-IcingaCheckEventlog returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. e.g Eventlog returns 500 entrys with the specified parameters, WARNING is set to 200, CRITICAL is set to 800. Thereby the check will return WARNING. - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .FUNCTIONALITY This Module is intended to be used to check how many eventlog occurences of a given type there are. Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. @@ -63,7 +63,7 @@ Import-IcingaLib icinga\plugin; .OUTPUTS System.String .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> diff --git a/lib/plugins/Invoke-IcingaCheckFirewall.psm1 b/lib/plugins/Invoke-IcingaCheckFirewall.psm1 index 8857e4e..57d2bf8 100644 --- a/lib/plugins/Invoke-IcingaCheckFirewall.psm1 +++ b/lib/plugins/Invoke-IcingaCheckFirewall.psm1 @@ -4,7 +4,7 @@ .DESCRIPTION Invoke-IcingaCheckFirewall returns either 'OK' or 'CRITICAL', whether the check matches or not. - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .FUNCTIONALITY This module is intended to be used to check the status of a firewall profile. Based on the match result the status will change between 'OK' or 'CRITICAL'. The function will return one of these given codes. @@ -38,7 +38,7 @@ System.String .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> diff --git a/lib/plugins/Invoke-IcingaCheckMemory.psm1 b/lib/plugins/Invoke-IcingaCheckMemory.psm1 index 210f109..55b156c 100644 --- a/lib/plugins/Invoke-IcingaCheckMemory.psm1 +++ b/lib/plugins/Invoke-IcingaCheckMemory.psm1 @@ -8,7 +8,7 @@ Import-IcingaLib core\tools; Invoke-IcingaCheckMemory returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. e.g memory is currently at 60% usage, WARNING is set to 50, CRITICAL is set to 90. In this case the check will return WARNING. - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .FUNCTIONALITY This module is intended to be used to check on memory usage. Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. @@ -48,7 +48,7 @@ Import-IcingaLib core\tools; System.String .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> diff --git a/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 b/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 index 50726ec..2b9191c 100644 --- a/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 +++ b/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 @@ -9,7 +9,7 @@ Import-IcingaLib icinga\plugin; To gain insight on an specific performance counter use "Show-IcingaPerformanceCounters " e.g ' - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .FUNCTIONALITY This module is intended to be used to perform checks on different performance counter. Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. @@ -29,7 +29,7 @@ Import-IcingaLib icinga\plugin; .OUTPUTS System.String .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> diff --git a/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 b/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 index 7487371..8bf792a 100644 --- a/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 +++ b/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 @@ -7,7 +7,7 @@ Import-IcingaLib icinga\plugin; .DESCRIPTION Invoke-IcingaCheckDirectory returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. e.g there are three conhost processes running, WARNING is set to 3, CRITICAL is set to 4. In this case the check will return WARNING. - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .FUNCTIONALITY This module is intended to be used to check how many processes of a process exist. Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. @@ -33,7 +33,7 @@ Import-IcingaLib icinga\plugin; .OUTPUTS System.String .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> diff --git a/lib/plugins/Invoke-IcingaCheckService.psm1 b/lib/plugins/Invoke-IcingaCheckService.psm1 index 3afa6c1..743d291 100644 --- a/lib/plugins/Invoke-IcingaCheckService.psm1 +++ b/lib/plugins/Invoke-IcingaCheckService.psm1 @@ -7,7 +7,7 @@ Import-IcingaLib icinga\plugin; Checks if a service has a specified status. .DESCRIPTION Invoke-icingaCheckService returns either 'OK' or 'CRITICAL', if a service status is matching status to be checked. - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .FUNCTIONALITY This module is intended to be used to check whether one or more services have a certain status. As soon as one of the specified services does not match the status, the function returns 'CRITICAL' instead of 'OK'. @@ -26,7 +26,7 @@ Import-IcingaLib icinga\plugin; .OUTPUTS System.String .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> diff --git a/lib/plugins/Invoke-IcingaCheckUpdates.psm1 b/lib/plugins/Invoke-IcingaCheckUpdates.psm1 index 531a0fe..fc954e0 100644 --- a/lib/plugins/Invoke-IcingaCheckUpdates.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUpdates.psm1 @@ -7,7 +7,7 @@ Import-IcingaLib provider\updates; .DESCRIPTION Invoke-IcingaCheckUpdates returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. e.g 'C:\Users\Icinga\Backup' 10 updates are pending, WARNING is set to 20, CRITICAL is set to 50. In this case the check will return OK. - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .FUNCTIONALITY This module is intended to be used to check how many updates are to be applied and thereby currently pending Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. @@ -25,7 +25,7 @@ Import-IcingaLib provider\updates; .OUTPUTS System.String .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> diff --git a/lib/plugins/Invoke-IcingaCheckUptime.psm1 b/lib/plugins/Invoke-IcingaCheckUptime.psm1 index 1635539..591a0c9 100644 --- a/lib/plugins/Invoke-IcingaCheckUptime.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUptime.psm1 @@ -8,7 +8,7 @@ Import-IcingaLib core\tools; .DESCRIPTION InvokeIcingaCheckUptime returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. e.g 'C:\Users\Icinga\Backup' the system has been running for 10 days, WARNING is set to 15d, CRITICAL is set to 30d. In this case the check will return OK. - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .FUNCTIONALITY This module is intended to check how long a Windows system has been up for. Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. @@ -27,7 +27,7 @@ Import-IcingaLib core\tools; .OUTPUTS System.String .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> diff --git a/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 b/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 index 95aa13f..7ee2f0f 100644 --- a/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 @@ -7,7 +7,7 @@ Import-IcingaLib icinga\plugin; .DESCRIPTION Invoke-IcingaCheckUsedPartition returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. e.g 'C:' is at 8% usage, WARNING is set to 60, CRITICAL is set to 80. In this case the check will return OK. - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .FUNCTIONALITY This module is intended to be used to check how much usage there is on an partition. Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. @@ -38,7 +38,7 @@ Import-IcingaLib icinga\plugin; .OUTPUTS System.String .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> diff --git a/lib/plugins/Invoke-IcingaCheckUsers.psm1 b/lib/plugins/Invoke-IcingaCheckUsers.psm1 index 2fc1871..feb588e 100644 --- a/lib/plugins/Invoke-IcingaCheckUsers.psm1 +++ b/lib/plugins/Invoke-IcingaCheckUsers.psm1 @@ -7,7 +7,7 @@ Import-IcingaLib provider\users; .DESCRIPTION Invoke-IcingaCheckDirectory returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. e.g 'C:\Users\Icinga\Backup' contains 200 files, WARNING is set to 150, CRITICAL is set to 300. In this case the check will return CRITICAL - More Information on https://github.com/LordHepipud/icinga-module-windows + More Information on https://github.com/Icinga/icinga-powershell-framework .FUNCTIONALITY This module is intended to be used to check how many files and directories are within are specified path. Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. @@ -29,7 +29,7 @@ Import-IcingaLib provider\users; .OUTPUTS System.String .LINK - https://github.com/LordHepipud/icinga-module-windows + https://github.com/Icinga/icinga-powershell-framework .NOTES #> From abfbac1448d868a0f28df510b68c596ad6b26742 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Thu, 31 Oct 2019 17:28:14 +0100 Subject: [PATCH 223/259] Fixes powershell services url due to renaming --- doc/10-InstallService.md | 4 ++-- lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/doc/10-InstallService.md b/doc/10-InstallService.md index 92a2214..7eff404 100644 --- a/doc/10-InstallService.md +++ b/doc/10-InstallService.md @@ -6,12 +6,12 @@ Requirements As PowerShell Scripts / Modules can not be installed directly as Windows Service, we will require a little assistance here. -In order to make this work, you will require the Icinga Windows Service which can be downloaded directly from the [GitHub Repository](https://github.com/Icinga/icinga-windows-service). +In order to make this work, you will require the Icinga Windows Service which can be downloaded directly from the [GitHub Repository](https://github.com/Icinga/icinga-powershell-service). Install the Service --- -At first you will require the Service Binary from the [Icinga Windows Service GitHub Repository](https://github.com/Icinga/icinga-windows-service) and copy the binary locally to your system. A recommended path would be your Program Files / Program Files (x86) directory. +At first you will require the Service Binary from the [Icinga Windows Service GitHub Repository](https://github.com/Icinga/icinga-powershell-service) and copy the binary locally to your system. A recommended path would be your Program Files / Program Files (x86) directory. Any other custom location is fully supported, has to be however accessable from the Windows Service Environment. diff --git a/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 b/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 index 18a12f7..415845d 100644 --- a/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 +++ b/lib/core/framework/Get-IcingaFrameworkServiceBinary.psm1 @@ -9,7 +9,7 @@ function Get-IcingaFrameworkServiceBinary() if ([string]::IsNullOrEmpty($FrameworkServiceUrl)) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you provide a custom source of the service binary?' -Default 'n').result -eq 1) { - $LatestRelease = (Invoke-WebRequest -Uri 'https://github.com/Icinga/icinga-windows-service/releases/latest' -UseBasicParsing).BaseResponse.ResponseUri.AbsoluteUri; + $LatestRelease = (Invoke-WebRequest -Uri 'https://github.com/Icinga/icinga-powershell-service/releases/latest' -UseBasicParsing).BaseResponse.ResponseUri.AbsoluteUri; $FrameworkServiceUrl = $LatestRelease.Replace('/tag/', '/download/'); $Tag = $FrameworkServiceUrl.Split('/')[-1]; $FrameworkServiceUrl = [string]::Format('{0}/icinga-service-{1}.zip', $FrameworkServiceUrl, $Tag); From 01b4ca19372d9c4628e8bb075c26246cfabb26fb Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 2 Nov 2019 12:12:26 +0100 Subject: [PATCH 224/259] Add function to fetch module root path --- icinga-powershell-framework.psd1 | 2 +- icinga-powershell-framework.psm1 | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/icinga-powershell-framework.psd1 b/icinga-powershell-framework.psd1 index 236f170..86f8eed 100644 --- a/icinga-powershell-framework.psd1 +++ b/icinga-powershell-framework.psd1 @@ -25,7 +25,7 @@ Description = 'Icinga 2 Windows Agent Module, which allows to entirely monitor t PowerShellVersion = '3.0' # Aus diesem Modul zu exportierende Funktionen. Um optimale Leistung zu erzielen, verwenden Sie keine Platzhalter und löschen den Eintrag nicht. Verwenden Sie ein leeres Array, wenn keine zu exportierenden Funktionen vorhanden sind. -FunctionsToExport = @( 'Use-Icinga', 'Import-IcingaLib', 'Publish-IcingaModuleManifests', 'Get-IcingaPluginDir', 'Get-IcingaCustomPluginDir', 'Get-IcingaCacheDir', 'Get-IcingaPowerShellConfigDir', 'Get-IcingaPowerShellModuleFile' ) +FunctionsToExport = @( 'Use-Icinga', 'Import-IcingaLib', 'Publish-IcingaModuleManifests', 'Get-IcingaPluginDir', 'Get-IcingaCustomPluginDir', 'Get-IcingaCacheDir', 'Get-IcingaPowerShellConfigDir', 'Get-IcingaFrameworkRootPath', 'Get-IcingaPowerShellModuleFile' ) # Aus diesem Modul zu exportierende Cmdlets. Um optimale Leistung zu erzielen, verwenden Sie keine Plat'zhalter und löschen den Eintrag nicht. Verwenden Sie ein leeres Array, wenn keine zu exportierenden Cmdlets vorhanden sind. CmdletsToExport = @() diff --git a/icinga-powershell-framework.psm1 b/icinga-powershell-framework.psm1 index 9cfdf0f..cb5181f 100644 --- a/icinga-powershell-framework.psm1 +++ b/icinga-powershell-framework.psm1 @@ -173,6 +173,14 @@ function Get-IcingaPowerShellConfigDir() return (Join-Path -Path $PSScriptRoot -ChildPath 'config'); } +function Get-IcingaFrameworkRootPath() +{ + [string]$Path = $PSScriptRoot; + [int]$Index = $Path.LastIndexOf('\') + 1; + $Path = $Path.Substring(0, $Index); + return $Path; +} + function Get-IcingaPowerShellModuleFile() { return (Join-Path -Path $PSScriptRoot -ChildPath 'icinga-powershell-framework.psm1'); From 8bce99e42a7c984fabd22fbf54ce58b95507955b Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 2 Nov 2019 12:15:25 +0100 Subject: [PATCH 225/259] Add function to update the module from CLI --- .../Install-IcingaFrameworkUpdate.psm1 | 88 +++++++++++++++++++ 1 file changed, 88 insertions(+) create mode 100644 lib/core/framework/Install-IcingaFrameworkUpdate.psm1 diff --git a/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 b/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 new file mode 100644 index 0000000..eb5867c --- /dev/null +++ b/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 @@ -0,0 +1,88 @@ +function Install-IcingaFrameworkUpdate() +{ + param( + [string]$FrameworkUrl + ); + + $ProgressPreference = "SilentlyContinue"; + + if ([string]::IsNullOrEmpty($FrameworkUrl)) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you provide a custom repository of the framework?' -Default 'n').result -eq 1) { + $branch = (Read-IcingaWizardAnswerInput -Prompt 'Which version to you want to install? (snapshot/stable)' -Default 'v' -DefaultInput 'stable').answer + if ($branch.ToLower() -eq 'snapshot') { + $FrameworkUrl = 'https://github.com/Icinga/icinga-powershell-framework/archive/master.zip'; + } else { + $LatestRelease = (Invoke-WebRequest -Uri 'https://github.com/Icinga/icinga-powershell-framework/releases/latest' -UseBasicParsing).BaseResponse.ResponseUri.AbsoluteUri; + $FrameworkUrl = $LatestRelease.Replace('/releases/tag/', '/archive/'); + $Tag = $FrameworkUrl.Split('/')[-1]; + $FrameworkUrl = [string]::Format('{0}/{1}.zip', $FrameworkUrl, $Tag); + } + } else { + $FrameworkUrl = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the full path to your icinga framework repository' -Default 'v').answer; + } + } + + $ModuleDirectory = Get-IcingaFrameworkRootPath; + $DownloadPath = (Join-Path -Path $ENv:TEMP -ChildPath 'icinga-powershell-framework-zip'); + Write-Host ([string]::Format('Downloading Icinga Framework into "{0}"', $DownloadPath)); + + Invoke-WebRequest -UseBasicParsing -Uri $FrameworkUrl -OutFile $DownloadPath; + + Write-Host ([string]::Format('Installing module into "{0}"', ($ModuleDirectory))); + Expand-IcingaZipArchive -Path $DownloadPath -Destination $ModuleDirectory | Out-Null; + + $FolderContent = Get-ChildItem -Path $ModuleDirectory; + $Extracted = ''; + + foreach ($entry in $FolderContent) { + if ($entry -eq 'icinga-powershell-framework') { + # Skip the framework directory directly + continue; + } + if ($entry -like 'icinga-powershell-framework-*') { + $Extracted = $entry; + } + } + + if ([string]::IsNullOrEmpty($Extracted)) { + Write-Host 'No update package could be found.' + return; + } + + $NewDirectory = (Join-Path -Path $ModuleDirectory -ChildPath 'icinga-powershell-framework'); + $ExtractDir = (Join-Path -Path $ModuleDirectory -ChildPath $Extracted); + $BackupDir = (Join-Path -Path $ExtractDir -ChildPath 'previous'); + $OldBackupDir = (Join-Path -Path $NewDirectory -ChildPath 'previous'); + + if ((Test-Path $NewDirectory)) { + if ((Test-Path (Join-Path -Path $NewDirectory -ChildPath 'cache'))) { + Write-Host 'Importing cache into new module version...'; + Copy-Item -Path (Join-Path -Path $NewDirectory -ChildPath 'cache') -Destination $ExtractDir -Force -Recurse; + } + if ((Test-Path (Join-Path -Path $NewDirectory -ChildPath 'custom'))) { + Write-Host 'Importing custom modules into new module version...'; + Copy-Item -Path (Join-Path -Path $NewDirectory -ChildPath 'custom') -Destination $ExtractDir -Force -Recurse; + } + Write-Host 'Creating backup directory'; + if ((Test-Path $OldBackupDir)) { + Write-Host 'Importing old backups into new module version...'; + Move-Item -Path $OldBackupDir -Destination $ExtractDir; + } else { + Write-Host 'No previous backups found. Creating new backup space'; + if ((Test-Path $BackupDir) -eq $FALSE) { + New-Item -Path $BackupDir -ItemType Container | Out-Null; + } + } + Write-Host 'Moving old module into backup directory'; + Move-Item -Path $NewDirectory -Destination (Join-Path -Path $BackupDir -ChildPath (Get-Date -Format "MM-dd-yyyy-HH-mm-ffff")); + } + + Write-Host 'Installing new module version'; + Move-Item -Path (Join-Path -Path $Destination -ChildPath $Extracted) -Destination $NewDirectory; + + Unblock-IcingaFramework -Path $NewDirectory; + + Test-IcingaAgent; + + Write-Host 'Framework update has been completed'; +} From a390d9262339d36b210d6d24b686583259d792c5 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 2 Nov 2019 12:33:01 +0100 Subject: [PATCH 226/259] Fixes CA endpoint by using the actual connection address --- lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index c6cd715..44f4d23 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -214,7 +214,7 @@ function Start-IcingaAgentInstallWizard() if ($CanConnectToParent) { if ([string]::IsNullOrEmpty($CAEndpoint)) { - $CAEndpoint = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the FQDN for either ONE of your Icinga parent node/nodes or your Icinga 2 CA master' -Default 'v' -DefaultInput $Endpoints[0]).answer; + $CAEndpoint = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the FQDN for either ONE of your Icinga parent node/nodes or your Icinga 2 CA master' -Default 'v' -DefaultInput (Get-IPConfigFromString $EndpointConnections[0]).address).answer; $InstallerArguments += "-CAEndpoint $CAEndpoint"; } if ($null -eq $Ticket) { From 0a9f24f66326b9f6e2177046e9ceb792c0ddd59f Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 2 Nov 2019 14:48:44 +0100 Subject: [PATCH 227/259] Add function to combine web Urls properly --- lib/core/tools/Join-WebPath.psm1 | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) create mode 100644 lib/core/tools/Join-WebPath.psm1 diff --git a/lib/core/tools/Join-WebPath.psm1 b/lib/core/tools/Join-WebPath.psm1 new file mode 100644 index 0000000..8a91545 --- /dev/null +++ b/lib/core/tools/Join-WebPath.psm1 @@ -0,0 +1,24 @@ +function Join-WebPath() +{ + param( + [string]$Path, + [string]$ChildPath + ); + + if ([string]::IsNullOrEmpty($Path) -Or [string]::IsNullOrEmpty($ChildPath)) { + return $Path; + } + + [int]$Length = $Path.Length; + [int]$Slash = $Path.LastIndexOf('/') + 1; + + if ($Length -eq $Slash) { + $Path = $Path.Substring(0, $Path.Length - 1); + } + + if ($ChildPath[0] -eq '/') { + return ([string]::Format('{0}{1}', $Path, $ChildPath)); + } + + return ([string]::Format('{0}/{1}', $Path, $ChildPath)); +} From 8a3c8c4102c2c9c9775ca340b04852a07fd738d8 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 2 Nov 2019 17:42:39 +0100 Subject: [PATCH 228/259] Add Director Self-Service setup wizard integration --- .../Get-IcingaDirectorSelfServiceConfig.psm1 | 2 +- .../Get-IcingaDirectorSelfServiceTicket.psm1 | 29 ++++ ...egister-IcingaDirectorSelfServiceHost.psm1 | 8 +- .../Install-IcingaFrameworkService.psm1 | 5 + ...rt-IcingaDirectorSelfServiceArguments.psm1 | 64 +++++++++ .../misc/Start-IcingaAgentDirectorWizard.psm1 | 127 ++++++++++++++++++ .../misc/Start-IcingaAgentInstallWizard.psm1 | 109 +++++++++++++-- 7 files changed, 332 insertions(+), 12 deletions(-) create mode 100644 lib/apis/Get-IcingaDirectorSelfServiceTicket.psm1 create mode 100644 lib/core/icingaagent/misc/Convert-IcingaDirectorSelfServiceArguments.psm1 create mode 100644 lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 diff --git a/lib/apis/Get-IcingaDirectorSelfServiceConfig.psm1 b/lib/apis/Get-IcingaDirectorSelfServiceConfig.psm1 index 7e48f9c..1d263b6 100644 --- a/lib/apis/Get-IcingaDirectorSelfServiceConfig.psm1 +++ b/lib/apis/Get-IcingaDirectorSelfServiceConfig.psm1 @@ -15,7 +15,7 @@ function Get-IcingaDirectorSelfServiceConfig() $ProgressPreference = "SilentlyContinue"; - $EndpointUrl = [string]::Format('{0}/self-service/powershell-parameters?key={1}', $DirectorUrl, $ApiKey); + $EndpointUrl = Join-WebPath -Path $DirectorUrl -ChildPath ([string]::Format('/self-service/powershell-parameters?key={0}', $ApiKey)); $response = Invoke-WebRequest -Uri $EndpointUrl -UseBasicParsing -Headers @{ 'accept' = 'application/json'; 'X-Director-Accept' = 'application/json' } -Method 'POST'; diff --git a/lib/apis/Get-IcingaDirectorSelfServiceTicket.psm1 b/lib/apis/Get-IcingaDirectorSelfServiceTicket.psm1 new file mode 100644 index 0000000..48fca58 --- /dev/null +++ b/lib/apis/Get-IcingaDirectorSelfServiceTicket.psm1 @@ -0,0 +1,29 @@ +function Get-IcingaDirectorSelfServiceTicket() +{ + param( + $DirectorUrl, + $ApiKey = $null + ); + + if ([string]::IsNullOrEmpty($DirectorUrl)) { + Write-Host 'Unable to fetch host ticket. No Director url has been specified'; + return; + } + + if ([string]::IsNullOrEmpty($ApiKey)) { + Write-Host 'Unable to fetch host ticket. No API key has been specified'; + return; + } + + [string]$url = Join-WebPath -Path $DirectorUrl -ChildPath ([string]::Format('/self-service/ticket?key={0}', $ApiKey)); + + $response = Invoke-WebRequest -Uri $url -UseBasicParsing -Headers @{ 'accept' = 'application/json'; 'X-Director-Accept' = 'application/json' } -Method 'POST'; + + if ($response.StatusCode -ne 200) { + throw $response.Content; + } + + $JsonContent = ConvertFrom-Json -InputObject $response.Content; + + return $JsonContent; +} diff --git a/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 b/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 index da2250d..13c6c67 100644 --- a/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 +++ b/lib/apis/Register-IcingaDirectorSelfServiceHost.psm1 @@ -20,7 +20,7 @@ function Register-IcingaDirectorSelfServiceHost() $ProgressPreference = "SilentlyContinue"; - $EndpointUrl = [string]::Format('{0}/self-service/register-host?name={1}&key={2}', $DirectorUrl, $Hostname, $ApiKey); + $EndpointUrl = Join-WebPath -Path $DirectorUrl -ChildPath ([string]::Format('/self-service/register-host?name={0}&key={1}', $Hostname, $ApiKey)); $response = Invoke-WebRequest -Uri $EndpointUrl -UseBasicParsing -Headers @{ 'accept' = 'application/json'; 'X-Director-Accept' = 'application/json' } -Method 'POST'; @@ -31,8 +31,14 @@ function Register-IcingaDirectorSelfServiceHost() $JsonContent = ConvertFrom-Json -InputObject $response.Content; if (Test-PSCustomObjectMember -PSObject $JsonContent -Name 'error') { + if ($JsonContent.error -like '*already been registered*') { + return $null; + } + throw 'Icinga Director Self-Service has thrown an error: ' + $JsonContent.error; } + Set-IcingaPowerShellConfig -Path 'IcingaDirector.SelfService.ApiKey' -Value $JsonContent; + return $JsonContent; } diff --git a/lib/core/framework/Install-IcingaFrameworkService.psm1 b/lib/core/framework/Install-IcingaFrameworkService.psm1 index 71abdb3..ebf4db2 100644 --- a/lib/core/framework/Install-IcingaFrameworkService.psm1 +++ b/lib/core/framework/Install-IcingaFrameworkService.psm1 @@ -6,6 +6,11 @@ function Install-IcingaFrameworkService() [SecureString]$Password ); + if ([string]::IsNullOrEmpty($Path)) { + Write-Host 'No path specified for Framework service. Service will not be installed'; + return; + } + if ((Test-Path $Path) -eq $FALSE) { throw 'Please specify the path directly to the service binary'; } diff --git a/lib/core/icingaagent/misc/Convert-IcingaDirectorSelfServiceArguments.psm1 b/lib/core/icingaagent/misc/Convert-IcingaDirectorSelfServiceArguments.psm1 new file mode 100644 index 0000000..156bc8d --- /dev/null +++ b/lib/core/icingaagent/misc/Convert-IcingaDirectorSelfServiceArguments.psm1 @@ -0,0 +1,64 @@ +function Convert-IcingaDirectorSelfServiceArguments() +{ + param( + $JsonInput + ); + + if ($null -eq $JsonInput) { + return @{}; + } + + [hashtable]$DirectorArguments = @{ + PackageSource = $JsonInput.download_url; + AgentVersion = $JsonInput.agent_version; + CAPort = $JsonInput.agent_listen_port; + AllowVersionChanges = $JsonInput.allow_updates; + GlobalZones = $JsonInput.global_zones; + ParentZone = $JsonInput.parent_zone; + CAEndpoint = $JsonInput.ca_server; + Endpoints = $JsonInput.parent_endpoints; + AddFirewallRule = $JsonInput.agent_add_firewall_rule; + AcceptConnections = $JsonInput.agent_add_firewall_rule; + #ServiceUser = $JsonInput.service_user; # This is yet missing within the Icinga Director API + ServiceUser = 'NT Authority\NetworkService'; + UpdateAgent = $TRUE; + AddDirectorGlobal = $FALSE; + AddGlobalTemplates = $FALSE; + RunInstaller = $TRUE; + }; + + if ($JsonInput.transform_hostname -eq 1) { + $DirectorArguments.Add( + 'LowerCase', $TRUE + ); + } + + if ($JsonInput.transform_hostname -eq 2) { + $DirectorArguments.Add( + 'UpperCase', $TRUE + ); + } + + if ($JsonInput.fetch_agent_fqdn) { + $DirectorArguments.Add( + 'AutoUseFQDN', $TRUE + ); + } elseif ($JsonInput.fetch_agent_name) { + $DirectorArguments.Add( + 'AutoUseHostname', $TRUE + ); + } + + $NetworkDefault = ''; + foreach ($Endpoint in $JsonInput.parent_endpoints) { + $NetworkDefault += [string]::Format('[{0}]:{1},', $Endpoint, $JsonInput.agent_listen_port); + } + if ([string]::IsNullOrEmpty($NetworkDefault) -eq $FALSE) { + $NetworkDefault = $NetworkDefault.Substring(0, $NetworkDefault.Length - 1); + $DirectorArguments.Add( + 'EndpointConnections', $NetworkDefault + ); + } + + return $DirectorArguments; +} diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 new file mode 100644 index 0000000..51f13cc --- /dev/null +++ b/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 @@ -0,0 +1,127 @@ +function Start-IcingaAgentDirectorWizard() +{ + param( + [string]$DirectorUrl, + [string]$SelfServiceAPIKey, + $OverrideDirectorVars = $null, + $InstallFrameworkService = $null, + $ServiceDirectory = $null, + $ServiceBin = $null, + [bool]$RunInstaller = $FALSE + ); + + if ([string]::IsNullOrEmpty($DirectorUrl)) { + $DirectorUrl = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the Url pointing to your Icinga Director' -Default 'v').answer; + } + + [bool]$HostKnown = $FALSE; + [string]$TemplateKey = $SelfServiceAPIKey; + + if ($null -eq $OverrideDirectorVars) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to manually override arguments provided by the Director API?' -Default 'n').result -eq 0) { + $OverrideDirectorVars = $TRUE; + } else{ + $OverrideDirectorVars = $FALSE; + } + } + + $SelfServiceAPIKey = Get-IcingaPowerShellConfig -Path 'IcingaDirector.SelfService.ApiKey'; + if ([string]::IsNullOrEmpty($SelfServiceAPIKey)) { + $LegacyTokenPath = Join-Path -Path Get-IcingaAgentConfigDirectory -ChildPath 'icingadirector.token'; + if (Test-Path $LegacyTokenPath) { + $SelfServiceAPIKey = Get-Content -Path $LegacyTokenPath; + Set-IcingaPowerShellConfig -Path 'IcingaDirector.SelfService.ApiKey' -Value $SelfServiceAPIKey; + } + } + + if ([string]::IsNullOrEmpty($SelfServiceAPIKey)) { + $SelfServiceAPIKey = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter your Self-Service API key' -Default 'v').answer; + } else { + $HostKnown = $TRUE; + } + + $Arguments = Get-IcingaDirectorSelfServiceConfig -DirectorUrl $DirectorUrl -ApiKey $SelfServiceAPIKey; + $Arguments = Convert-IcingaDirectorSelfServiceArguments -JsonInput $Arguments; + + if ($OverrideDirectorVars -eq $TRUE) { + $NewArguments = Start-IcingaDirectorAPIArgumentOverride -Arguments $Arguments; + $Arguments = $NewArguments; + } + + if ($HostKnown -eq $FALSE) { + Write-Host $SelfServiceAPIKey; + Write-Host (Get-IcingaHostname @Arguments); + Write-Host $DirectorUrl; + $SelfServiceAPIKey = Register-IcingaDirectorSelfServiceHost -DirectorUrl $DirectorUrl -ApiKey $SelfServiceAPIKey -Hostname (Get-IcingaHostname @Arguments); + + # Host is already registered + if ($null -eq $SelfServiceAPIKey) { + Write-Host 'The wizard is unable to complete as this host is already registered but the local API key is not stored within the config' + return; + } + + $Arguments = Get-IcingaDirectorSelfServiceConfig -DirectorUrl $DirectorUrl -ApiKey $SelfServiceAPIKey; + $Arguments = Convert-IcingaDirectorSelfServiceArguments -JsonInput $Arguments; + if ($OverrideDirectorVars -eq $TRUE) { + $NewArguments = Start-IcingaDirectorAPIArgumentOverride -Arguments $Arguments; + $Arguments = $NewArguments; + } + } + + $Arguments.Add( + 'UseDirectorSelfService', $TRUE + ); + $Arguments.Add( + 'OverrideDirectorVars', $FALSE + ); + $Arguments.Add( + 'DirectorUrl', $DirectorUrl + ); + $Arguments.Add( + 'SelfServiceAPIKey', $TemplateKey + ); + $Arguments.Add( + 'SkipDirectorQuestion', $TRUE + ); + $Arguments.Add( + 'InstallFrameworkService', $InstallFrameworkService + ); + $Arguments.Add( + 'ServiceDirectory', $ServiceDirectory + ); + $Arguments.Add( + 'ServiceBin', $ServiceBin + ); + $Arguments.Add( + 'ProvidedArgs', $Arguments + ); + + if ($RunInstaller) { + Start-IcingaAgentInstallWizard @Arguments; + return; + } + + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'The Director wizard is complete. Do you want to start the installation now?' -Default 'y').result -eq 1) { + Start-IcingaAgentInstallWizard @Arguments; + } +} + +function Start-IcingaDirectorAPIArgumentOverride() +{ + param( + $Arguments + ); + + $NewArguments = @{}; + Write-Host 'Please follow the wizard and manually override all entries you intend to'; + Write-Host '===='; + + foreach ($entry in $Arguments.Keys) { + $value = (Get-IcingaAgentInstallerAnswerInput -Prompt ([string]::Format('Please enter the new value for the argument "{0}"', $entry)) -Default 'v' -DefaultInput $Arguments[$entry]).answer; + $NewArguments.Add($entry, $value); + } + + return $NewArguments; +} + +Export-ModuleMember -Function @( 'Start-IcingaAgentDirectorWizard' ); diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index 44f4d23..4a8b926 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -28,12 +28,41 @@ function Start-IcingaAgentInstallWizard() $InstallFrameworkService = $null, $FrameworkServiceUrl = $null, $ServiceDirectory = $null, - $ServiceBin = $null + $ServiceBin = $null, + $UseDirectorSelfService = $null, + [bool]$SkipDirectorQuestion = $FALSE, + [string]$DirectorUrl, + [string]$SelfServiceAPIKey, + $OverrideDirectorVars = $null, + [hashtable]$ProvidedArgs = @{} ); [array]$InstallerArguments = @(); [array]$GlobalZoneConfig = @(); + if ($SkipDirectorQuestion -eq $FALSE) { + if ($null -eq $UseDirectorSelfService) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to use the Icinga Director Self-Service API?' -Default 'y').result -eq 1) { + $UseDirectorSelfService = $TRUE; + } else { + $UseDirectorSelfService = $FALSE; + $InstallerArguments += '-UseDirectorSelfService 0'; + } + } + if ($UseDirectorSelfService) { + $InstallerArguments += '-UseDirectorSelfService 1'; + Start-IcingaAgentDirectorWizard ` + -DirectorUrl $DirectorUrl ` + -SelfServiceAPIKey $SelfServiceAPIKey ` + -OverrideDirectorVars $OverrideDirectorVars ` + -InstallFrameworkService $InstallFrameworkService ` + -ServiceDirectory $ServiceDirectory ` + -ServiceBin $ServiceBin ` + -RunInstaller $RunInstaller; + return; + } + } + if ([string]::IsNullOrEmpty($Hostname) -And $AutoUseFQDN -eq $FALSE -And $AutoUseHostname -eq $FALSE) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to manually specify a hostname?' -Default 'n').result -eq 1) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to automatically fetch the hostname with its FQDN?' -Default 'y').result -eq 1) { @@ -261,27 +290,87 @@ function Start-IcingaAgentInstallWizard() $InstallerArguments += [string]::Format("-ServiceDirectory '{0}'", $result.ServiceDirectory); $InstallerArguments += [string]::Format("-ServiceBin '{0}'", $result.ServiceBin); $ServiceBin = $result.ServiceBin; + } else { + $InstallerArguments += "-InstallFrameworkService 0"; } } elseif ($InstallFrameworkService -eq $TRUE) { $result = Get-IcingaFrameworkServiceBinary -FrameworkServiceUrl $FrameworkServiceUrl -ServiceDirectory $ServiceDirectory; $ServiceBin = $result.ServiceBin; + } else { + $InstallerArguments += "-InstallFrameworkService 0"; } if ($InstallerArguments.Count -ne 0) { $InstallerArguments += "-RunInstaller"; Write-Host 'The wizard is complete. These are the configured settings:'; + + foreach ($entry in $ProvidedArgs.Keys) { + if ($entry -eq 'ProvidedArgs' -Or $entry -eq 'SkipDirectorQuestion') { + continue; + } + + [bool]$SkipArgument = $FALSE; + + if ($OverrideDirectorVars -eq $FALSE) { + switch ($entry) { + 'InstallFrameworkService' { break; }; + 'FrameworkServiceUrl' { break; }; + 'ServiceDirectory' { break; }; + 'ServiceBin' { break; }; + 'UseDirectorSelfService' { break; }; + 'DirectorUrl' { break; }; + 'SelfServiceAPIKey' { break; }; + 'OverrideDirectorVars' { break; }; + Default { + $SkipArgument = $TRUE; + break; + } + } + + if ($SkipArgument) { + continue; + } + } + + [bool]$KnownArgument = $FALSE; + foreach ($item in $InstallerArguments) { + if ($item -like "-$entry *" -Or $item -eq "-$entry") { + $KnownArgument = $TRUE; + break; + } + } + + if ($KnownArgument) { + continue; + } + + $Value = $ProvidedArgs[$entry]; + if ($Value -is [System.Object]) { + $Value = [string]::Join(',', $Value); + } + + if ($OverrideDirectorVars -eq $FALSE) { + #$ClearedArguments += [string]::Format("-{0} '{1}'", $entry, $Value); + #continue; + } + + $InstallerArguments += [string]::Format("-{0} '{1}'", $entry, $Value); + } + Write-Host ($InstallerArguments | Out-String); - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Is this configuration correct?' -Default 'y').result -eq 1) { - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to run the installer now? (Otherwise only the configration command will be printed)' -Default 'y').result -eq 1) { - Write-Host 'To execute your Icinga Agent installation based on your answers again on this or another machine, simply run this command:' + if (-Not $RunInstaller) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Is this configuration correct?' -Default 'y').result -eq 1) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to run the installer now? (Otherwise only the configration command will be printed)' -Default 'y').result -eq 1) { + Write-Host 'To execute your Icinga Agent installation based on your answers again on this or another machine, simply run this command:' - $RunInstaller = $TRUE; + $RunInstaller = $TRUE; + } else { + Write-Host 'To execute your Icinga Agent installation based on your answers, simply run this command:' + } } else { - Write-Host 'To execute your Icinga Agent installation based on your answers, simply run this command:' + Write-Host 'Please run the wizard again to modify your answers or modify the command below:' } - } else { - Write-Host 'Please run the wizard again to modify your answers or modify the command below:' } Get-IcingaAgentInstallCommand -InstallerArguments $InstallerArguments -PrintConsole; } @@ -289,8 +378,8 @@ function Start-IcingaAgentInstallWizard() if ($RunInstaller) { if ((Install-IcingaAgent -Version $AgentVersion -Source $PackageSource -AllowUpdates $AllowVersionChanges) -Or $Reconfigure) { Move-IcingaAgentDefaultConfig; - Set-IcingaAgentServiceUser -User $ServiceUser -Password $ServicePass; - Set-IcingaAgentServicePermission; + Set-IcingaAgentServiceUser -User $ServiceUser -Password $ServicePass | Out-Null; + Set-IcingaAgentServicePermission | Out-Null; Set-IcingaAcl "$Env:ProgramData\icinga2\etc"; Set-IcingaAcl "$Env:ProgramData\icinga2\var"; Set-IcingaAcl (Get-IcingaCacheDir); From cdd1cf8189b9b4d114da1e817cec2850258aa2ff Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 2 Nov 2019 17:42:56 +0100 Subject: [PATCH 229/259] Add output for service restart message --- lib/core/framework/Restart-IcingaService.psm1 | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/core/framework/Restart-IcingaService.psm1 b/lib/core/framework/Restart-IcingaService.psm1 index ce0f009..4fc26e7 100644 --- a/lib/core/framework/Restart-IcingaService.psm1 +++ b/lib/core/framework/Restart-IcingaService.psm1 @@ -5,6 +5,7 @@ function Restart-IcingaService() ); if (Get-Service $Service -ErrorAction SilentlyContinue) { + Write-Host ([string]::Format('Restarting service "{0}"', $Service)); Restart-Service $Service; } } From 6e5b0ee218d2e941b409494a7748d69bd6117236 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sat, 2 Nov 2019 17:43:19 +0100 Subject: [PATCH 230/259] Fixes Url building for Agent download --- lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 b/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 index f4b9ed5..5a48b7d 100644 --- a/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 +++ b/lib/core/icingaagent/getters/Get-IcingaAgentMSIPackage.psm1 @@ -62,7 +62,7 @@ function Get-IcingaAgentMSIPackage() if ($SkipDownload -eq $FALSE) { $DownloadPath = Join-Path $Env:TEMP -ChildPath $UsePackage; Write-Host ([string]::Format('Downloading Icinga 2 Agent installer "{0}" into temp directory "{1}"', $UsePackage, $DownloadPath)); - Invoke-WebRequest -Uri ([string]::Format('{0}/{1}', $Source, $UsePackage)) -OutFile $DownloadPath; + Invoke-WebRequest -Uri (Join-WebPath -Path $Source -ChildPath $UsePackage) -OutFile $DownloadPath; } return @{ From 89e8045870f98c4f8db9d0ac8a8ac8812eff3c08 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 09:46:27 +0100 Subject: [PATCH 231/259] Improves setup wizard usability and fixes Director overriding --- .../misc/Start-IcingaAgentDirectorWizard.psm1 | 94 +++---- .../misc/Start-IcingaAgentInstallWizard.psm1 | 251 ++++++++++++------ 2 files changed, 221 insertions(+), 124 deletions(-) diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 index 51f13cc..b8ad7a2 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 @@ -2,22 +2,20 @@ function Start-IcingaAgentDirectorWizard() { param( [string]$DirectorUrl, - [string]$SelfServiceAPIKey, + [string]$SelfServiceAPIKey = $null, $OverrideDirectorVars = $null, - $InstallFrameworkService = $null, - $ServiceDirectory = $null, - $ServiceBin = $null, [bool]$RunInstaller = $FALSE ); + [hashtable]$DirectorOverrideArgs = @{} if ([string]::IsNullOrEmpty($DirectorUrl)) { $DirectorUrl = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the Url pointing to your Icinga Director' -Default 'v').answer; } - [bool]$HostKnown = $FALSE; + [bool]$HostKnown = $FALSE; [string]$TemplateKey = $SelfServiceAPIKey; - if ($null -eq $OverrideDirectorVars) { + if ($null -eq $OverrideDirectorVars -And $RunInstaller -eq $FALSE) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to manually override arguments provided by the Director API?' -Default 'n').result -eq 0) { $OverrideDirectorVars = $TRUE; } else{ @@ -43,9 +41,13 @@ function Start-IcingaAgentDirectorWizard() $Arguments = Get-IcingaDirectorSelfServiceConfig -DirectorUrl $DirectorUrl -ApiKey $SelfServiceAPIKey; $Arguments = Convert-IcingaDirectorSelfServiceArguments -JsonInput $Arguments; - if ($OverrideDirectorVars -eq $TRUE) { - $NewArguments = Start-IcingaDirectorAPIArgumentOverride -Arguments $Arguments; - $Arguments = $NewArguments; + if ($OverrideDirectorVars -eq $TRUE -And -Not $RunInstaller) { + $DirectorOverrideArgs = Start-IcingaDirectorAPIArgumentOverride -Arguments $Arguments; + foreach ($entry in $DirectorOverrideArgs.Keys) { + if ($Arguments.ContainsKey($entry)) { + $Arguments[$entry] = $DirectorOverrideArgs[$entry]; + } + } } if ($HostKnown -eq $FALSE) { @@ -62,48 +64,29 @@ function Start-IcingaAgentDirectorWizard() $Arguments = Get-IcingaDirectorSelfServiceConfig -DirectorUrl $DirectorUrl -ApiKey $SelfServiceAPIKey; $Arguments = Convert-IcingaDirectorSelfServiceArguments -JsonInput $Arguments; - if ($OverrideDirectorVars -eq $TRUE) { - $NewArguments = Start-IcingaDirectorAPIArgumentOverride -Arguments $Arguments; - $Arguments = $NewArguments; + if ($OverrideDirectorVars -eq $TRUE -And -Not $RunInstaller) { + $DirectorOverrideArgs = Start-IcingaDirectorAPIArgumentOverride -Arguments $Arguments; + foreach ($entry in $DirectorOverrideArgs.Keys) { + if ($Arguments.ContainsKey($entry)) { + $Arguments[$entry] = $DirectorOverrideArgs[$entry]; + } + } } } - $Arguments.Add( - 'UseDirectorSelfService', $TRUE - ); - $Arguments.Add( - 'OverrideDirectorVars', $FALSE - ); - $Arguments.Add( + $DirectorOverrideArgs.Add( 'DirectorUrl', $DirectorUrl ); - $Arguments.Add( - 'SelfServiceAPIKey', $TemplateKey - ); - $Arguments.Add( - 'SkipDirectorQuestion', $TRUE - ); - $Arguments.Add( - 'InstallFrameworkService', $InstallFrameworkService - ); - $Arguments.Add( - 'ServiceDirectory', $ServiceDirectory - ); - $Arguments.Add( - 'ServiceBin', $ServiceBin - ); - $Arguments.Add( - 'ProvidedArgs', $Arguments - ); - - if ($RunInstaller) { - Start-IcingaAgentInstallWizard @Arguments; - return; + if ([string]::IsNullOrEmpty($TemplateKey) -eq $FALSE) { + $DirectorOverrideArgs.Add( + 'SelfServiceAPIKey', $TemplateKey + ); } - if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'The Director wizard is complete. Do you want to start the installation now?' -Default 'y').result -eq 1) { - Start-IcingaAgentInstallWizard @Arguments; - } + return @{ + 'Arguments' = $Arguments; + 'Overrides' = $DirectorOverrideArgs; + }; } function Start-IcingaDirectorAPIArgumentOverride() @@ -118,7 +101,28 @@ function Start-IcingaDirectorAPIArgumentOverride() foreach ($entry in $Arguments.Keys) { $value = (Get-IcingaAgentInstallerAnswerInput -Prompt ([string]::Format('Please enter the new value for the argument "{0}"', $entry)) -Default 'v' -DefaultInput $Arguments[$entry]).answer; - $NewArguments.Add($entry, $value); + if ($Arguments[$entry] -is [array]) { + if ([string]::IsNullOrEmpty($value) -eq $FALSE) { + [array]$tmpArray = $value.Split(','); + if ($null -ne (Compare-Object -ReferenceObject $Arguments[$entry] -DifferenceObject $tmpArray)) { + $NewArguments.Add( + $entry, + ([string]::Join(',', $tmpArray)) + ); + } + } + continue; + } elseif ($Arguments[$entry] -is [bool]) { + if ($value -eq 'true' -or $value -eq 'y' -or $value -eq '1' -or $value -eq 'yes' -or $value -eq 1) { + $value = 1; + } else { + $value = 0; + } + } + + if ($Arguments[$entry] -ne $value) { + $NewArguments.Add($entry, $value); + } } return $NewArguments; diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index 4a8b926..1cd10ae 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -2,15 +2,15 @@ function Start-IcingaAgentInstallWizard() { param( [string]$Hostname, - [switch]$AutoUseFQDN = $FALSE, - [switch]$AutoUseHostname = $FALSE, - [switch]$LowerCase = $FALSE, - [switch]$UpperCase = $FALSE, + $AutoUseFQDN, + $AutoUseHostname, + $LowerCase, + $UpperCase, $AddDirectorGlobal = $null, $AddGlobalTemplates = $null, [string]$PackageSource, [string]$AgentVersion, - [switch]$AllowVersionChanges = $FALSE, + $AllowVersionChanges, $UpdateAgent = $null, $AcceptConnections = $null, [array]$Endpoints = @(), @@ -20,7 +20,8 @@ function Start-IcingaAgentInstallWizard() [string]$CAEndpoint, $CAPort = $null, [string]$Ticket, - [string]$CAFile, + [string]$CAFile = $null, + $EmptyCA = $null, [switch]$RunInstaller, [switch]$Reconfigure, [string]$ServiceUser, @@ -32,9 +33,8 @@ function Start-IcingaAgentInstallWizard() $UseDirectorSelfService = $null, [bool]$SkipDirectorQuestion = $FALSE, [string]$DirectorUrl, - [string]$SelfServiceAPIKey, - $OverrideDirectorVars = $null, - [hashtable]$ProvidedArgs = @{} + [string]$SelfServiceAPIKey = $null, + $OverrideDirectorVars = $null ); [array]$InstallerArguments = @(); @@ -50,34 +50,98 @@ function Start-IcingaAgentInstallWizard() } } if ($UseDirectorSelfService) { + $InstallerArguments += '-UseDirectorSelfService 1'; - Start-IcingaAgentDirectorWizard ` + $DirectorArgs = Start-IcingaAgentDirectorWizard ` -DirectorUrl $DirectorUrl ` -SelfServiceAPIKey $SelfServiceAPIKey ` -OverrideDirectorVars $OverrideDirectorVars ` - -InstallFrameworkService $InstallFrameworkService ` - -ServiceDirectory $ServiceDirectory ` - -ServiceBin $ServiceBin ` -RunInstaller $RunInstaller; - return; + + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'DirectorUrl' -Value $DirectorUrl -InstallerArguments $InstallerArguments; + $DirectorUrl = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'SelfServiceAPIKey' -Value $SelfServiceAPIKey -InstallerArguments $InstallerArguments -Default $null; + if ([string]::IsNullOrEmpty($Result.Value) -eq $FALSE) { + Write-Host 'Setting self service arg' + $SelfServiceAPIKey = $Result.Value; + $InstallerArguments = $Result.Args; + } + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'PackageSource' -Value $PackageSource -InstallerArguments $InstallerArguments; + $PackageSource = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AgentVersion' -Value $AgentVersion -InstallerArguments $InstallerArguments; + $AgentVersion = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'CAPort' -Value $CAPort -InstallerArguments $InstallerArguments; + $CAPort = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AllowVersionChanges' -Value $AllowVersionChanges -InstallerArguments $InstallerArguments; + $AllowVersionChanges = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'GlobalZones' -Value $GlobalZones -InstallerArguments $InstallerArguments; + $GlobalZones = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'ParentZone' -Value $ParentZone -InstallerArguments $InstallerArguments; + $ParentZone = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'CAEndpoint' -Value $CAEndpoint -InstallerArguments $InstallerArguments; + $CAEndpoint = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'Endpoints' -Value $Endpoints -InstallerArguments $InstallerArguments; + $Endpoints = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AddFirewallRule' -Value $AddFirewallRule -InstallerArguments $InstallerArguments; + $AddFirewallRule = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AcceptConnections' -Value $AcceptConnections -InstallerArguments $InstallerArguments; + $AcceptConnections = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'ServiceUser' -Value $ServiceUser -InstallerArguments $InstallerArguments; + $ServiceUser = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'UpdateAgent' -Value $UpdateAgent -InstallerArguments $InstallerArguments; + $UpdateAgent = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AddDirectorGlobal' -Value $AddDirectorGlobal -InstallerArguments $InstallerArguments; + $AddDirectorGlobal = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AddGlobalTemplates' -Value $AddGlobalTemplates -InstallerArguments $InstallerArguments; + $AddGlobalTemplates = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'LowerCase' -Value $LowerCase -Default $FALSE -InstallerArguments $InstallerArguments; + $LowerCase = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'UpperCase' -Value $UpperCase -Default $FALSE -InstallerArguments $InstallerArguments; + $UpperCase = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AutoUseFQDN' -Value $AutoUseFQDN -Default $FALSE -InstallerArguments $InstallerArguments; + $AutoUseFQDN = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AutoUseHostname' -Value $AutoUseHostname -Default $FALSE -InstallerArguments $InstallerArguments; + $AutoUseHostname = $Result.Value; + $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'EndpointConnections' -Value $EndpointConnections -InstallerArguments $InstallerArguments; + $EndpointConnections = $Result.Value; + $InstallerArguments = $Result.Args; } } if ([string]::IsNullOrEmpty($Hostname) -And $AutoUseFQDN -eq $FALSE -And $AutoUseHostname -eq $FALSE) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to manually specify a hostname?' -Default 'n').result -eq 1) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to automatically fetch the hostname with its FQDN?' -Default 'y').result -eq 1) { - $InstallerArguments += '-AutoUseFQDN'; + $InstallerArguments += '-AutoUseFQDN 1'; $AutoUseFQDN = $TRUE; } else { - $InstallerArguments += '-AutoUseHostname'; + $InstallerArguments += '-AutoUseHostname 1'; $AutoUseHostname = $TRUE; } if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to modify the hostname to only include lower case characters?' -Default 'y').result -eq 1) { - $InstallerArguments += '-LowerCase'; + $InstallerArguments += '-LowerCase 1'; $LowerCase = $TRUE; } else { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to modify the hostname to only include upper case characters?' -Default 'n').result -eq 0) { - $InstallerArguments += '-UpperCase'; + $InstallerArguments += '-UpperCase 1'; $UpperCase = $TRUE; } } @@ -130,7 +194,7 @@ function Start-IcingaAgentInstallWizard() $AgentVersion = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please specify the version you wish to install ("latest", "snapshot", or a version like "2.11.0")' -Default 'v').answer; $AllowVersionChanges = $TRUE; $InstallerArguments += "-AgentVersion '$AgentVersion'"; - $InstallerArguments += '-AllowVersionChanges'; + $InstallerArguments += '-AllowVersionChanges 1'; Write-Host ([string]::Format('Updating/Downgrading Icinga 2 Agent to version: "{0}"', $AgentVersion)); } @@ -194,12 +258,13 @@ function Start-IcingaAgentInstallWizard() if ($null -eq $AddDirectorGlobal) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to add the global zone "director-global"?' -Default 'y').result -eq 1) { $AddDirectorGlobal = $TRUE; + $InstallerArguments += ("-AddDirectorGlobal 1"); } else { $AddDirectorGlobal = $FALSE; + $InstallerArguments += ("-AddDirectorGlobal 0"); } } - $InstallerArguments += ("-AddDirectorGlobal $AddDirectorGlobal"); if ($AddDirectorGlobal) { $GlobalZoneConfig += 'director-global'; } @@ -207,12 +272,13 @@ function Start-IcingaAgentInstallWizard() if ($null -eq $AddGlobalTemplates) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to add the global zone "global-templates"?' -Default 'y').result -eq 1) { $AddGlobalTemplates = $TRUE; + $InstallerArguments += ("-AddGlobalTemplates 1"); } else { $AddGlobalTemplates = $FALSE; + $InstallerArguments += ("-AddGlobalTemplates 0"); } } - $InstallerArguments += ("-AddGlobalTemplates $AddGlobalTemplates"); if ($AddGlobalTemplates) { $GlobalZoneConfig += 'global-templates'; } @@ -233,12 +299,16 @@ function Start-IcingaAgentInstallWizard() [bool]$CanConnectToParent = $FALSE; - if ($AcceptConnections -eq 0) { + if ($null -eq $AcceptConnections) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Is this Agent able to connect to its parent node for certificate generation?' -Default 'y').result -eq 1) { $CanConnectToParent = $TRUE; + $InstallerArguments += ("-AcceptConnections 1"); + } else { + $InstallerArguments += ("-AcceptConnections 0"); } - } else { + } elseif ($AcceptConnections) { $CanConnectToParent = $TRUE; + $InstallerArguments += ("-AcceptConnections 1"); } if ($CanConnectToParent) { @@ -255,11 +325,22 @@ function Start-IcingaAgentInstallWizard() } } } else { - if ([string]::IsNullOrEmpty($CAFile)) { + if ([string]::IsNullOrEmpty($CAFile) -And $null -eq $EmptyCA) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Is your public Icinga 2 CA (ca.crt) available on a local, network or web share?' -Default 'y').result -eq 1) { $CAFile = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please provide the full path to your ca.crt file' -Default 'v').answer; $InstallerArguments += "-CAFile $CAFile"; + $InstallerArguments += "-EmptyCA 0"; + } else { + $InstallerArguments += "-CAFile ''"; + $InstallerArguments += "-EmptyCA 1" } + } else { + if ([string]::IsNullOrEmpty($CAFile)) { + $InstallerArguments += "-CAFile ''"; + } else { + $InstallerArguments += "-CAFile $CAFile"; + } + $InstallerArguments += "-EmptyCA $EmptyCA" } } @@ -304,60 +385,9 @@ function Start-IcingaAgentInstallWizard() $InstallerArguments += "-RunInstaller"; Write-Host 'The wizard is complete. These are the configured settings:'; - foreach ($entry in $ProvidedArgs.Keys) { - if ($entry -eq 'ProvidedArgs' -Or $entry -eq 'SkipDirectorQuestion') { - continue; - } - - [bool]$SkipArgument = $FALSE; - - if ($OverrideDirectorVars -eq $FALSE) { - switch ($entry) { - 'InstallFrameworkService' { break; }; - 'FrameworkServiceUrl' { break; }; - 'ServiceDirectory' { break; }; - 'ServiceBin' { break; }; - 'UseDirectorSelfService' { break; }; - 'DirectorUrl' { break; }; - 'SelfServiceAPIKey' { break; }; - 'OverrideDirectorVars' { break; }; - Default { - $SkipArgument = $TRUE; - break; - } - } - - if ($SkipArgument) { - continue; - } - } - - [bool]$KnownArgument = $FALSE; - foreach ($item in $InstallerArguments) { - if ($item -like "-$entry *" -Or $item -eq "-$entry") { - $KnownArgument = $TRUE; - break; - } - } - - if ($KnownArgument) { - continue; - } - - $Value = $ProvidedArgs[$entry]; - if ($Value -is [System.Object]) { - $Value = [string]::Join(',', $Value); - } - - if ($OverrideDirectorVars -eq $FALSE) { - #$ClearedArguments += [string]::Format("-{0} '{1}'", $entry, $Value); - #continue; - } - - $InstallerArguments += [string]::Format("-{0} '{1}'", $entry, $Value); - } - + Write-Host '========' Write-Host ($InstallerArguments | Out-String); + Write-Host '========' if (-Not $RunInstaller) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Is this configuration correct?' -Default 'y').result -eq 1) { @@ -396,6 +426,69 @@ function Start-IcingaAgentInstallWizard() } } +function Set-IcingaWizardArgument() +{ + param( + [hashtable]$DirectorArgs, + [string]$WizardArg, + $Value, + $Default = $null, + $InstallerArguments + ); + + if ($DirectorArgs.Overrides.ContainsKey($WizardArg)) { + $Override = $DirectorArgs.Overrides[$WizardArg]; + if ($Value -is [array]) { + $Override = [string]::Join(',', $Override); + } + $InstallerArguments += "-$WizardArg $Override"; + return @{ + 'Value' = $Override; + 'Args' = $InstallerArguments; + }; + } + + $RetValue = $null; + + if ($DirectorArgs.Arguments.ContainsKey($WizardArg)) { + $RetValue = $DirectorArgs.Arguments[$WizardArg]; + if ($Value -is [array]) { + $RetValue = [string]::Join(',', $RetValue); + } + } else { + if ($null -ne $Value -Or [string]::IsNullOrEmpty($Value) -eq $FALSE) { + if ($Value -is [array]) { + $Value = [string]::Join(',', $Value); + } + $InstallerArguments += "-$WizardArg $Value"; + return @{ + 'Value' = $Value; + 'Args' = $InstallerArguments; + }; + } else { + return @{ + 'Value' = $Default; + 'Args' = $InstallerArguments; + }; + } + } + + if ([string]::IsNullOrEmpty($Value) -eq $FALSE) { + if ($Value -is [array]) { + $Value = [string]::Join(',', $Value); + } + $InstallerArguments += "-$WizardArg $Value"; + return @{ + 'Value' = $Value; + 'Args' = $InstallerArguments; + }; + } + + return @{ + 'Value' = $RetValue; + 'Args' = $InstallerArguments; + }; +} function Get-IcingaAgentInstallCommand() { param( @@ -411,9 +504,9 @@ function Get-IcingaAgentInstallCommand() ); if ($PrintConsole) { - Write-Host '####' + Write-Host '====' Write-Host $Installer -ForegroundColor ([System.ConsoleColor]::Cyan); - Write-Host '####' + Write-Host '====' } else { return $Installer; } From 00417e93920e3aca295221bbbbd3da42d9c5e87d Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 11:56:55 +0100 Subject: [PATCH 232/259] Improves check output --- lib/icinga/plugin/New-IcingaCheck.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/icinga/plugin/New-IcingaCheck.psm1 b/lib/icinga/plugin/New-IcingaCheck.psm1 index 3c7ee48..780915d 100644 --- a/lib/icinga/plugin/New-IcingaCheck.psm1 +++ b/lib/icinga/plugin/New-IcingaCheck.psm1 @@ -494,7 +494,7 @@ function New-IcingaCheck() $this.SetExitCode($state); $this.AddMessage( [string]::Format( - '{0} {1}{4} is {2} {3}{4}', + '{0}: Value "{1}{4}" is {2} threshold "{3}{4}"', $this.name, $this.TranslateValue($this.value), $type, @@ -670,7 +670,7 @@ function New-IcingaCheck() $this.exitcode = $IcingaEnums.IcingaExitCode.Ok; $this.AddMessage( [string]::Format( - '{0} is {1}{2}', + '{0}: {1}{2}', $this.name, $this.TranslateValue($this.value), $this.unit From d314c71628ccaf6c35fbe7d4ac19574b0570d049 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 11:57:47 +0100 Subject: [PATCH 233/259] Fixes check translation by converting non-numeric to string --- lib/icinga/plugin/New-IcingaCheck.psm1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/icinga/plugin/New-IcingaCheck.psm1 b/lib/icinga/plugin/New-IcingaCheck.psm1 index 780915d..89d8bf7 100644 --- a/lib/icinga/plugin/New-IcingaCheck.psm1 +++ b/lib/icinga/plugin/New-IcingaCheck.psm1 @@ -471,6 +471,8 @@ function New-IcingaCheck() if ((Test-Numeric $checkValue)) { $checkValue = [int]$checkValue; + } else { + $checkValue = [string]$checkValue; } if ($this.translation.ContainsKey($checkValue)) { From a23fbd2d1f1b8f7782290728887b4db8fcac0279 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 11:58:22 +0100 Subject: [PATCH 234/259] Removes plugins from framework --- lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 | 27 - lib/plugins/Invoke-IcingaCheckCPU.psm1 | 66 --- lib/plugins/Invoke-IcingaCheckCheckSum.psm1 | 65 --- lib/plugins/Invoke-IcingaCheckDirectory.psm1 | 115 ---- lib/plugins/Invoke-IcingaCheckEventlog.psm1 | 122 ---- lib/plugins/Invoke-IcingaCheckFirewall.psm1 | 73 --- lib/plugins/Invoke-IcingaCheckMemory.psm1 | 113 ---- .../Invoke-IcingaCheckPerfcounter.psm1 | 70 --- .../Invoke-IcingaCheckProcessCount.psm1 | 71 --- lib/plugins/Invoke-IcingaCheckService.psm1 | 92 --- lib/plugins/Invoke-IcingaCheckUpdates.psm1 | 87 --- lib/plugins/Invoke-IcingaCheckUptime.psm1 | 57 -- .../Invoke-IcingaCheckUsedPartitionSpace.psm1 | 82 --- lib/plugins/Invoke-IcingaCheckUsers.psm1 | 75 --- lib/provider/bios/Icinga_ProviderBios.psm1 | 125 ----- lib/provider/bios/Show-IcingaBiosData.psm1 | 13 - lib/provider/cpu/Icinga_ProviderCpu.psm1 | 279 ---------- lib/provider/cpu/Show-IcingaCPUData.psm1 | 16 - .../directory/Icinga_Provider_Directory.psm1 | 187 ------- lib/provider/disks/Icinga_ProviderDisks.psm1 | 146 ----- lib/provider/disks/Show-IcingaDiskData.psm1 | 67 --- lib/provider/enums/Icinga_ProviderEnums.psm1 | 525 ------------------ lib/provider/eventlog/Get-IcingaEventLog.psm1 | 153 ----- .../Get-IcingaMemoryPerformanceCounter.psm1 | 18 - .../memory/Get-IcingaMemoryUsage.psm1 | 14 - .../memory/Icinga_ProviderMemory.psm1 | 148 ----- .../memory/Show-IcingaMemoryData.psm1 | 51 -- .../process/Icinga_ProviderProcess.psm1 | 109 ---- .../services/ConvertTo-ServiceStatusCode.psm1 | 15 - .../services/Get-IcingaServiceCheckName.psm1 | 20 - .../services/Icinga_ProviderServices.psm1 | 85 --- .../updates/Get-IcingaUpdatesHotfix.psm1 | 29 - .../updates/Get-IcingaUpdatesInstalled.psm1 | 75 --- .../updates/Get-IcingaUpdatesPending.psm1 | 79 --- .../users/Get-IcingaLoggedOnUsers.psm1 | 43 -- lib/provider/users/Get-IcingaUsers.psm1 | 17 - .../windows/Icinga_ProviderWindows.psm1 | 53 -- .../windows/Show-IcingaWindowsData.psm1 | 11 - 38 files changed, 3393 deletions(-) delete mode 100644 lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 delete mode 100644 lib/plugins/Invoke-IcingaCheckCPU.psm1 delete mode 100644 lib/plugins/Invoke-IcingaCheckCheckSum.psm1 delete mode 100644 lib/plugins/Invoke-IcingaCheckDirectory.psm1 delete mode 100644 lib/plugins/Invoke-IcingaCheckEventlog.psm1 delete mode 100644 lib/plugins/Invoke-IcingaCheckFirewall.psm1 delete mode 100644 lib/plugins/Invoke-IcingaCheckMemory.psm1 delete mode 100644 lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 delete mode 100644 lib/plugins/Invoke-IcingaCheckProcessCount.psm1 delete mode 100644 lib/plugins/Invoke-IcingaCheckService.psm1 delete mode 100644 lib/plugins/Invoke-IcingaCheckUpdates.psm1 delete mode 100644 lib/plugins/Invoke-IcingaCheckUptime.psm1 delete mode 100644 lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 delete mode 100644 lib/plugins/Invoke-IcingaCheckUsers.psm1 delete mode 100644 lib/provider/bios/Icinga_ProviderBios.psm1 delete mode 100644 lib/provider/bios/Show-IcingaBiosData.psm1 delete mode 100644 lib/provider/cpu/Icinga_ProviderCpu.psm1 delete mode 100644 lib/provider/cpu/Show-IcingaCPUData.psm1 delete mode 100644 lib/provider/directory/Icinga_Provider_Directory.psm1 delete mode 100644 lib/provider/disks/Icinga_ProviderDisks.psm1 delete mode 100644 lib/provider/disks/Show-IcingaDiskData.psm1 delete mode 100644 lib/provider/enums/Icinga_ProviderEnums.psm1 delete mode 100644 lib/provider/eventlog/Get-IcingaEventLog.psm1 delete mode 100644 lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 delete mode 100644 lib/provider/memory/Get-IcingaMemoryUsage.psm1 delete mode 100644 lib/provider/memory/Icinga_ProviderMemory.psm1 delete mode 100644 lib/provider/memory/Show-IcingaMemoryData.psm1 delete mode 100644 lib/provider/process/Icinga_ProviderProcess.psm1 delete mode 100644 lib/provider/services/ConvertTo-ServiceStatusCode.psm1 delete mode 100644 lib/provider/services/Get-IcingaServiceCheckName.psm1 delete mode 100644 lib/provider/services/Icinga_ProviderServices.psm1 delete mode 100644 lib/provider/updates/Get-IcingaUpdatesHotfix.psm1 delete mode 100644 lib/provider/updates/Get-IcingaUpdatesInstalled.psm1 delete mode 100644 lib/provider/updates/Get-IcingaUpdatesPending.psm1 delete mode 100644 lib/provider/users/Get-IcingaLoggedOnUsers.psm1 delete mode 100644 lib/provider/users/Get-IcingaUsers.psm1 delete mode 100644 lib/provider/windows/Icinga_ProviderWindows.psm1 delete mode 100644 lib/provider/windows/Show-IcingaWindowsData.psm1 diff --git a/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 b/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 deleted file mode 100644 index 2d13871..0000000 --- a/lib/plugins/Invoke-IcingaCheckBiosSerial.psm1 +++ /dev/null @@ -1,27 +0,0 @@ -Import-IcingaLib provider\bios; - -<# -.SYNOPSIS - Finds out the Bios Serial -.DESCRIPTION - Invoke-IcingaCheckBiosSerial returns either the Bios Serial or nothing. - More Information on https://github.com/Icinga/icinga-powershell-framework -.FUNCTIONALITY - This module is intended to be used to find out the Bios Serial of a given system - Either the a Bios Serial is returned or not. Thereby the Check is always okay. -.EXAMPLE - PS>Invoke-IcingaCheckBiosSerial - [OK]: SerialNumber is 1234-5678-9101-1121-3141-5161-7100 -.OUTPUTS - System.String -.LINK - https://github.com/Icinga/icinga-powershell-framework -.NOTES -#> - -function Invoke-IcingaCheckBiosSerial() -{ - $Bios = Get-IcingaBiosSerialNumber; - $BiosCheck = New-IcingaCheck -Name ([string]::Format('BIOS {0}', $Bios.Name)) -Value $Bios.Value -NoPerfData; - return (New-IcingaCheckresult -Check $BiosCheck -NoPerfData $TRUE -Compile); -} diff --git a/lib/plugins/Invoke-IcingaCheckCPU.psm1 b/lib/plugins/Invoke-IcingaCheckCPU.psm1 deleted file mode 100644 index ad1fa53..0000000 --- a/lib/plugins/Invoke-IcingaCheckCPU.psm1 +++ /dev/null @@ -1,66 +0,0 @@ -Import-IcingaLib core\perfcounter; -Import-IcingaLib core\tools; -Import-IcingaLib icinga\plugin; - -<# -.SYNOPSIS - Checks cpu usage of cores. -.DESCRIPTION - Invoke-IcingaCheckCPU returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. - e.g A system has 4 cores, each running at 60% usage, WARNING is set to 50%, CRITICAL is set to 75%. In this case the check will return WARNING. - More Information on https://github.com/Icinga/icinga-powershell-framework -.FUNCTIONALITY - This module is intended to be used to check on the current cpu usage of a specified core. - Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. -.EXAMPLE - PS>Invoke-IcingaCheckCpu -Warning 50 -Critical 75 - [OK]: Check package "CPU Load" is [OK] - | 'Core #0'=4,588831%;50;75;0;100 'Core #1'=0,9411243%;50;75;0;100 'Core #2'=11,53223%;50;75;0;100 'Core #3'=4,073013%;50;75;0;100 -.EXAMPLE - PS>Invoke-IcingaCheckCpu -Warning 50 -Critical 75 -Core 1 - [OK]: Check package "CPU Load" is [OK] - | 'Core #1'=2,612651%;50;75;0;100 -.PARAMETER Warning - Used to specify a Warning threshold. In this case an integer value. -.PARAMETER Critical - Used to specify a Critical threshold. In this case an integer value. -.PARAMETER Core - Used to specify a single core to check on. -.INPUTS - System.String -.OUTPUTS - System.String -.LINK - https://github.com/Icinga/icinga-powershell-framework -.NOTES -#> - -function Invoke-IcingaCheckCPU() -{ - param( - $Warning = $null, - $Critical = $null, - [string]$Core = '*', - [switch]$NoPerfData, - [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 - ); - - $CpuCounter = New-IcingaPerformanceCounter -Counter ([string]::Format('\Processor({0})\% processor time', $Core)); - $CpuPackage = New-IcingaCheckPackage -Name 'CPU Load' -OperatorAnd -Verbose $Verbosity; - $CpuCount = ([string](Get-IcingaCpuCount)).Length; - - if ($CpuCounter.Counters.Count -ne 0) { - foreach ($counter in $CpuCounter.Counters) { - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core {0}', (Format-IcingaDigitCount $counter.Instance.Replace('_', '') -Digits $CpuCount -Symbol ' '))) -Value $counter.Value().Value -Unit '%'; - $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; - $CpuPackage.AddCheck($IcingaCheck); - } - } else { - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Core {0}', (Format-IcingaDigitCount $Core.Replace('_', '') -Digits $CpuCount -Symbol ' '))) -Value $CpuCounter.Value().Value -Unit '%'; - $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; - $CpuPackage.AddCheck($IcingaCheck); - } - - return (New-IcingaCheckResult -Name 'CPU Load' -Check $CpuPackage -NoPerfData $NoPerfData -Compile); -} diff --git a/lib/plugins/Invoke-IcingaCheckCheckSum.psm1 b/lib/plugins/Invoke-IcingaCheckCheckSum.psm1 deleted file mode 100644 index c399184..0000000 --- a/lib/plugins/Invoke-IcingaCheckCheckSum.psm1 +++ /dev/null @@ -1,65 +0,0 @@ -<# -.SYNOPSIS - Checks hash against filehash of a file -.DESCRIPTION - Invoke-IcingaCheckCheckSum returns either 'OK' or 'CRITICAL', whether the check matches or not. - - More Information on https://github.com/Icinga/icinga-powershell-framework -.FUNCTIONALITY - This module is intended to be used to check a hash against a filehash of a file, to determine whether changes have occured. - Based on the match result the status will change between 'OK' or 'CRITICAL'. The function will return one of these given codes. -.EXAMPLE - PS> Invoke-IcingaCheckCheckSum -Path "C:\Users\Icinga\Downloads\test.txt" - [OK] CheckSum C:\Users\Icinga\Downloads\test.txt is 008FB84A017F5DFDAF038DB2FDD6934E6E5D9CD3C7AACE2F2168D7D93AF51E4B - |0 -.EXAMPLE - PS> Invoke-IcingaCheckCheckSum -Path "C:\Users\Icinga\Downloads\test.txt" -Hash 008FB84A017F5DFDAF038DB2FDD6934E6E5D9CD3C7AACE2F2168D7D93AF51E4B - [OK] CheckSum C:\Users\Icinga\Downloads\test.txt is 008FB84A017F5DFDAF038DB2FDD6934E6E5D9CD3C7AACE2F2168D7D93AF51E4B| - 0 -.EXAMPLE - PS> Invoke-IcingaCheckCheckSum -Path "C:\Users\Icinga\Downloads\test.txt" -Hash 008FB84A017F5DFDAF038DB2FDD6934E6E5D - [CRITICAL] CheckSum C:\Users\Icinga\Downloads\test.txt 008FB84A017F5DFDAF038DB2FDD6934E6E5D9CD3C7AACE2F2168D7D93AF51E4B is not matching 008FB84A017F5DFDAF038DB2FDD6934E6E5D - | - 2 -.PARAMETER WarningBytes - Used to specify a string to the path of a file, which will be checked. - - The string has to be like "C:\Users\Icinga\test.txt" - -.PARAMETER Algorithm - Used to specify a string, which contains the algorithm to be used. - - Allowed algorithms: 'SHA1', 'SHA256', 'SHA384', 'SHA512', 'MD5' - -.INPUTS - System.String - -.OUTPUTS - System.String - -.LINK - https://github.com/Icinga/icinga-powershell-framework -.NOTES -#> - -function Invoke-IcingaCheckCheckSum() -{ - param( - [string]$Path = $null, - [ValidateSet('SHA1', 'SHA256', 'SHA384', 'SHA512', 'MD5')] - [string]$Algorithm = 'SHA256', - [string]$Hash = $null, - [switch]$NoPerfData, - [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 - ); - - [string]$FileHash = (Get-FileHash $Path -Algorithm $Algorithm).Hash - $CheckSumCheck = New-IcingaCheck -Name "CheckSum $Path" -Value $FileHash; - - If(([string]::IsNullOrEmpty($Hash)) -eq $FALSE){ - $CheckSumCheck.CritIfNotMatch($Hash) | Out-Null; - } - - return (New-IcingaCheckresult -Check $CheckSumCheck -NoPerfData $NoPerfData -Compile); -} \ No newline at end of file diff --git a/lib/plugins/Invoke-IcingaCheckDirectory.psm1 b/lib/plugins/Invoke-IcingaCheckDirectory.psm1 deleted file mode 100644 index c030596..0000000 --- a/lib/plugins/Invoke-IcingaCheckDirectory.psm1 +++ /dev/null @@ -1,115 +0,0 @@ -Import-IcingaLib provider\directory; - -<# -.SYNOPSIS - Checks how many files are in a directory. -.DESCRIPTION - Invoke-IcingaCheckDirectory returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. - e.g 'C:\Users\Icinga\Backup' contains 200 files, WARNING is set to 150, CRITICAL is set to 300. In this case the check will return CRITICAL - More Information on https://github.com/Icinga/icinga-powershell-framework -.FUNCTIONALITY - This module is intended to be used to check how many files and directories are within are specified path. - Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. -.EXAMPLE - PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -Warning 20 -Critical 30 -Verbosity 3 - [OK]: Check package "C:\Users\Icinga\Downloads" is [OK] (Match All) - \_ [OK]: C:\Users\Icinga\Downloads is 19 -.EXAMPLE - PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -Warning 20 -Critical 30 -Verbosity 3 - [WARNING]: Check package "C:\Users\Icinga\Downloads" is [WARNING] (Match All) - \_ [WARNING]: C:\Users\Icinga\Downloads is 24 -.EXAMPLE - PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -Warning 20 -Critical 30 -Verbosity 3 -ChangeYoungerThen 20d -ChangeOlderThen 10d - [OK]: Check package "C:\Users\Icinga\Downloads" is [OK] (Match All) - \_ [OK]: C:\Users\Icinga\Downloads is 1 -.EXAMPLE - PS>Invoke-IcingaCheckDirectory -Path "C:\Users\Icinga\Downloads" -FileNames "*.txt","*.sql" -Warning 20 -Critical 30 -Verbosity 3 - [OK]: Check package "C:\Users\Icinga\Downloads" is [OK] (Match All) - \_ [OK]: C:\Users\Icinga\Downloads is 4 -.PARAMETER Warning - Used to specify a Warning threshold. In this case an integer value. -.PARAMETER Critical - Used to specify a Critical threshold. In this case an integer value. -.PARAMETER Path - Used to specify a path. - e.g. 'C:\Users\Icinga\Downloads' -.PARAMETER FileNames - Used to specify an array of filenames or expressions to match against. - - e.g '*.txt', '*.sql' # Fiends all files ending with .txt and .sql -.PARAMETER Recurse - A switch, which can be set to filter through directories recursively. -.PARAMETER ChangeYoungerThen - String that expects input format like "20d", which translates to 20 days. Allowed units: ms, s, m, h, d, w, M, y. - - Thereby all files which have a change date younger then 20 days are considered within the check. -.PARAMETER ChangeOlderThen - String that expects input format like "20d", which translates to 20 days. Allowed units: ms, s, m, h, d, w, M, y. - - Thereby all files which have a change date older then 20 days are considered within the check. -.PARAMETER CreationYoungerThen - String that expects input format like "20d", which translates to 20 days. Allowed units: ms, s, m, h, d, w, M, y. - - Thereby all files which have a creation date younger then 20 days are considered within the check. -.PARAMETER CreationOlderThen - String that expects input format like "20d", which translates to 20 days. Allowed units: ms, s, m, h, d, w, M, y. - - Thereby all files which have a creation date older then 20 days are considered within the check. - -.PARAMETER ChangeTimeEqual - String that expects input format like "20d", which translates to 20 days. Allowed units: ms, s, m, h, d, w, M, y. - - Thereby all files which have been changed 20 days ago are considered within the check. - -.PARAMETER CreationTimeEqual - String that expects input format like "20d", which translates to 20 days. Allowed units: ms, s, m, h, d, w, M, y. - - Thereby all files which have been created 20 days ago are considered within the check. - - -.INPUTS - System.String -.OUTPUTS - System.String -.LINK - https://github.com/Icinga/icinga-powershell-framework -.NOTES -#> - -function Invoke-IcingaCheckDirectory() -{ - param( - [string]$Path, - [array]$FileNames, - [switch]$Recurse, - $Critical = $null, - $Warning = $null, - [string]$ChangeTimeEqual, - [string]$ChangeYoungerThan, - [string]$ChangeOlderThan, - [string]$CreationTimeEqual, - [string]$CreationOlderThan, - [string]$CreationYoungerThan, - [string]$FileSizeGreaterThan, - [string]$FileSizeSmallerThan, - [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0, - [switch]$NoPerfData - ); - - $DirectoryData = Get-IcingaDirectoryAll -Path $Path -FileNames $FileNames -Recurse $Recurse ` - -ChangeYoungerThan $ChangeYoungerThan -ChangeOlderThan $ChangeOlderThan ` - -CreationYoungerThan $CreationYoungerThan -CreationOlderThan $CreationOlderThan ` - -CreationTimeEqual $CreationTimeEqual -ChangeTimeEqual $ChangeTimeEqual; - $DirectoryCheck = New-IcingaCheck -Name 'File Count' -Value $DirectoryData.Count; - - $DirectoryCheck.WarnOutOfRange( - ($Warning) - ).CritOutOfRange( - ($Critical) - ) | Out-Null; - - $DirectoryPackage = New-IcingaCheckPackage -Name $Path -OperatorAnd -Checks $DirectoryCheck -Verbose $Verbosity; - - return (New-IcingaCheckresult -Check $DirectoryPackage -NoPerfData $NoPerfData -Compile); -} \ No newline at end of file diff --git a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 b/lib/plugins/Invoke-IcingaCheckEventlog.psm1 deleted file mode 100644 index 18b8ccc..0000000 --- a/lib/plugins/Invoke-IcingaCheckEventlog.psm1 +++ /dev/null @@ -1,122 +0,0 @@ -Import-IcingaLib icinga\plugin; - -<# -.SYNOPSIS - Checks how many eventlog occurences of a given type there are. -.DESCRIPTION - Invoke-IcingaCheckEventlog returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. - e.g Eventlog returns 500 entrys with the specified parameters, WARNING is set to 200, CRITICAL is set to 800. Thereby the check will return WARNING. - - More Information on https://github.com/Icinga/icinga-powershell-framework -.FUNCTIONALITY - This Module is intended to be used to check how many eventlog occurences of a given type there are. - Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. -.EXAMPLE - PS> Invoke-IcingaCheckEventlog -LogName Application -IncludeEntryType Warning -Warning 100 -Critical 1000 - [WARNING]: Check package "EventLog" is [WARNING] - | 'EventId_508'=2c;; 'EventId_2002'=586c;; 'EventId_63'=6c;; 'EventId_2248216578'=1364c;; 'EventId_1008'=1745c;; 'EventId_2147489653'=1c;; 'EventId_636'=3c;; 'EventId_2147484656'=1c;; 'EventId_2147489654'=1c;; 'EventId_640'=3c;; 'EventId_533'=1c;; - 1 - PS> Invoke-IcingaCheckEventlog -LogName Application -IncludeEntryType Warning -Warning 100 -Critical 1000 - [OK]: Check package "EventLog" is [OK]| - 0 -.EXAMPLE - PS> Invoke-IcingaCheckEventlog -LogName Application -IncludeEntryType Warning -Warning 100 -Critical 1000 - [WARNING]: Check package "EventLog" is [WARNING] - | 'EventId_508'=2c;; 'EventId_2002'=586c;; 'EventId_63'=6c;; 'EventId_2248216578'=1364c;; 'EventId_1008'=1745c;; 'EventId_2147489653'=1c;; 'EventId_636'=3c;; 'EventId_2147484656'=1c;; 'EventId_2147489654'=1c;; 'EventId_640'=3c;; 'EventId_533'=1c;; - 1 - PS> Invoke-IcingaCheckEventlog -LogName Application -IncludeEntryType Warning -Warning 100 -Critical 1000 -DisableTimeCache - [WARNING]: Check package "EventLog" is [WARNING] - | 'EventId_508'=2c;; 'EventId_2002'=586c;; 'EventId_63'=6c;; 'EventId_2248216578'=1364c;; 'EventId_1008'=1745c;; 'EventId_2147489653'=1c;; 'EventId_636'=3c;; 'EventId_2147484656'=1c;; 'EventId_2147489654'=1c;; 'EventId_640'=3c;; 'EventId_533'=1c;; - 1 -.PARAMETER Warning - Used to specify a Warning threshold. -.PARAMETER Critical - Used to specify a Critical threshold. -.PARAMETER LogName - Used to specify a certain log. -.PARAMETER IncludeEventId - Used to specify an array of events identified by their id to be included. -.PARAMETER ExcludeEventId - Used to specify an array of events identified by their id to be excluded. -.PARAMETER IncludeUsername - Used to specify an array of usernames within the eventlog to be included. -.PARAMETER ExcludeUsername - Used to specify an array of usernames within the eventlog to be excluded. -.PARAMETER IncludeEntryType - Used to specify an array of entry types within the eventlog to be included. -.PARAMETER ExcludeEntryType - Used to specify an array of entry types within the eventlog to be excluded. -.PARAMETER IncludeMessage - Used to specify an array of messages within the eventlog to be included. -.PARAMETER ExcludeMessage - Used to specify an array of messages within the eventlog to be excluded. -.PARAMETER After - Used to specify a date like dd.mm.yyyy and every eventlog entry after that date will be considered. -.PARAMETER Before - Used to specify a date like dd.mm.yyyy and every eventlog entry before that date will be considered. -.PARAMETER DisableTimeCache - Switch to disable the time cache on a check. If this parameter is set the time cache is disabled. - After the check has been run once, the next check instance will filter through the eventlog from the point the last check ended. - This is due to the time cache, when disabled the whole eventlog is checked instead. -.INPUTS - System.String -.OUTPUTS - System.String -.LINK - https://github.com/Icinga/icinga-powershell-framework -.NOTES -#> - -function Invoke-IcingaCheckEventlog() -{ - param( - $Warning = $null, - $Critical = $null, - [string]$LogName, - [array]$IncludeEventId, - [array]$ExcludeEventId, - [array]$IncludeUsername, - [array]$ExcludeUsername, - [array]$IncludeEntryType, - [array]$ExcludeEntryType, - [array]$IncludeMessage, - [array]$ExcludeMessage, - $After = $null, - $Before = $null, - [switch]$DisableTimeCache = $FALSE, - [switch]$NoPerfData, - [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 - ); - - $EventLogPackage = New-IcingaCheckPackage -Name 'EventLog' -OperatorAnd -Verbose $Verbosity; - $EventLogData = Get-IcingaEventLog -LogName $LogName -IncludeEventId $IncludeEventId -ExcludeEventId $ExcludeEventId -IncludeUsername $IncludeUsername -ExcludeUsername $ExcludeUsername ` - -IncludeEntryType $IncludeEntryType -ExcludeEntryType $ExcludeEntryType -IncludeMessage $IncludeMessage -ExcludeMessage $ExcludeMessage ` - -After $After -Before $Before -DisableTimeCache $DisableTimeCache; - - if ($EventLogData.eventlog.Count -ne 0) { - foreach ($event in $EventLogData.eventlog.Keys) { - $eventEntry = $EventLogData.eventlog[$event]; - $EventLogEntryPackage = New-IcingaCheckPackage -Name ([string]::Format('Between: [{0}] - [{1}] there occured {2} event(s).', $eventEntry.OldestEntry, $eventEntry.NewestEntry, $eventEntry.Count)) -OperatorAnd -Verbose $Verbosity; - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('EventId {0}', $EventLogData.eventlog[$event].EventId)) -Value $eventEntry.Count -NoPerfData; - $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; - $EventLogEntryPackage.AddCheck($IcingaCheck); - - $EventLogPackage.AddCheck($EventLogEntryPackage); - } - - $EventLogCountPackage = New-IcingaCheckPackage -Name 'EventLog Count' -OperatorAnd -Verbose $Verbosity -Hidden; - - foreach ($event in $EventLogData.events.Keys) { - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('EventId {0}', $event)) -Value $EventLogData.events[$event] -Unit 'c'; - $EventLogCountPackage.AddCheck($IcingaCheck); - } - - $EventLogPackage.AddCheck($EventLogCountPackage); - } else { - $IcingaCheck = New-IcingaCheck -Name 'No EventLogs found' -Value 0 -Unit 'c' -NoPerfData; - $EventLogPackage.AddCheck($IcingaCheck); - } - - return (New-IcingaCheckResult -Name 'EventLog' -Check $EventLogPackage -NoPerfData $NoPerfData -Compile); -} diff --git a/lib/plugins/Invoke-IcingaCheckFirewall.psm1 b/lib/plugins/Invoke-IcingaCheckFirewall.psm1 deleted file mode 100644 index 57d2bf8..0000000 --- a/lib/plugins/Invoke-IcingaCheckFirewall.psm1 +++ /dev/null @@ -1,73 +0,0 @@ -<# -.SYNOPSIS - Checks whether a firewall module is enabled or not -.DESCRIPTION - Invoke-IcingaCheckFirewall returns either 'OK' or 'CRITICAL', whether the check matches or not. - - More Information on https://github.com/Icinga/icinga-powershell-framework -.FUNCTIONALITY - This module is intended to be used to check the status of a firewall profile. - Based on the match result the status will change between 'OK' or 'CRITICAL'. The function will return one of these given codes. -.EXAMPLE - PS> Invoke-IcingaCheckFirewall -Profile "Domain" -Verbosity 3 - [OK] Check package "Firewall profiles" (Match All) - \_ [OK] Firewall Profile Domain is True - | 'firewall_profile_domain'=True;; - 0 -.EXAMPLE - PS> Invoke-IcingaCheckFirewall -Profile "Domain", "Private" -Verbosity 1} - [OK] Check package "Firewall profiles" (Match All) - | 'firewall_profile_domain'=True;; 'firewall_profile_private'=True;; - 0 - [array]$Profile, - [bool]$Status = $TRUE, -.PARAMETER Profile - Used to specify an array of profiles to check. - -.PARAMETER Status - Used to specify a bool value, which determines, whether the firewall profiles should be enabled or disabled. - - -Status $TRUE - translates to enabled, while - -Status $FALSE - translates to disabled. -.INPUTS - System.String - -.OUTPUTS - System.String - -.LINK - https://github.com/Icinga/icinga-powershell-framework -.NOTES -#> - -function Invoke-IcingaCheckFirewall() -{ - param( - [array]$Profile, - [bool]$Status = $TRUE, - [switch]$NoPerfData, - [int]$Verbosity = 0 - ); - - if ($Status -eq $TRUE) { - $StatusString = "true" - } else { - $StatusString = "false" - } - - $FirewallPackage = New-IcingaCheckPackage -Name 'Firewall profiles' -OperatorAnd -Verbos $Verbosity; - - foreach ($singleprofile in $Profile) { - $FirewallData = (Get-NetFirewallProfile -Name $singleprofile) - - $FirewallCheck = New-IcingaCheck -Name "Firewall Profile $singleprofile" -Value $FirewallData.Enabled; - $FirewallCheck.CritIfNotMatch($StatusString) | Out-Null; - - $FirewallPackage.AddCheck($FirewallCheck) - } - - - return (New-IcingaCheckResult -Check $FirewallPackage -NoPerfData $NoPerfData -Compile); -} \ No newline at end of file diff --git a/lib/plugins/Invoke-IcingaCheckMemory.psm1 b/lib/plugins/Invoke-IcingaCheckMemory.psm1 deleted file mode 100644 index 55b156c..0000000 --- a/lib/plugins/Invoke-IcingaCheckMemory.psm1 +++ /dev/null @@ -1,113 +0,0 @@ -Import-IcingaLib provider\memory; -Import-IcingaLib core\tools; - -<# -.SYNOPSIS - Checks on memory usage -.DESCRIPTION - Invoke-IcingaCheckMemory returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. - e.g memory is currently at 60% usage, WARNING is set to 50, CRITICAL is set to 90. In this case the check will return WARNING. - - More Information on https://github.com/Icinga/icinga-powershell-framework -.FUNCTIONALITY - This module is intended to be used to check on memory usage. - Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. -.EXAMPLE - PS>Invoke-IcingaCheckMemory -Verbosity 3 -Warning 60 -Critical 80 - [WARNING]: % Memory Check 78.74 is greater than 60 - 1 -.EXAMPLE - PS> -.PARAMETER WarningBytes - Used to specify a Warning threshold. In this case an string value. - - The string has to be like, "20B", "20KB", "20MB", "20GB", "20TB", "20TB" -.PARAMETER CriticalBytes - Used to specify a Critical threshold. In this case an string value. - - The string has to be like, "20B", "20KB", "20MB", "20GB", "20TB", "20TB" - -.PARAMETER Pagefile - Switch which determines whether the pagefile should be used instead. - If not set memory will be checked. - -.PARAMETER CriticalPercent - Used to specify a Critical threshold. In this case an integer value. - - Like 30 for 30%. If memory usage is below 30%, the check will return CRITICAL. - -.PARAMETER CriticalPercent - Used to specify a Critical threshold. In this case an integer value. - - Like 30 for 30%. If memory usage is below 30%, the check will return Warning. - -.INPUTS - System.String - -.OUTPUTS - System.String - -.LINK - https://github.com/Icinga/icinga-powershell-framework -.NOTES -#> - -function Invoke-IcingaCheckMemory() -{ - param( - [string]$CriticalBytes = $null, - [string]$WarningBytes = $null, - $CriticalPercent = $null, - $WarningPercent = $null, -# [switch]$PageFile, - [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0, - [switch]$NoPerfData - ); - - If ([string]::IsNullOrEmpty($CriticalBytes) -eq $FALSE) { - $CrticalConvertedAll = Convert-Bytes $CriticalBytes -Unit B - [decimal]$CriticalConverted = $CriticalConvertedAll.value - - } - If ([string]::IsNullOrEmpty($WarningBytes) -eq $FALSE) { - $WarningConvertedAll = Convert-Bytes $WarningBytes -Unit B - [decimal]$WarningConverted = $WarningConvertedAll.value - } - - $MemoryPackage = New-IcingaCheckPackage -Name 'Memory Usage' -OperatorAnd -Verbos $Verbosity; - $MemoryData = (Get-IcingaMemoryPerformanceCounter); - - # Auto-Detect? - If (($MemoryData['Memory Total Bytes'] / [math]::Pow(2, 50)) -ge 1) { - $Unit = "PB" - } elseif (($MemoryData['Memory Total Bytes'] / [math]::Pow(2, 40)) -ge 1) { - $Unit = "TB" - } elseif (($MemoryData['Memory Total Bytes'] / [math]::Pow(2, 30)) -ge 1) { - $Unit = "GB" - } elseif (($MemoryData['Memory Total Bytes'] / [math]::Pow(2, 20)) -ge 1) { - $Unit = "MB" - } elseif (($MemoryData['Memory Total Bytes'] / [math]::Pow(2, 10)) -ge 1) { - $Unit = "KB" - } else { - $Unit = "B" - } - - Write-Host $Unit - - $MemoryPerc = New-IcingaCheck -Name 'Memory Percent Used' -Value $MemoryData['Memory Used %'] -Unit '%'; - $MemoryByteUsed = New-IcingaCheck -Name "Used Bytes" -Value $MemoryData['Memory Used Bytes'] -Unit 'B'; - #$MemoryByteAvailable = New-IcingaCheck -Name "Available Bytes" -Value $MemoryData['Memory Available Bytes'] -Unit 'B'; - #$PageFileCheck = New-IcingaCheck -Name 'PageFile Percent' -Value $MemoryData['PageFile %'] -Unit '%'; - - # PageFile To-Do - $MemoryByteUsed.WarnOutOfRange($WarningConverted).CritOutOfRange($CrticalConverted) | Out-Null; - $MemoryPerc.WarnOutOfRange($WarningPercent).CritOutOfRange($CriticalPercent) | Out-Null; - - $MemoryPackage.AddCheck($MemoryPerc); - #$MemoryPackage.AddCheck($MemoryByteAvailable); - $MemoryPackage.AddCheck($MemoryByteUsed); - #$MemoryPackage.AddCheck($PageFileCheck); - - return (New-IcingaCheckResult -Check $MemoryPackage -NoPerfData $NoPerfData -Compile); -} diff --git a/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 b/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 deleted file mode 100644 index 2b9191c..0000000 --- a/lib/plugins/Invoke-IcingaCheckPerfcounter.psm1 +++ /dev/null @@ -1,70 +0,0 @@ -Import-IcingaLib icinga\plugin; - -<# -.SYNOPSIS - Performs checks on various performance counter -.DESCRIPTION - Invoke-IcingaCheckDirectory returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. - Use "Show-IcingaPerformanceCounterCategories" to see all performance counter categories available. - To gain insight on an specific performance counter use "Show-IcingaPerformanceCounters " - e.g ' - - More Information on https://github.com/Icinga/icinga-powershell-framework -.FUNCTIONALITY - This module is intended to be used to perform checks on different performance counter. - Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. -.EXAMPLE - PS> Invoke-IcingaCheckPerfCounter -PerfCounter '\processor(*)\% processor time' -Warning 60 -Critical 90 - [WARNING]: Check package "Performance Counter" is [WARNING] - | 'processor1_processor_time'=68.95;60;90 'processor3_processor_time'=4.21;60;90 'processor5_processor_time'=9.5;60;90 'processor_Total_processor_time'=20.6;60;90 'processor0_processor_time'=5.57;60;90 'processor2_processor_time'=0;60;90 'processor4_processor_time'=6.66;60;90 - 1 -.PARAMETER Warning - Used to specify a Warning threshold. In this case an ??? value. -.PARAMETER Critical - Used to specify a Critical threshold. In this case an ??? value. -.PARAMETER PerfCounter - Used to specify an array of performance counter to check against. -.INPUTS - System.String -.OUTPUTS - System.String -.LINK - https://github.com/Icinga/icinga-powershell-framework -.NOTES -#> - -function Invoke-IcingaCheckPerfcounter() -{ - param( - [array]$PerfCounter, - $Warning = $null, - $Critical = $null, - [switch]$NoPerfData, - [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 - ); - - $Counters = New-IcingaPerformanceCounterArray -CounterArray $PerfCounter; - $CheckPackage = New-IcingaCheckPackage -Name 'Performance Counter' -OperatorAnd -Verbose $Verbosity; - - foreach ($counter in $Counters.Keys) { - - $CounterPackage = New-IcingaCheckPackage -Name $counter -OperatorAnd -Verbose $Verbosity; - - foreach ($instanceName in $Counters[$counter].Keys) { - $instance = $Counters[$counter][$instanceName]; - if ($instance -isnot [hashtable]) { - $IcingaCheck = New-IcingaCheck -Name $counter -Value $Counters[$counter].Value; - $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; - $CounterPackage.AddCheck($IcingaCheck); - break; - } - $IcingaCheck = New-IcingaCheck -Name $instanceName -Value $instance.Value; - $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; - $CounterPackage.AddCheck($IcingaCheck); - } - $CheckPackage.AddCheck($CounterPackage); - } - - return (New-IcingaCheckresult -Check $CheckPackage -NoPerfData $NoPerfData -Compile); -} diff --git a/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 b/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 deleted file mode 100644 index 8bf792a..0000000 --- a/lib/plugins/Invoke-IcingaCheckProcessCount.psm1 +++ /dev/null @@ -1,71 +0,0 @@ -Import-IcingaLib provider\process; -Import-IcingaLib icinga\plugin; - -<# -.SYNOPSIS - Checks how many processes of a process exist. -.DESCRIPTION - Invoke-IcingaCheckDirectory returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. - e.g there are three conhost processes running, WARNING is set to 3, CRITICAL is set to 4. In this case the check will return WARNING. - More Information on https://github.com/Icinga/icinga-powershell-framework -.FUNCTIONALITY - This module is intended to be used to check how many processes of a process exist. - Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. -.EXAMPLE - PS>Invoke-IcingaCheckProcessCount -Process conhost -Warning 5 -Critical 10 - [OK]: Check package "Process Check" is [OK] - | 'Process Count "conhost"'=3;; -.EXAMPLE - PS>Invoke-IcingaCheckProcessCount -Process conhost,wininit -Warning 5 -Critical 10 -Verbosity 4 - [OK]: Check package "Process Check" is [OK] (Match All) - \_ [OK]: Process Count "conhost" is 3 - \_ [OK]: Process Count "wininit" is 1 - | 'Process Count "conhost"'=3;5;10 'Process Count "wininit"'=1;5;10 -.PARAMETER Warning - Used to specify a Warning threshold. In this case an integer value. -.PARAMETER Critical - Used to specify a Critical threshold. In this case an integer value. -.PARAMETER Process - Used to specify an array of processes to count and match against. - e.g. conhost,wininit -.INPUTS - System.String -.OUTPUTS - System.String -.LINK - https://github.com/Icinga/icinga-powershell-framework -.NOTES -#> - -function Invoke-IcingaCheckProcessCount() -{ - param( - $Warning = $null, - $Critical = $null, - [array]$Process, - [switch]$NoPerfData, - [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 - ); - - $ProcessInformation = (Get-IcingaProcessData -Name $Process) - - $ProcessPackage = New-icingaCheckPackage -Name "Process Check" -OperatorAnd -Verbose $Verbosity -NoPerfData $NoPerfData; - - if ($Process.Count -eq 0) { - $ProcessCount = $ProcessInformation['Process Count']; - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Process Count')) -Value $ProcessCount; - $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; - $ProcessPackage.AddCheck($IcingaCheck); - } else { - foreach ($proc in $process) { - $ProcessCount = $ProcessInformation."Processes".$proc.processlist.Count; - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Process Count "{0}"', $proc)) -Value $ProcessCount; - $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; - $ProcessPackage.AddCheck($IcingaCheck); - } - } - - - return (New-IcingaCheckResult -Check $ProcessPackage -NoPerfData $NoPerfData -Compile); -} diff --git a/lib/plugins/Invoke-IcingaCheckService.psm1 b/lib/plugins/Invoke-IcingaCheckService.psm1 deleted file mode 100644 index 743d291..0000000 --- a/lib/plugins/Invoke-IcingaCheckService.psm1 +++ /dev/null @@ -1,92 +0,0 @@ -Import-IcingaLib provider\services; -Import-IcingaLib provider\enums; -Import-IcingaLib icinga\plugin; - -<# -.SYNOPSIS - Checks if a service has a specified status. -.DESCRIPTION - Invoke-icingaCheckService returns either 'OK' or 'CRITICAL', if a service status is matching status to be checked. - More Information on https://github.com/Icinga/icinga-powershell-framework -.FUNCTIONALITY - This module is intended to be used to check whether one or more services have a certain status. - As soon as one of the specified services does not match the status, the function returns 'CRITICAL' instead of 'OK'. -.EXAMPLE - PS>Invoke-IcingaCheckService -Service WiaRPC, Spooler -Status '1' -Verbose 3 - [CRITICAL]: Check package "Services" is [CRITICAL] (Match All) - \_ [OK]: Service "Ereignisse zum Abrufen von Standbildern (WiaRPC)" is Stopped - \_ [CRITICAL]: Service "Druckwarteschlange (Spooler)" Running is not matching Stopped -.PARAMETER Service - Used to specify an array of services which should be checked against the status. - Seperated with ',' -.PARAMETER Status - Status for the specified service or services to check against. -.INPUTS - System.Array -.OUTPUTS - System.String -.LINK - https://github.com/Icinga/icinga-powershell-framework -.NOTES -#> - -function Invoke-IcingaCheckService() -{ - param( - [array]$Service, - [ValidateSet('Stopped', 'StartPending', 'StopPending', 'Running', 'ContinuePending', 'PausePending', 'Paused')] - [string]$Status = 'Running', - [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0, - [switch]$NoPerfData - ); - - $ServicesPackage = New-IcingaCheckPackage -Name 'Services' -OperatorAnd -Verbose $Verbosity; - $ServicesCountPackage = New-IcingaCheckPackage -Name 'Count Services' -OperatorAnd -Verbose $Verbosity -Hidden; - - [int]$StoppedCount,[int]$StartPendingCount,[int]$StopPendingCount,[int]$RunningCount,[int]$ContinuePendingCount,[int]$PausePendingCount,[int]$PausedCount,[int]$ServicesCounted = 0 - foreach ($services in $Service) { - $IcingaCheck = $null; - - $FoundService = Get-IcingaServices -Service $services; - $ServiceName = Get-IcingaServiceCheckName -ServiceInput $services -Service $FoundService; - $ConvertedStatus = ConvertTo-ServiceStatusCode -Status $Status; - $StatusRaw = $FoundService.Values.configuration.Status.raw; - - $IcingaCheck = New-IcingaCheck -Name $ServiceName -Value $StatusRaw -ObjectExists $FoundService -Translation $ProviderEnums.ServiceStatusName; - $IcingaCheck.CritIfNotMatch($ConvertedStatus) | Out-Null; - $ServicesPackage.AddCheck($IcingaCheck) - - switch($StatusRaw) { - {1 -contains $_} { $StoppedCount++; $ServicesCounted++} - {2 -contains $_} { $StartPendingCount++; $ServicesCounted++} - {3 -contains $_} { $StopPendingCount++; $ServicesCounted++} - {4 -contains $_} { $RunningCount++; $ServicesCounted++} - {5 -contains $_} { $ContinuePendingCount++; $ServicesCounted++} - {6 -contains $_} { $PausePendingCount++; $ServicesCounted++} - {7 -contains $_} { $PausedCount++; $ServicesCounted++} - } - } - $IcingaStopped = New-IcingaCheck -Name 'stopped services' -Value $StoppedCount; - $IcingaStartPending = New-IcingaCheck -Name 'pending started services' -Value $StartPendingCount; - $IcingaStopPending = New-IcingaCheck -Name 'pending stopped services' -Value $StopPendingCount; - $IcingaRunning = New-IcingaCheck -Name 'running services' -Value $RunningCount; - $IcingaContinuePending = New-IcingaCheck -Name 'pending continued services' -Value $ContinuePendingCount; - $IcingaPausePending = New-IcingaCheck -Name 'pending paused services' -Value $PausePendingCount; - $IcingaPaused = New-IcingaCheck -Name 'paused services' -Value $PausePendingCount; - - $IcingaCount = New-IcingaCheck -Name 'service count' -Value $ServicesCounted; - - $ServicesCountPackage.AddCheck($IcingaStopped) - $ServicesCountPackage.AddCheck($IcingaStartPending) - $ServicesCountPackage.AddCheck($IcingaStopPending) - $ServicesCountPackage.AddCheck($IcingaRunning) - $ServicesCountPackage.AddCheck($IcingaContinuePending) - $ServicesCountPackage.AddCheck($IcingaPausePending) - $ServicesCountPackage.AddCheck($IcingaPaused) - - $ServicesCountPackage.AddCheck($IcingaCount) - $ServicesPackage.AddCheck($ServicesCountPackage) - - return (New-IcingaCheckResult -Name 'Services' -Check $ServicesPackage -NoPerfData $NoPerfData -Compile); -} diff --git a/lib/plugins/Invoke-IcingaCheckUpdates.psm1 b/lib/plugins/Invoke-IcingaCheckUpdates.psm1 deleted file mode 100644 index fc954e0..0000000 --- a/lib/plugins/Invoke-IcingaCheckUpdates.psm1 +++ /dev/null @@ -1,87 +0,0 @@ -Import-IcingaLib icinga\plugin; -Import-IcingaLib provider\updates; - -<# -.SYNOPSIS - Checks how many updates are to be applied -.DESCRIPTION - Invoke-IcingaCheckUpdates returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. - e.g 'C:\Users\Icinga\Backup' 10 updates are pending, WARNING is set to 20, CRITICAL is set to 50. In this case the check will return OK. - More Information on https://github.com/Icinga/icinga-powershell-framework -.FUNCTIONALITY - This module is intended to be used to check how many updates are to be applied and thereby currently pending - Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. - -.EXAMPLE - PS> Invoke-IcingaCheckUpdates -Warning 4 -Critical 20 - [OK]: Check package "Updates" is [OK] - | 'Pending Update Count'=2;4;20 -.PARAMETER Warning - Used to specify a Warning threshold. In this case an integer value. -.PARAMETER Critical - Used to specify a Critical threshold. In this case an integer value. -.INPUTS - System.String -.OUTPUTS - System.String -.LINK - https://github.com/Icinga/icinga-powershell-framework -.NOTES -#> - -function Invoke-IcingaCheckUpdates() -{ - param ( - [array]$UpdateFilter, - $Warning = $null, - $Critical = $null, - [switch]$NoPerfData, - [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 - ); - - $PendingUpdates = Get-IcingaUpdatesPending; - - $UpdateCount = New-IcingaCheckPackage -Name 'Pending Update Count' -OperatorAnd; - $UpdateList = New-IcingaCheckPackage -Name 'Update List' -OperatorAnd; - $PendingCount = 0; - - if ($UpdateFilter.Count -ne 0) { - foreach ($Filter in $UpdateFilter) { - foreach ($Update in $PendingUpdates.updates.Keys) { - if ($Update -Like $Filter) { - $PendingCount += 1; - $UpdateList.AddCheck( - (New-IcingaCheck -Name $Update -Value 'pending' -NoPerfData) - ); - } - } - } - if ($PendingCount -eq 0) { - $UpdateList.AddCheck( - (New-IcingaCheck -Name 'No update' -Value 'pending' -NoPerfData) - ); - } - } else { - $PendingCount = $PendingUpdates.count; - foreach ($Update in $PendingUpdates.updates.Keys) { - $UpdateList.AddCheck( - (New-IcingaCheck -Name $Update -Value 'pending' -NoPerfData) - ); - } - } - - $IcingaCheck = New-IcingaCheck -Name 'Pending Update Count' -Value $PendingCount; - $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; - $UpdateCount.AddCheck($IcingaCheck); - - $UpdatePackage = New-IcingaCheckPackage -Name 'Windows Updates' -OperatorAnd -Verbose $Verbosity -Checks @( - $UpdateCount - ); - - if ($PendingCount -ne 0) { - $UpdatePackage.AddCheck($UpdateList); - } - - return (New-IcingaCheckResult -Name 'Pending Updates' -Check $UpdatePackage -NoPerfData $NoPerfData -Compile); -} diff --git a/lib/plugins/Invoke-IcingaCheckUptime.psm1 b/lib/plugins/Invoke-IcingaCheckUptime.psm1 deleted file mode 100644 index 591a0c9..0000000 --- a/lib/plugins/Invoke-IcingaCheckUptime.psm1 +++ /dev/null @@ -1,57 +0,0 @@ -Import-IcingaLib icinga\plugin; -Import-IcingaLib provider\windows; -Import-IcingaLib core\tools; - -<# -.SYNOPSIS - Checks how long a Windows system has been up for. -.DESCRIPTION - InvokeIcingaCheckUptime returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. - e.g 'C:\Users\Icinga\Backup' the system has been running for 10 days, WARNING is set to 15d, CRITICAL is set to 30d. In this case the check will return OK. - More Information on https://github.com/Icinga/icinga-powershell-framework -.FUNCTIONALITY - This module is intended to check how long a Windows system has been up for. - Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. -.EXAMPLE - PS> Invoke-IcingaCheckUptime -Warning 18d -Critical 20d - [WARNING]: Check package "Windows Uptime: Days: 19 Hours: 13 Minutes: 48 Seconds: 29" is [WARNING] - | 'Windows Uptime'=1691309,539176s;1555200;1728000 -.PARAMETER Warning - Used to specify a Warning threshold. In this case a string. - Allowed units include: ms, s, m, h, d, w, M, y -.PARAMETER Critical - Used to specify a Critical threshold. In this case a string. - Allowed units include: ms, s, m, h, d, w, M, y -.INPUTS - System.String -.OUTPUTS - System.String -.LINK - https://github.com/Icinga/icinga-powershell-framework -.NOTES -#> - -function Invoke-IcingaCheckUptime() -{ - param( - [string]$Warning = $null, - [string]$Critical = $null, - [switch]$NoPerfData, - [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 - ); - - $WindowsData = Get-IcingaWindows; - $Name = ([string]::Format('System Uptime: {0}', (ConvertFrom-TimeSpan -Seconds $WindowsData.windows.metadata.uptime.value))); - - $IcingaCheck = New-IcingaCheck -Name 'System Uptime' -Value $WindowsData.windows.metadata.uptime.value -Unit 's'; - $IcingaCheck.WarnOutOfRange( - (ConvertTo-SecondsFromIcingaThresholds -Threshold $Warning) - ).CritOutOfRange( - (ConvertTo-SecondsFromIcingaThresholds -Threshold $Critical) - ) | Out-Null; - - $CheckPackage = New-IcingaCheckPackage -Name $Name -OperatorAnd -Checks $IcingaCheck -Verbose $Verbosity; - - return (New-IcingaCheckresult -Check $CheckPackage -NoPerfData $NoPerfData -Compile); -} diff --git a/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 b/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 deleted file mode 100644 index 7ee2f0f..0000000 --- a/lib/plugins/Invoke-IcingaCheckUsedPartitionSpace.psm1 +++ /dev/null @@ -1,82 +0,0 @@ -Import-IcingaLib core\perfcounter; -Import-IcingaLib icinga\plugin; - -<# -.SYNOPSIS - Checks how much space on a partition is used. -.DESCRIPTION - Invoke-IcingaCheckUsedPartition returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. - e.g 'C:' is at 8% usage, WARNING is set to 60, CRITICAL is set to 80. In this case the check will return OK. - More Information on https://github.com/Icinga/icinga-powershell-framework -.FUNCTIONALITY - This module is intended to be used to check how much usage there is on an partition. - Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. -.EXAMPLE - PS>Invoke-IcingaCheckUsedPartitionSpace -Warning 60 -Critical 80 - [OK]: Check package "Used Partition Space" is [OK] - | 'Partition C'=8,06204986572266%;60;;0;100 'Partition D'=12,06204736572266%;60;;0;100 'Partition K'=19,062047896572266%;60;;0;100 -.EXAMPLE - PS>Invoke-IcingaCheckUsedPartitionSpace -Warning 60 -Critical 80 -Exclude "C:\" - [OK]: Check package "Used Partition Space" is [OK] - | 'Partition D'=12,06204736572266%;60;;0;100 'Partition K'=19,062047896572266%;60;;0;100 -.EXAMPLE - PS>Invoke-IcingaCheckUsedPartitionSpace -Warning 60 -Critical 80 -Include "C:\" - [OK]: Check package "Used Partition Space" is [OK] - | 'Partition C'=8,06204986572266%;60;;0;100 -.PARAMETER Warning - Used to specify a Warning threshold. In this case an integer value. -.PARAMETER Critical - Used to specify a Critical threshold. In this case an integer value. -.PARAMETER Exclude - Used to specify an array of partitions to be excluded. - e.g. 'C:\','D:\' -.PARAMETER Include - Used to specify an array of partitions to be included. - e.g. 'C:\','D:\' -.INPUTS - System.String -.OUTPUTS - System.String -.LINK - https://github.com/Icinga/icinga-powershell-framework -.NOTES -#> - -function Invoke-IcingaCheckUsedPartitionSpace() -{ - param( - $Warning = $null, - $Critical = $null, - [array]$Include = @(), - [array]$Exclude = @(), - [switch]$NoPerfData, - [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 - ); - - $DiskFree = Get-IcingaDiskPartitions; - $DiskPackage = New-IcingaCheckPackage -Name 'Used Partition Space' -OperatorAnd -Verbos $Verbosity; - - foreach ($Letter in $DiskFree.Keys) { - if ($Include.Count -ne 0) { - $Include = $Include.trim(' :/\'); - if (-Not ($Include.Contains($Letter))) { - continue; - } - } - - - if ($Exclude.Count -ne 0) { - $Exclude = $Exclude.trim(' :/\'); - if ($Exclude.Contains($Letter)) { - continue; - } - } - - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Partition {0}', $Letter)) -Value (100-($DiskFree.([string]::Format($Letter))."Free Space")) -Unit '%'; - $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; - $DiskPackage.AddCheck($IcingaCheck); - } - - return (New-IcingaCheckResult -Check $DiskPackage -NoPerfData $NoPerfData -Compile); -} diff --git a/lib/plugins/Invoke-IcingaCheckUsers.psm1 b/lib/plugins/Invoke-IcingaCheckUsers.psm1 deleted file mode 100644 index feb588e..0000000 --- a/lib/plugins/Invoke-IcingaCheckUsers.psm1 +++ /dev/null @@ -1,75 +0,0 @@ -Import-IcingaLib icinga\plugin; -Import-IcingaLib provider\users; - -<# -.SYNOPSIS - Checks how many files are in a directory. -.DESCRIPTION - Invoke-IcingaCheckDirectory returns either 'OK', 'WARNING' or 'CRITICAL', based on the thresholds set. - e.g 'C:\Users\Icinga\Backup' contains 200 files, WARNING is set to 150, CRITICAL is set to 300. In this case the check will return CRITICAL - More Information on https://github.com/Icinga/icinga-powershell-framework -.FUNCTIONALITY - This module is intended to be used to check how many files and directories are within are specified path. - Based on the thresholds set the status will change between 'OK', 'WARNING' or 'CRITICAL'. The function will return one of these given codes. - -.EXAMPLE - PS> -.EXAMPLE - PS> -.PARAMETER Warning - Used to specify a Warning threshold. In this case an integer value. -.PARAMETER Critical - Used to specify a Critical threshold. In this case an integer value. -.PARAMETER Username - Used to specify an array of usernames to match against. - - e.g 'Administrator', 'Icinga' -.INPUTS - System.String -.OUTPUTS - System.String -.LINK - https://github.com/Icinga/icinga-powershell-framework -.NOTES -#> - -function Invoke-IcingaCheckUsers() -{ - param ( - [array]$Username, - $Warning = $null, - $Critical = $null, - [switch]$NoPerfData, - [ValidateSet(0, 1, 2, 3)] - [int]$Verbosity = 0 - ); - - $UsersPackage = New-IcingaCheckPackage -Name 'Users' -OperatorAnd -Verbose $Verbosity; - $LoggedOnUsers = Get-IcingaLoggedOnUsers -UserFilter $Username; - - if ($Username.Count -ne 0) { - foreach ($User in $Username) { - $IcingaCheck = $null; - [int]$LoginCount = 0; - - if ($LoggedOnUsers.users.ContainsKey($User)) { - $LoginCount = $LoggedOnUsers.users.$User.count; - } - - $IcingaCheck = New-IcingaCheck -Name ([string]::Format('Logged On Users "{0}"', $User)) -Value $LoginCount; - $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; - $UsersPackage.AddCheck($IcingaCheck); - } - } else { - foreach ($User in $LoggedOnUsers.users.Keys) { - $UsersPackage.AddCheck( - (New-IcingaCheck -Name ([string]::Format('Logged On Users "{0}"', $User)) -Value $LoggedOnUsers.users.$User.count) - ); - } - $IcingaCheck = New-IcingaCheck -Name 'Logged On Users' -Value $LoggedOnUsers.count; - $IcingaCheck.WarnOutOfRange($Warning).CritOutOfRange($Critical) | Out-Null; - $UsersPackage.AddCheck($IcingaCheck) - } - - return (New-IcingaCheckResult -Name 'Users' -Check $UsersPackage -NoPerfData $NoPerfData -Compile); -} diff --git a/lib/provider/bios/Icinga_ProviderBios.psm1 b/lib/provider/bios/Icinga_ProviderBios.psm1 deleted file mode 100644 index 76e6a73..0000000 --- a/lib/provider/bios/Icinga_ProviderBios.psm1 +++ /dev/null @@ -1,125 +0,0 @@ -Import-IcingaLib provider\enums; -function Get-IcingaBios() -{ - <# Collects the most important BIOS informations, - e.g. name, version, manufacturer#> - $BIOSInformation = Get-CimInstance Win32_BIOS; - [hashtable]$BIOSCharacteristics = @{}; - [hashtable]$BIOSData = @{}; - - foreach ($id in $BIOSInformation.BiosCharacteristics) { - $BIOSCharacteristics.Add([string]$id, $ProviderEnums.BiosCharacteristics.Item([int]$id)); - } - - $BIOSData.Add( - 'bios', @{ - 'metadata' = @{ - 'Name' = $BIOSInformation.Name; - 'Caption' = $BIOSInformation.Caption; - 'Manufacturer' = $BIOSInformation.Manufacturer; - 'PrimaryBIOS' = $BIOSInformation.PrimaryBIOS; - 'SerialNumber' = $BIOSInformation.SerialNumber; - 'SMBIOSBIOSVersion' = $BIOSInformation.SMBIOSBIOSVersion; - 'SoftwareElementID' = $BIOSInformation.SoftwareElementID; - 'Status' = $BIOSInformation.Status; - 'Version' = $BIOSInformation.Version; - 'BiosCharacteristics' = $BIOSCharacteristics; - } - } - ); - return $BIOSData; - } - - -function Get-IcingaBiosCharacteristics() -{ - param([switch]$Sorted); - - $bios = Get-CimInstance WIN32_BIOS; - [hashtable]$BIOSCharacteristics = @{}; - - foreach ($id in $bios.BiosCharacteristics) { - $BIOSCharacteristics.Add([string]$id, $ProviderEnums.BiosCharacteristics.Item([int]$id)); - } - - $output = $BIOSCharacteristics; - - if ($sorted) { - $output = $BIOSCharacteristics.GetEnumerator() | Sort-Object name; - } - - return @{'value' = $output; 'name' = 'BiosCharacteristics'}; -} -function Get-IcingaBiosCharacteristics() -{ - param([switch]$Sorted); - - $bios = Get-CimInstance WIN32_BIOS; - [hashtable]$BIOSCharacteristics = @{}; - - foreach ($id in $bios.BiosCharacteristics) { - $BIOSCharacteristics.Add([string]$id, $ProviderEnums.BiosCharacteristics.Item([int]$id)); - } - - $output = $BIOSCharacteristics; - - if ($sorted) { - $output = $BIOSCharacteristics.GetEnumerator() | Sort-Object name; - } - - return @{'value' = $output; 'name' = 'BiosCharacteristics'}; -} -function Get-IcingaBiosSerialNumber() -{ - $bios = Get-CimInstance Win32_BIOS; - return @{'value' = $bios.SerialNumber; 'name' = 'SerialNumber'}; -} - -function Get-IcingaBiosVersion() -{ - $bios = Get-CimInstance Win32_BIOS; - return @{'value' = $bios.Version; 'name' = 'Version'}; -} - -function Get-IcingaBiosManufacturer() -{ - $bios = Get-CimInstance Win32_BIOS; - return @{'value' = $bios.Manufacturer; 'name' = 'Manufacturer'}; -} - -# Primary Bios might be more relevant in dual bios context -function Get-IcingaBiosPrimaryBios() -{ - $bios = Get-CimInstance Win32_BIOS; - return @{'value' = $bios.PrimaryBIOS; 'name' = 'PrimaryBIOS'}; -} - -function Get-IcingaBiosName() -{ - $bios = Get-CimInstance Win32_BIOS; - return @{'value' = $bios.Name; 'name' = 'Name'}; -} - -function Get-IcingaBiosStatus() -{ - $bios = Get-CimInstance Win32_BIOS; - return @{'value' = $bios.Status; 'name' = 'Status'}; -} - -function Get-IcingaBiosCaption() -{ - $bios = Get-CimInstance Win32_BIOS; - return @{'value' = $bios.Caption; 'name' = 'Caption'}; -} - -function Get-IcingaBiosSMBIOSBIOSVersion() -{ - $bios = Get-CimInstance Win32_BIOS; - return @{'value' = $bios.SMBIOSBIOSVersion; 'name' = 'SMBIOSBIOSVersion'}; -} - -function Get-IcingaBiosSoftwareElementID() -{ - $bios = Get-CimInstance Win32_BIOS; - return @{'value' = $bios.SoftwareElementID; 'name' = 'SoftwareElementID'}; -} \ No newline at end of file diff --git a/lib/provider/bios/Show-IcingaBiosData.psm1 b/lib/provider/bios/Show-IcingaBiosData.psm1 deleted file mode 100644 index 087c461..0000000 --- a/lib/provider/bios/Show-IcingaBiosData.psm1 +++ /dev/null @@ -1,13 +0,0 @@ -function Show-IcingaBiosData() -{ - $BIOSInformation = Get-CimInstance Win32_BIOS; - [hashtable]$BIOSData = @{}; - - foreach ($bios_properties in $BIOSInformation) { - foreach($bios in $bios_properties.CimInstanceProperties) { - $BIOSData.Add($bios.Name, $bios.Value); - } - } - - return $BIOSData; -} \ No newline at end of file diff --git a/lib/provider/cpu/Icinga_ProviderCpu.psm1 b/lib/provider/cpu/Icinga_ProviderCpu.psm1 deleted file mode 100644 index 6dac6c8..0000000 --- a/lib/provider/cpu/Icinga_ProviderCpu.psm1 +++ /dev/null @@ -1,279 +0,0 @@ -Import-IcingaLib provider\enums; -function Get-IcingaCPUs() -{ - <# Collects the most important CPU informations, - e.g. name, version, manufacturer#> - $CPUInformation = Get-CimInstance Win32_Processor; - [hashtable]$CPUData = @{}; - - foreach ($cpu in $CPUInformation) { - - $CPUData.Add( - $cpu.DeviceID.trim('CPU'), @{ - 'metadata' = @{ - 'Name' = $cpu.Name; - 'DeviceID' = $cpu.DeviceID; - 'ProcessorID' = $cpu.ProcessorId; - 'UniqueID' = $cpu.UniqueId; - 'Description' = $cpu.Description; - 'OtherFamilyDescription' = $cpu.OtherFamilyDescription; - 'Caption' = $cpu.Caption; - 'Version' = $cpu.Version; - 'SerialNumber' = $cpu.SerialNumber; - 'Manufacturer' = $cpu.Manufacturer; - 'NumberOfCores' = $cpu.NumberOfCores; - 'PartNumber' = $cpu.PartNumber; - 'Status' = $cpu.Status; - 'CPUStatus' = $cpu.CpuStatus; - 'Revision' = $cpu.Revision; - 'NumberOfLogicalProcessors' = $cpu.NumberOfLogicalProcessors; - 'Level'= $cpu.Level; - 'AddressWidth' = $cpu.AddressWidth; - 'Stepping' = $cpu.Stepping; - 'SocketDesignation' = $cpu.SocketDesignation; - 'Family' = @{ - 'raw' = $cpu.Family; - 'value' = $ProviderEnums.CPUFamily[[int]$cpu.Family]; - }; - 'Architecture' = @{ - 'raw' = $cpu.Architecture; - 'value' = $ProviderEnums.CPUArchitecture[[int]$cpu.Architecture]; - }; - 'ProcessorType' = @{ - 'raw' = $cpu.ProcessorType; - 'value' = $ProviderEnums.CPUProcessorType[[int]$cpu.ProcessorType]; - }; - 'StatusInfo' = @{ - 'raw' = $cpu.StatusInfo; - 'value' = $ProviderEnums.CPUStatusInfo[[int]$cpu.StatusInfo]; - }; - 'Availability' = @{ - 'raw' = $cpu.Availability; - 'value' = $ProviderEnums.CPUAvailability[[int]$cpu.Availability]; - }; - 'PowerManagementCapabilities' = @{ - 'raw' = $cpu.PowerManagementCapabilities; - 'value' = $ProviderEnums.CPUPowerManagementCapabilities[[int]$cpu.PowerManagementCapabilities]; - } - }; - 'errors' = @{ - 'LastErrorCode' = $cpu.LastErrorCode; - 'ErrorCleared' = $cpu.ErrorCleared; - 'ErrorDescription' = $cpu.ErrorDescription; - 'ConfigManagerErrorCode' = @{ - 'raw' = [int]$cpu.ConfigManagerErrorCode; - 'value' = $ProviderEnums.CPUConfigManagerErrorCode.([int]$cpu.ConfigManagerErrorCode); - } - }; - 'specs' = @{ - 'LoadPercentage' = $cpu.LoadPercentage; - 'CurrentVoltage' = $cpu.CurrentVoltage; - 'ThreadCount' = $cpu.ThreadCount; - 'L3CacheSize' = $cpu.L3CacheSize; - 'L2CacheSpeed' = $cpu.L2CacheSpeed; - 'L2CacheSize' = $cpu.L2CacheSize; - 'VoltageCaps' = $cpu.VoltageCaps; - 'CurrentClockSpeed' = $cpu.CurrentClockSpeed; - } - } - ); - } - return $CPUData; -} - -function Get-IcingaCPUInformation() -{ - <# Fetches the information for other more specific Get-IcingaCPU-functions - e.g. Get-IcingaCPUThreadCount; Get-IcingaCPULoadPercentage. - Can be used to fetch information regarding a value of your choice. #> - param( - [string]$Parameter - ); - $CPUInformation = Get-CimInstance Win32_Processor; - [hashtable]$CPUData = @{}; - - foreach ($cpu in $CPUInformation) { - $CPUData.Add($cpu.DeviceID.trim('CPU'), $cpu.$Parameter); - } - - return $CPUData; -} - -function Get-IcingaCPUInformationWithEnums() -{ <# Fetches the information of other more specific Get-IcingaCPU-functions, - which require a enums key-value pair to resolve their code - e.g Get-IcingaCPUFamily, e.g. Get-IcingaCPUArchitecture#> - param( - [string]$Parameter - ); - - $CPUInformation = Get-CimInstance Win32_Processor; - $Prefix = "CPU"; - - [hashtable]$CPUData = @{}; - - foreach ($cpu in $CPUInformation) { - $CPUData.Add( - $cpu.DeviceID.trim('CPU'), @{ - 'raw' = $cpu.$Parameter; - 'value' = $ProviderEnums."$Prefix$Parameter"[[int]$cpu.$Parameter] - } - ); - } - return $CPUData; -} - -function Get-IcingaCPUErrors() -{ - $CPUInformation = Get-CimInstance Win32_Processor; - [hashtable]$CPUData = @{}; - - foreach ($cpu in $CPUInformation) { - $CPUData.Add( - $cpu.trim('CPU'), @{ - 'errors' = @{ - 'LastErrorCode' = $cpu.LastErrorCode; - 'ErrorCleared' = $cpu.ErrorCleared; - 'ErrorDescription' = $cpu.ErrorDescription; - 'ConfigManagerErrorCode' = @{ - 'raw' = [int]$cpu.ConfigManagerErrorCode; - 'value' = $ProviderEnums.CPUConfigManagerErrorCode.([int]$cpu.ConfigManagerErrorCode); - } - } - } - ); - } - return $CPUData; -} - -function Get-IcingaCPUArchitecture() -{ - $CPUArchitecture = Get-IcingaCPUInformationWithEnums -Parameter Architecture; - - return @{'value' = $CPUArchitecture; 'name' = 'Architecture'}; -} - -function Get-IcingaCPUProcessorType() -{ - $CPUProcessorType = Get-IcingaCPUInformationWithEnums -Parameter ProcessorType; - - return @{'value' = $CPUProcessorType; 'name' = 'ProcessorType'}; -} - -function Get-IcingaCPUStatusInfo() -{ - $CPUStatusInfo = Get-IcingaCPUInformationWithEnums -Parameter StatusInfo; - - return @{'value' = $CPUStatusInfo; 'name' = 'StatusInfo'}; -} - -function Get-IcingaCPUFamily() -{ - $CPUFamily = Get-IcingaCPUInformationWithEnums -Parameter Family; - - return @{'value' = $CPUFamily; 'name' = 'Family'}; -} - -function Get-IcingaCPUConfigManagerErrorCode() -{ - $CPUConfigManagerErrorCode = Get-IcingaCPUInformationWithEnums -Parameter ConfigManagerErrorCode; - - return @{'value' = $CPUConfigManagerErrorCode; 'name' = 'ConfigManagerErrorCode'}; -} - -function Get-IcingaCPUAvailability() -{ - $CPUAvailability = Get-IcingaCPUInformationWithEnums -Parameter Availability; - - return @{'value' = $CPUAvailability; 'name' = 'Availability'}; -} - -function Get-IcingaCPUPowerManagementCapabilities() -{ - $CPUPowerManagementCapabilities = Get-IcingaCPUInformationWithEnums -Parameter PowerManagementCapabilities; - - return @{'value' = $CPUPowerManagementCapabilities; 'name' = 'PowerManagementCapabilities'}; -} - -function Get-IcingaCPULoadPercentage() -{ - $CPULoadPercentage = Get-IcingaCPUInformation -Parameter LoadPercentage; - - return @{'value' = $CPULoadPercentage; 'name' = 'LoadPercentage'}; -} - -function Get-IcingaCPUCurrentVoltage() -{ - $CPUCurrentVoltage = Get-IcingaCPUInformation -Parameter CurrentVoltage; - - return @{'value' = $CPUCurrentVoltage; 'name' = 'CurrentVoltage'}; -} - -function Get-IcingaCPUThreadCount() -{ - $CPUThreadCount = Get-IcingaCPUInformation -Parameter ThreadCount; - - return @{'value' = $CPUThreadCount; 'name' = 'ThreadCount'}; -} - -function Get-IcingaCPUL3CacheSize() -{ - $CPUL3CacheSize = Get-IcingaCPUInformation -Parameter L3CacheSize; - - return @{'value' = $CPUL3CacheSize; 'name' = 'L3CacheSize'}; -} - -function Get-IcingaCPUL2CacheSize() -{ - $CPUL2CacheSize = Get-IcingaCPUInformation -Parameter L2CacheSize; - - return @{'value' = $CPUL2CacheSize; 'name' = 'L2CacheSize'}; -} - -function Get-IcingaCPUL2CacheSpeed() -{ - $CPUL2CacheSpeed = Get-IcingaCPUInformation -Parameter L2CacheSpeed; - - return @{'value' = $CPUL2CacheSpeed; 'name' = 'L2CacheSpeed'}; -} - -function Get-IcingaCPUVoltageCaps() -{ - $CPUVoltageCaps = Get-IcingaCPUInformation -Parameter VoltageCaps; - - return @{'value' = $CPUVoltageCaps; 'name' = 'VoltageCaps'}; -} - -function Get-IcingaCPUCurrentClockSpeed() -{ - $CPUCurrentClockSpeed = Get-IcingaCPUInformation -Parameter CurrentClockSpeed; - - return @{'value' = $CPUCurrentClockSpeed; 'name' = 'CurrentClockSpeed'}; -} - -function Get-IcingaCPUNumberOfLogicalProcessors() -{ - $CPUNumberOfLogicalProcessors = Get-IcingaCPUInformation -Parameter NumberOfLogicalProcessors; - - return @{'value' = $CPUNumberOfLogicalProcessors; 'name' = 'NumberOfLogicalProcessors'}; -} - -function Get-IcingaCPUCount() -{ - <# Compares whether NumberofLogicalCores, NumberofCores or Threadcount across all CPUs is the highest, - this function is used in provider/memory/Icinga_ProviderMemory.psm1#> - $CPUInformation = Get-CimInstance Win32_Processor; - - foreach ($cpu in $CPUInformation) { - $NumberOfCoresValue += $cpu.NumberOfCores; - $NumberOfLogicalProcessorsValue += $cpu.NumberOfLogicalProcessors; - $ThreadCountValue += $cpu.ThreadCount; - } - - If (($NumberOfCoresValue -ge $NumberOfLogicalProcessorsValue) -and ($NumberOfCoresValue -ge $ThreadCountValue)) { - return $NumberOfCoresValue; - } elseif ($NumberOfLogicalProcessorsValue -ge $ThreadCountValue) { - return $NumberOfLogicalProcessorsValue; - } - return $ThreadCountValue; -} \ No newline at end of file diff --git a/lib/provider/cpu/Show-IcingaCPUData.psm1 b/lib/provider/cpu/Show-IcingaCPUData.psm1 deleted file mode 100644 index 651a595..0000000 --- a/lib/provider/cpu/Show-IcingaCPUData.psm1 +++ /dev/null @@ -1,16 +0,0 @@ -function Show-IcingaCPUData() -{ - -$CPUInformation = Get-CimInstance Win32_Processor; -[hashtable]$PhysicalCPUData = @{}; - -foreach ($cpu_properties in $CPUInformation) { - $cpu_datails = @{}; - foreach($cpu_core in $cpu_properties.CimInstanceProperties) { - $cpu_datails.Add($cpu_core.Name, $cpu_core.Value); - } - $PhysicalCPUData.Add($cpu_datails.DeviceID, $cpu_datails); -} - -return $PhysicalCPUData; -} \ No newline at end of file diff --git a/lib/provider/directory/Icinga_Provider_Directory.psm1 b/lib/provider/directory/Icinga_Provider_Directory.psm1 deleted file mode 100644 index f33af95..0000000 --- a/lib/provider/directory/Icinga_Provider_Directory.psm1 +++ /dev/null @@ -1,187 +0,0 @@ -Import-IcingaLib core\tools; - -function Get-IcingaDirectoryAll() -{ - param( - [string]$Path, - [array]$FileNames, - [bool]$Recurse, - [string]$ChangeTimeEqual, - [string]$ChangeYoungerThan, - [string]$ChangeOlderThan, - [string]$CreationTimeEqual, - [string]$CreationOlderThan, - [string]$CreationYoungerThan, - [string]$FileSizeGreaterThan, - [string]$FileSizeSmallerThan - ); - - if ($Recurse -eq $TRUE) { - $DirectoryData = Get-IcingaDirectoryRecurse -Path $Path -FileNames $FileNames; - } else { - $DirectoryData = Get-IcingaDirectory -Path $Path -FileNames $FileNames; - } - - if ([string]::IsNullOrEmpty($ChangeTimeEqual) -eq $FALSE) { - $DirectoryData = Get-IcingaDirectoryChangeTimeEqual -ChangeTimeEqual $ChangeTimeEqual -DirectoryData $DirectoryData; - } - - if ([string]::IsNullOrEmpty($CreationTimeEqual) -eq $FALSE) { - $DirectoryData = Get-IcingaDirectoryCreationTimeEqual -CreationTimeEqual $CreationTimeEqual -DirectoryData $DirectoryData; - } - - If ([string]::IsNullOrEmpty($ChangeTimeEqual) -eq $TRUE -Or [string]::IsNullOrEmpty($CreationTimeEqual) -eq $TRUE) { - if ([string]::IsNullOrEmpty($ChangeOlderThan) -eq $FALSE) { - $DirectoryData = Get-IcingaDirectoryChangeOlderThan -ChangeOlderThan $ChangeOlderThan -DirectoryData $DirectoryData; - } - if ([string]::IsNullOrEmpty($ChangeYoungerThan) -eq $FALSE) { - $DirectoryData = Get-IcingaDirectoryChangeYoungerThan -ChangeYoungerThan $ChangeYoungerThan -DirectoryData $DirectoryData; - } - if ([string]::IsNullOrEmpty($CreationOlderThan) -eq $FALSE) { - $DirectoryData = Get-IcingaDirectoryCreationOlderThan -CreationOlderThan $CreationOlderThan -DirectoryData $DirectoryData; - } - if ([string]::IsNullOrEmpty($CreationYoungerThan) -eq $FALSE) { - $DirectoryData = Get-IcingaDirectoryCreationYoungerThan -CreationYoungerThan $CreationYoungerThan -DirectoryData $DirectoryData; - } - } - if ([string]::IsNullOrEmpty($FileSizeGreaterThan) -eq $FALSE) { - $DirectoryData = (Get-IcingaDirectorySizeGreaterThan -FileSizeGreaterThan $FileSizeGreaterThan -DirectoryData $DirectoryData); - } - if ([string]::IsNullOrEmpty($FileSizeSmallerThan) -eq $FALSE) { - $DirectoryData = (Get-IcingaDirectorySizeSmallerThan -FileSizeSmallerThan $FileSizeSmallerThan -DirectoryData $DirectoryData); - } - - return $DirectoryData; -} - - - -# RECURSE - -function Get-IcingaDirectory() -{ - param( - [string]$Path, - [array]$FileNames - ); - - $DirectoryData = Get-ChildItem -Include $FileNames -Path $Path; - - return $DirectoryData; -} - -function Get-IcingaDirectoryRecurse() -{ - param( - [string]$Path, - [array]$FileNames - ); - - $DirectoryData = Get-ChildItem -Recurse -Include $FileNames -Path $Path; - - return $DirectoryData; -} - -# FILE SIZE - -function Get-IcingaDirectorySizeGreaterThan() -{ - param( - [string]$FileSizeGreaterThan, - $DirectoryData - ); - $FileSizeGreaterThanValue = (Convert-Bytes $FileSizeGreaterThan -Unit B).value - $DirectoryData = ($DirectoryData | Where-Object {$_.Length -gt $FileSizeGreaterThanValue}) - - return $DirectoryData; -} - -function Get-IcingaDirectorySizeSmallerThan() -{ - param( - [string]$FileSizeSmallerThan, - $DirectoryData - ); - $FileSizeSmallerThanValue = (Convert-Bytes $FileSizeSmallerThan -Unit B).value - $DirectoryData = ($DirectoryData | Where-Object {$_.Length -gt $FileSizeSmallerThanValue}) - - return $DirectoryData; -} - -# TIME BASED CHANGE - -function Get-IcingaDirectoryChangeOlderThan() -{ - param ( - [string]$ChangeOlderThan, - $DirectoryData - ) - $ChangeOlderThan = Set-NumericNegative (ConvertTo-Seconds $ChangeOlderThan); - $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -lt (Get-Date).AddSeconds($ChangeOlderThan)}) - - return $DirectoryData; -} - -function Get-IcingaDirectoryChangeYoungerThan() -{ - param ( - [string]$ChangeYoungerThan, - $DirectoryData - ) - $ChangeYoungerThan = Set-NumericNegative (ConvertTo-Seconds $ChangeYoungerThan); - $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime -gt (Get-Date).AddSeconds($ChangeYoungerThan)}) - - return $DirectoryData; -} - -function Get-IcingaDirectoryChangeTimeEqual() -{ - param ( - [string]$ChangeTimeEqual, - $DirectoryData - ) - $ChangeTimeEqual = Set-NumericNegative (ConvertTo-Seconds $ChangeTimeEqual); - $ChangeTimeEqual = (Get-Date).AddSeconds($ChangeTimeEqual); - $DirectoryData = ($DirectoryData | Where-Object {$_.LastWriteTime.Day -eq $ChangeTimeEqual.Day -And $_.LastWriteTime.Month -eq $ChangeTimeEqual.Month -And $_.LastWriteTime.Year -eq $ChangeTimeEqual.Year}) - - return $DirectoryData; -} - -# TIME BASED CREATION - -function Get-IcingaDirectoryCreationYoungerThan() -{ - param ( - [string]$CreationYoungerThan, - $DirectoryData - ) - $CreationYoungerThan = Set-NumericNegative (ConvertTo-Seconds $CreationYoungerThan); - $DirectoryData = ($DirectoryData | Where-Object {$_.CreationTime -gt (Get-Date).AddSeconds($CreationYoungerThan)}) - - return $DirectoryData; -} - -function Get-IcingaDirectoryCreationOlderThan() -{ - param ( - [string]$CreationOlderThan, - $DirectoryData - ) - $CreationOlderThan = Set-NumericNegative (ConvertTo-Seconds $CreationOlderThan); - $DirectoryData = ($DirectoryData | Where-Object {$_.CreationTime -lt (Get-Date).AddSeconds($CreationOlderThan)}) - - return $DirectoryData; -} - -function Get-IcingaDirectoryCreationTimeEqual() -{ - param ( - [string]$CreationTimeEqual, - $DirectoryData - ) - $CreationTimeEqual = Set-NumericNegative (ConvertTo-Seconds $CreationTimeEqual); - $CreationTimeEqual = (Get-Date).AddSeconds($CreationTimeEqual); - $DirectoryData = ($DirectoryData | Where-Object {$_.CreationTime.Day -eq $CreationTimeEqual.Day -And $_.CreationTime.Month -eq $CreationTimeEqual.Month -And $_.CreationTime.Year -eq $CreationTimeEqual.Year}) - - return $DirectoryData; -} \ No newline at end of file diff --git a/lib/provider/disks/Icinga_ProviderDisks.psm1 b/lib/provider/disks/Icinga_ProviderDisks.psm1 deleted file mode 100644 index c1fb3b1..0000000 --- a/lib/provider/disks/Icinga_ProviderDisks.psm1 +++ /dev/null @@ -1,146 +0,0 @@ -Import-IcingaLib provider\enums; - -function Get-IcingaDiskInformation() -{ - <# Fetches the information for other more specific Get-IcingaDisk-functions - e.g. Get-IcingaDiskModel; Get-IcingaDiskManufacturer. - Can be used to fetch information regarding a value of your choice. #> - param( - # The value to fetch from Win32_DiskDrive - [string]$Parameter - ); - $DiskInformation = Get-CimInstance Win32_DiskDrive; - [hashtable]$DiskData = @{}; - - foreach ($disk in $DiskInformation) { - $DiskData.Add($disk.DeviceID.trimstart(".\PHYSICALDRVE"), $disk.$Parameter); - } - - return $DiskData; -} -function Get-IcingaDiskPartitions() -{ - param( - $Disk - ); - <# Fetches all the most important informations regarding partitions - e.g. physical disk; partition, size - , also collects partition information for Get-IcingaDisks #> - $LogicalDiskInfo = Get-WmiObject Win32_LogicalDiskToPartition; - [hashtable]$PartitionDiskByDriveLetter = @{}; - - foreach ($item in $LogicalDiskInfo) { - [string]$driveLetter = $item.Dependent.SubString( - $item.Dependent.LastIndexOf('=') + 1, - $item.Dependent.Length - $item.Dependent.LastIndexOf('=') - 1 - ); - $driveLetter = $driveLetter.Replace('"', '').trim(':'); - - [string]$diskPartition = $item.Antecedent.SubString( - $item.Antecedent.LastIndexOf('=') + 1, - $item.Antecedent.Length - $item.Antecedent.LastIndexOf('=') - 1 - ) - $diskPartition = $diskPartition.Replace('"', ''); - $diskDisk,$diskPartition = $diskPartition.split(','); - - $diskPartition = $diskPartition.trim("Partition #"); - $diskDisk = $diskDisk.trim("Disk #"); - - If ([string]::IsNullOrEmpty($Disk) -eq $FALSE) { - If ([int]$Disk -ne [int]$diskDisk) { - continue; - } - } - - $DiskArray = New-IcingaPerformanceCounterStructure -CounterCategory 'LogicalDisk' -PerformanceCounterHash (New-IcingaPerformanceCounterArray @('\LogicalDisk(*)\% free space')); - - $diskPartitionSize = Get-Partition -DriveLetter $driveLetter; - - $PartitionDiskByDriveLetter.Add( - $driveLetter, - @{ - 'Disk' = $diskDisk; - 'Partition' = $diskPartition; - 'Size' = $diskPartitionSize.Size; - 'Free Space' = $DiskArray.Item([string]::Format('{0}:', $driveLetter))."% free space".value; - } - ); - } - return $PartitionDiskByDriveLetter; -} - -function Get-IcingaDiskCapabilities -{ - $DiskInformation = Get-CimInstance Win32_DiskDrive; - [hashtable]$DiskCapabilities = @{}; - - foreach ($capabilities in $DiskInformation.Capabilities) { - $DiskCapabilities.Add([int]$capabilities, $ProviderEnums.DiskCapabilities.([int]$capabilities)); - } - return @{'value' = $DiskCapabilities; 'name' = 'Capabilities'}; - -} -function Get-IcingaDiskSize -{ - $DiskSize = Get-IcingaDiskInformation -Parameter Size; - - return @{'value' = $DiskSize; 'name' = 'Size'}; -} - -function Get-IcingaDiskCaption -{ - $DiskCaption = Get-IcingaDiskInformation -Parameter Caption; - - return @{'value' = $DiskCaption; 'name' = 'Caption'}; -} - -function Get-IcingaDiskModel -{ - $DiskModel = Get-IcingaDiskInformation -Parameter Model; - return @{'value' = $DiskModel; 'name' = 'Model'}; -} - -function Get-IcingaDiskManufacturer -{ - $DiskManufacturer = Get-IcingaDiskInformation -Parameter Manufacturer; - return @{'value' = $DiskManufacturer; 'name' = 'Manufacturer'}; -} - -function Get-IcingaDiskTotalCylinders -{ - $DiskTotalCylinders = Get-IcingaDiskInformation -Parameter TotalCylinders; - return @{'value' = $DiskTotalCylinders; 'name' = 'TotalCylinders'}; -} - -function Get-IcingaDiskTotalSectors -{ - $DiskTotalSectors = Get-IcingaDiskInformation -Parameter TotalSectors; - return @{'value' = $DiskTotalSectors; 'name' = 'TotalSectors'}; -} - -function Get-IcingaDisks { - <# Collects all the most important Disk-Informations, - e.g. size, model, sectors, cylinders - Is dependent on Get-IcingaDiskPartitions#> - $DiskInformation = Get-CimInstance Win32_DiskDrive; - [hashtable]$DiskData = @{}; - - foreach ($disk in $DiskInformation) { - $diskID = $disk.DeviceID.trimstart(".\PHYSICALDRVE"); - $DiskData.Add( - $diskID, @{ - 'metadata' = @{ - 'Size' = $disk.Size; - 'Model' = $disk.Model; - 'Name' = $disk.Name.trim('.\'); - 'Manufacturer' = $disk.Manufacturer; - 'Cylinder' = $disk.TotalCylinders; - 'Sectors' = $disk.TotalSectors - }; - 'partitions' = (Get-IcingaDiskPartitions -Disk $diskID); - } - ); - } - - return $DiskData; -} \ No newline at end of file diff --git a/lib/provider/disks/Show-IcingaDiskData.psm1 b/lib/provider/disks/Show-IcingaDiskData.psm1 deleted file mode 100644 index fab6e5b..0000000 --- a/lib/provider/disks/Show-IcingaDiskData.psm1 +++ /dev/null @@ -1,67 +0,0 @@ -function Show-IcingaDiskData { - - $DisksInformations = Get-CimInstance Win32_DiskDrive; - - [hashtable]$PhysicalDiskData = @{}; - - foreach ($disk_properties in $DisksInformations) { - $disk_datails = @{}; - foreach($disk in $disk_properties.CimInstanceProperties) { - $disk_datails.Add($disk.Name, $disk.Value); - } - $disk_datails.Add('DriveReference', @()); - $PhysicalDiskData.Add($disk_datails.DeviceID, $disk_datails); - } - - $DiskPartitionInfo = Get-WmiObject Win32_DiskDriveToDiskPartition; - - [hashtable]$MapDiskPartitionToLogicalDisk = @{}; - - foreach ($item in $DiskPartitionInfo) { - [string]$diskPartition = $item.Dependent.SubString( - $item.Dependent.LastIndexOf('=') + 1, - $item.Dependent.Length - $item.Dependent.LastIndexOf('=') - 1 - ); - $diskPartition = $diskPartition.Replace('"', ''); - - [string]$physicalDrive = $item.Antecedent.SubString( - $item.Antecedent.LastIndexOf('\') + 1, - $item.Antecedent.Length - $item.Antecedent.LastIndexOf('\') - 1 - ) - $physicalDrive = $physicalDrive.Replace('"', ''); - - $MapDiskPartitionToLogicalDisk.Add($diskPartition, $physicalDrive); - } - - $LogicalDiskInfo = Get-WmiObject Win32_LogicalDiskToPartition; - - foreach ($item in $LogicalDiskInfo) { - [string]$driveLetter = $item.Dependent.SubString( - $item.Dependent.LastIndexOf('=') + 1, - $item.Dependent.Length - $item.Dependent.LastIndexOf('=') - 1 - ); - $driveLetter = $driveLetter.Replace('"', ''); - - [string]$diskPartition = $item.Antecedent.SubString( - $item.Antecedent.LastIndexOf('=') + 1, - $item.Antecedent.Length - $item.Antecedent.LastIndexOf('=') - 1 - ) - $diskPartition = $diskPartition.Replace('"', ''); - - if ($MapDiskPartitionToLogicalDisk.ContainsKey($diskPartition)) { - foreach ($disk in $PhysicalDiskData.Keys) { - [string]$DiskId = $disk.SubString( - $disk.LastIndexOf('\') + 1, - $disk.Length - $disk.LastIndexOf('\') - 1 - ); - - if ($DiskId.ToLower() -eq $MapDiskPartitionToLogicalDisk[$diskPartition].ToLower()) { - $PhysicalDiskData[$disk]['DriveReference'] += $driveLetter; - } - } - } - } - - return $PhysicalDiskData; - -} \ No newline at end of file diff --git a/lib/provider/enums/Icinga_ProviderEnums.psm1 b/lib/provider/enums/Icinga_ProviderEnums.psm1 deleted file mode 100644 index a8850fa..0000000 --- a/lib/provider/enums/Icinga_ProviderEnums.psm1 +++ /dev/null @@ -1,525 +0,0 @@ - -<################################################################################################## -################# /lib/provider/bios ############################################################## -##################################################################################################> - -[hashtable]$BiosCharacteristics = @{ - 0 = 'Reserved'; - 1 = 'Reserved'; - 2 = 'Unknown'; - 3 = 'BIOS Characteristics Not Supported'; - 4 = 'ISA is supported'; - 5 = 'MCA is supported'; - 6 = 'EISA is supported'; - 7 = 'PCI is supported'; - 8 = 'PC Card (PCMCIA) is supported'; - 9 = 'Plug and Play is supported'; - 10 = 'APM is supported'; - 11 = 'BIOS is Upgradeable (Flash)'; - 12 = 'BIOS shadowing is allowed'; - 13 = 'VL-VESA is supported'; - 14 = 'ESCD support is available'; - 15 = 'Boot from CD is supported'; - 16 = 'Selectable Boot is supported'; - 17 = 'BIOS ROM is socketed'; - 18 = 'Boot From PC Card (PCMCIA) is supported'; - 19 = 'EDD (Enhanced Disk Drive) Specification is supported'; - 20 = 'Int 13h - Japanese Floppy for NEC 9800 1.2mb (3.5, 1k Bytes/Sector, 360 RPM) is supported'; - 21 = 'Int 13h - Japanese Floppy for Toshiba 1.2mb (3.5, 360 RPM) is supported'; - 22 = 'Int 13h - 5.25 / 360 KB Floppy Services are supported'; - 23 = 'Int 13h - 5.25 /1.2MB Floppy Services are supported'; - 24 = 'Int 13h - 3.5 / 720 KB Floppy Services are supported'; - 25 = 'Int 13h - 3.5 / 2.88 MB Floppy Services are supported'; - 26 = 'Int 5h, Print Screen Service is supported'; - 27 = 'Int 9h, 8042 Keyboard services are supported'; - 28 = 'Int 14h, Serial Services are supported'; - 29 = 'Int 17h, printer services are supported'; - 30 = 'Int 10h, CGA/Mono Video Services are supported'; - 31 = 'NEC PC-98'; - 32 = 'ACPI is supported'; - 33 = 'USB Legacy is supported'; - 34 = 'AGP is supported'; - 35 = 'I2O boot is supported'; - 36 = 'LS-120 boot is supported'; - 37 = 'ATAPI ZIP Drive boot is supported'; - 38 = '1394 boot is supported'; - 39 = 'Smart Battery is supported'; - 40 = 'Reserved for BIOS vendor'; - 41 = 'Reserved for BIOS vendor'; - 42 = 'Reserved for BIOS vendor'; - 43 = 'Reserved for BIOS vendor'; - 44 = 'Reserved for BIOS vendor'; - 45 = 'Reserved for BIOS vendor'; - 46 = 'Reserved for BIOS vendor'; - 47 = 'Reserved for BIOS vendor'; - 48 = 'Reserved for system vendor'; - 49 = 'Reserved for system vendor'; - 50 = 'Reserved for system vendor'; - 51 = 'Reserved for system vendor'; - 52 = 'Reserved for system vendor'; - 53 = 'Reserved for system vendor'; - 54 = 'Reserved for system vendor'; - 55 = 'Reserved for system vendor'; - 56 = 'Reserved for system vendor'; - 57 = 'Reserved for system vendor'; - 58 = 'Reserved for system vendor'; - 59 = 'Reserved for system vendor'; - 60 = 'Reserved for system vendor'; - 61 = 'Reserved for system vendor'; - 62 = 'Reserved for system vendor'; - 63 = 'Reserved for system vendor' -} - -<################################################################################################## -################# /lib/provider/disks ############################################################# -##################################################################################################> - -[hashtable]$DiskCapabilities = @{ - 0 = 'Unknown'; - 1 = 'Other'; - 2 = 'Sequential Access'; - 3 = 'Random Access'; - 4 = 'Supports Writing'; - 5 = 'Encryption'; - 6 = 'Compression'; - 7 = 'Supports Removeable Media'; - 8 = 'Manual Cleaning'; - 9 = 'Automatic Cleaning'; - 10 = 'SMART Notification'; - 11 = 'Supports Dual Sided Media'; - 12 = 'Predismount Eject Not Required'; -} - -<################################################################################################## -################# /lib/provider/cpu ############################################################### -##################################################################################################> - -[hashtable]$CPUArchitecture = @{ - 0='x86'; - 1='MIPS'; - 2='Alpha'; - 3='PowerPC'; - 6='ia64'; - 9='x64'; -} - -[hashtable]$CPUProcessorType = @{ - 1='Other'; - 2='Unknown'; - 3='Central Processor'; - 4='Math Processor'; - 5='DSP Processor'; - 6='Video Processor'; -} - -[hashtable]$CPUStatusInfo = @{ - 1='Other'; - 2='Unknown'; - 3='Enabled'; - 4='Disabled'; - 5='Not Applicable'; -} - -[hashtable]$CPUFamily = @{ - 1='Other'; - 2='Unknown'; - 3='8086'; - 4='80286'; - 5='80386'; - 6='80486'; - 7='8087'; - 8='80287'; - 9='80387'; - 10='80487'; - 11='Pentium(R) brand'; - 12='Pentium(R) Pro'; - 13='Pentium(R) II'; - 14='Pentium(R) processor with MMX(TM) technology'; - 15='Celeron(TM)'; - 16='Pentium(R) II Xeon(TM)'; - 17='Pentium(R) III'; - 18='M1 Family'; - 19='M2 Family'; - 24='K5 Family'; - 25='K6 Family'; - 26='K6-2'; - 27='K6-3'; - 28='AMD Athlon(TM) Processor Family'; - 29='AMD(R) Duron(TM) Processor'; - 30='AMD29000 Family'; - 31='K6-2+'; - 32='Power PC Family'; - 33='Power PC 601'; - 34='Power PC 603'; - 35='Power PC 603+'; - 36='Power PC 604'; - 37='Power PC 620'; - 38='Power PC X704'; - 39='Power PC 750'; - 48='Alpha Family'; - 49='Alpha 21064'; - 50='Alpha 21066'; - 51='Alpha 21164'; - 52='Alpha 21164PC'; - 53='Alpha 21164a'; - 54='Alpha 21264'; - 55='Alpha 21364'; - 64='MIPS Family'; - 65='MIPS R4000'; - 66='MIPS R4200'; - 67='MIPS R4400'; - 68='MIPS R4600'; - 69='MIPS R10000'; - 80='SPARC Family'; - 81='SuperSPARC'; - 82='microSPARC II'; - 83='microSPARC IIep'; - 84='UltraSPARC'; - 85='UltraSPARC II'; - 86='UltraSPARC IIi'; - 87='UltraSPARC III'; - 88='UltraSPARC IIIi'; - 96='68040'; - 97='68xxx Family'; - 98='68000'; - 99='68010'; - 100='68020'; - 101='68030'; - 112='Hobbit Family'; - 120='Crusoe(TM) TM5000 Family'; - 121='Crusoe(TM) TM3000 Family'; - 122='Efficeon(TM) TM8000 Family'; - 128='Weitek'; - 130='Itanium(TM) Processor'; - 131='AMD Athlon(TM) 64 Processor Family'; - 132='AMD Opteron(TM) Family'; - 144='PA-RISC Family'; - 145='PA-RISC 8500'; - 146='PA-RISC 8000'; - 147='PA-RISC 7300LC'; - 148='PA-RISC 7200'; - 149='PA-RISC 7100LC'; - 150='PA-RISC 7100'; - 160='V30 Family'; - 176='Pentium(R) III Xeon(TM)'; - 177='Pentium(R) III Processor with Intel(R) SpeedStep(TM) Technology'; - 178='Pentium(R) 4'; - 179='Intel(R) Xeon(TM)'; - 180='AS400 Family'; - 181='Intel(R) Xeon(TM) processor MP'; - 182='AMD AthlonXP(TM) Family'; - 183='AMD AthlonMP(TM) Family'; - 184='Intel(R) Itanium(R) 2'; - 185='Intel Pentium M Processor'; - 190='K7'; - 200='IBM390 Family'; - 201='G4'; - 202='G5'; - 203='G6'; - 204='z/Architecture base'; - 250='i860'; - 251='i960'; - 260='SH-3'; - 261='SH-4'; - 280='ARM'; - 281='StrongARM'; - 300='6x86'; - 301='MediaGX'; - 302='MII'; - 320='WinChip'; - 350='DSP'; - 500='Video Processor'; -} - -[hashtable]$CPUConfigManagerErrorCode = @{ - 0='This device is working properly.'; - 1='This device is not configured correctly.'; - 2='Windows cannot load the driver for this device.'; - 3='The driver for this device might be corrupted, or your system may be running low on memory or other resources.'; - 4='This device is not working properly. One of its drivers or your registry might be corrupted.'; - 5='The driver for this device needs a resource that Windows cannot manage.'; - 6='The boot configuration for this device conflicts with other devices.'; - 7='Cannot filter.'; - 8='The driver loader for the device is missing.'; - 9='This device is not working properly because the controlling firmware is reporting the resources for the device incorrectly.'; - 10='This device cannot start.'; - 11='This device failed.'; - 12='This device cannot find enough free resources that it can use.'; - 13="Windows cannot verify this device’s resources."; - 14='This device cannot work properly until you restart your computer.'; - 15='This device is not working properly because there is probably a re-enumeration problem.'; - 16='Windows cannot identify all the resources this device uses.'; - 17='This device is asking for an unknown resource type.'; - 18='Reinstall the drivers for this device.'; - 19='Your registry might be corrupted.'; - 20='Failure using the VxD loader.'; - 21='System failure: Try changing the driver for this device. If that does not work, see your hardware documentation. Windows is removing this device.'; - 22='This device is disabled.'; - 23="System failure: Try changing the driver for this device. If that doesn’t work, see your hardware documentation."; - 24="This device is not present, is not working properly, or does not have all its drivers installed."; - 25="Windows is still setting up this device."; - 26="Windows is still setting up this device."; - 27="This device does not have valid log configuration."; - 28="The drivers for this device are not installed."; - 29="This device is disabled because the firmware of the device did not give it the required resources."; - 30="This device is using an Interrupt Request (IRQ) resource that another device is using."; - 31='This device is not working properly because Windows cannot load the drivers required for this device.'; -} - -[hashtable]$CPUAvailability = @{ - 1='Other'; - 2='Unknown'; - 3='Running/Full Power'; - 4='Warning'; - 5='In Test'; - 6='Not Applicable'; - 7='Power Off'; - 8='Off Line'; - 9='Off Duty'; - 10='Degraded'; - 11='Not Installed'; - 12='Install Error'; - 13='Power Save - Unknown'; - 14='Power Save - Low Power Mode'; - 15='Power Save - Standby'; - 16='Power Cycle'; - 17='Power Save - Warning'; - 18='Paused'; - 19='Not Ready'; - 20='Not Configured'; - 21='Quiesced'; -} - -[hashtable]$CPUPowerManagementCapabilities = @{ - 0='Unknown'; - 1='Not Supported'; - 2='Disabled'; - 3='Enabled'; -} - -<################################################################################################## -################# /lib/provider/memory ############################################################ -##################################################################################################> - -[hashtable]$MemoryFormFactor = @{ - 0='Unknown'; - 1= 'Other'; - 2= 'SIP'; - 3= 'DIP'; - 4= 'ZIP'; - 5= 'SOJ'; - 6= 'Proprietary'; - 7= 'SIMM'; - 8= 'DIMM'; - 9= 'TSOP'; - 10= 'PGA'; - 11= 'RIMM'; - 12= 'SODIMM'; - 13= 'SRIMM'; - 14= 'SMD'; - 15= 'SSMP'; - 16= 'QFP'; - 17= 'TQFP'; - 18= 'SOIC'; - 19= 'LCC'; - 20= 'PLCC'; - 21= 'BGA'; - 22= 'FPBGA'; - 23= 'LGA'; -} - -[hashtable]$MemoryInterleavePosition = @{ - 0= 'Noninterleaved'; - 1= 'First position'; - 2= 'Second position'; -} - -[hashtable]$MemoryMemoryType = @{ - 0= 'Unknown'; - 1= 'Other'; - 2= 'DRAM'; - 3= 'Synchronous DRAM'; - 4= 'Cache DRAM'; - 5= 'EDO'; - 6= 'EDRAM'; - 7= 'VRAM'; - 8= 'SRAM'; - 9= 'RAM'; - 10= 'ROM'; - 11= 'Flash'; - 12='EEPROM'; - 13= 'FEPROM'; - 14= 'EPROM'; - 15= 'CDRAM'; - 16= '3DRAM'; - 17= 'SDRAM'; - 18= 'SGRAM'; - 19= 'RDRAM'; - 20= 'DDR'; - 21= 'DDR2'; - 22= 'DDR2 FB-DIMM'; - 23= 'DDR2—FB-DIMM,May not be available; see note above.'; - 24= 'DDR3—May not be available; see note above.'; - 25= 'FBD2'; -} - -[hashtable]$MemoryTypeDetail = @{ - 1= 'Reserved'; - 2= 'Other'; - 4= 'Unknown'; - 8= 'Fast-paged'; - 16= 'Static column'; - 32= 'Pseudo-static'; - 64= 'RAMBUS'; - 128= 'Synchronous'; - 256= 'CMOS'; - 512= 'EDO'; - 1024= 'Window DRAM'; - 2048= 'Cache DRAM'; - 4096= 'Non-volatile'; -} - -<################################################################################################## -################# /lib/provider/Windows ########################################################### -##################################################################################################> - -[hashtable]$WindowsOSProductSuite = @{ - 1= 'Microsoft Small Business Server was once installed, but may have been upgraded to another version of Windows.'; - 2= 'Windows Server 2008 Enterprise is installed.'; - 4= 'Windows BackOffice components are installed.'; - 8= 'Communication Server is installed.'; - 16= 'Terminal Services is installed.'; - 32= 'Microsoft Small Business Server is installed with the restrictive client license.'; - 64= 'Windows Embedded is installed.'; - 128= 'Datacenter edition is installed.'; - 256= 'Terminal Services is installed, but only one interactive session is supported.'; - 512= 'Windows Home Edition is installed.'; - 1024= 'Web Server Edition is installed.'; - 8192= 'Storage Server Edition is installed.'; - 16384= 'Compute Cluster Edition is installed.'; -} - -[hashtable]$WindowsProductType = @{ - 1= 'Work Station'; - 2= 'Domain Controller'; - 3= 'Server'; -} - -[hashtable]$WindowsOSType = @{ - 0= 'Unknown'; - 1= 'Other'; - 2= 'MACROS'; - 3= 'ATTUNIX'; - 4= 'DGUX'; - 5= 'DECNT'; - 6= 'Digital Unix'; - 7= 'OpenVMS' - 8= 'HPUX'; - 9= 'AIX'; - 10= 'MVS'; - 11= 'OS400'; - 12= 'OS/2'; - 13= 'JavaVM'; - 14= 'MSDOS'; - 15= 'WIN3x'; - 16= 'WIN95'; - 17= 'WIN98'; - 18= 'WINNT'; - 19= 'WINCE'; - 20= 'NCR3000'; - 21= 'NetWare'; - 22= 'OSF'; - 23= 'DC/OS'; - 24= 'Reliant UNIX'; - 25= 'SCO UnixWare'; - 26= 'SCO OpenServer'; - 27= 'Sequent'; - 28= 'IRIX'; - 29= 'Solaris'; - 30= 'SunOS'; - 31= 'U6000'; - 32= 'ASERIES'; - 33= 'TandemNSK'; - 34= 'TandemNT'; - 35= 'BS2000'; - 36= 'LINUX'; - 37= 'Lynx'; - 38= 'XENIX'; - 39= 'VM/ESA'; - 40= 'Interactive UNIX'; - 41= 'BSDUNIX'; - 42= 'FreeBSD'; - 43= 'NetBSD'; - 44= 'GNU Hurd'; - 45= 'OS9'; - 46= 'MACH Kernel'; - 47= 'Inferno'; - 48= 'QNX'; - 49= 'EPOC'; - 50= 'IxWorks'; - 51= 'VxWorks'; - 52= 'MiNT'; - 53= 'BeOS'; - 54= 'HP MPE'; - 55= 'NextStep'; - 56= 'PalmPilot'; - 57= 'Rhapsody'; - 58= 'Windows 2000'; - 59= 'Dedicated'; - 60= 'OS/390'; - 61= 'VSE'; - 62= 'TPF'; -} - -<################################################################################################## -################# /lib/provider/Services ########################################################### -##################################################################################################> - -[hashtable]$ServiceStatusName = @{ - 1 = 'Stopped'; - 2 = 'StartPending'; - 3 = 'StopPending'; - 4 = 'Running'; - 5 = 'ContinuePending'; - 6 = 'PausePending'; - 7 = 'Paused'; -} - -[hashtable]$ServiceStatus = @{ - 'Stopped' = 1; - 'StartPending' = 2; - 'StopPending' = 3; - 'Running' = 4; - 'ContinuePending' = 5; - 'PausePending' = 6; - 'Paused' = 7; -} - -[hashtable]$ProviderEnums = @{ - #/lib/provider/bios - BiosCharacteristics = $BiosCharacteristics; - #/lib/provider/disks - DiskCapabilities = $DiskCapabilities; - #/lib/provider/cpu - CPUArchitecture = $CPUArchitecture; - CPUProcessorType = $CPUProcessorType; - CPUStatusInfo = $CPUStatusInfo; - CPUFamily = $CPUFamily; - CPUConfigManagerErrorCode = $CPUConfigManagerErrorCode; - CPUAvailability = $CPUAvailability; - CPUPowerManagementCapabilities = $CPUPowerManagementCapabilities; - #/lib/provider/memory - MemoryFormFactor = $MemoryFormFactor; - MemoryInterleavePosition = $MemoryInterleavePosition; - MemoryMemoryType = $MemoryMemoryType; - MemoryTypeDetail = $MemoryTypeDetail; - #/lib/provider/windows - WindowsOSProductSuite = $WindowsOSProductSuite; - WindowsProductType = $WindowsProductType; - WindowsOSType = $WindowsOSType; - #/lib/provider/services - ServiceStatus = $ServiceStatus; - ServiceStatusName =$ServiceStatusName; -} - -Export-ModuleMember -Variable @('ProviderEnums'); \ No newline at end of file diff --git a/lib/provider/eventlog/Get-IcingaEventLog.psm1 b/lib/provider/eventlog/Get-IcingaEventLog.psm1 deleted file mode 100644 index d4fb878..0000000 --- a/lib/provider/eventlog/Get-IcingaEventLog.psm1 +++ /dev/null @@ -1,153 +0,0 @@ -Import-IcingaLib icinga\exception; - -function Get-IcingaEventLog() -{ - param( - [string]$LogName, - [array]$IncludeEventId, - [array]$ExcludeEventId, - [array]$IncludeUsername, - [array]$ExcludeUsername, - [array]$IncludeEntryType, - [array]$ExcludeEntryType, - [array]$IncludeMessage, - [array]$ExcludeMessage, - $After, - $Before, - [bool]$DisableTimeCache - ); - - if ([string]::IsNullOrEmpty($LogName)) { - Exit-IcingaThrowException -ExceptionType 'Input' -ExceptionThrown $IcingaExceptions.Inputs.EventLog -Force; - } - - [hashtable]$EventLogArguments = @{ - LogName = $LogName; - }; - - # This will generate a unique hash for each possible configured EventLog check to store the last check time for each of these checks - [string]$CheckHash = (Get-StringSha1 ($LogName + $IncludeEventId + $ExcludeEventId + $IncludeUsername + $ExcludeUsername + $IncludeEntryType + $ExcludeEntryType + $IncludeMessage + $ExcludeMessage)) + '.lastcheck'; - - if ($null -eq $After -and $DisableTimeCache -eq $FALSE) { - $time = Get-IcingaCacheData -Space 'provider' -CacheStore 'eventlog' -KeyName $CheckHash; - Set-IcingaCacheData -Space 'provider' -CacheStore 'eventlog' -KeyName $CheckHash -Value ((Get-Date).ToFileTime()); - - if ($null -ne $time) { - $After = [datetime]::FromFileTime($time); - } - } - - if ($null -ne $IncludeEventId) { - $EventLogArguments.Add('InstanceID', $IncludeEventId); - } - if ($null -ne $IncludeUsername) { - $EventLogArguments.Add('UserName', $IncludeUsername); - } - if ($null -ne $IncludeEntryType) { - $EventLogArguments.Add('EntryType', $IncludeEntryType); - } - if ($null -ne $After) { - $EventLogArguments.Add('After', $After); - } - if ($null -ne $Before) { - $EventLogArguments.Add('Before', $Before); - } - - try { - $events = Get-EventLog @EventLogArguments; - } catch { - Exit-IcingaThrowException -InputString $_.Exception -StringPattern 'ParameterBindingValidationException' -ExceptionType 'Input' -ExceptionThrown $IcingaExceptions.Inputs.EventLog; - Exit-IcingaThrowException -InputString $_.Exception -StringPattern 'System.InvalidOperationException' -CustomMessage (-Join $LogName) -ExceptionType 'Input' -ExceptionThrown $IcingaExceptions.Inputs.EventLogLogName; - Exit-IcingaThrowException -InputString $_.Exception -ExceptionType 'Unhandled' -Force; - } - - if ($null -ne $ExcludeEventId -Or $null -ne $ExcludeUsername -Or $null -ne $ExcludeEntryType -Or $null -ne $ExcludeMessage -Or $null -ne $IncludeMessage) { - $filteredEvents = @(); - foreach ($event in $events) { - # Filter out excluded event IDs - if ($ExcludeEventId.Count -ne 0 -And $event.InstanceID -contains $ExcludeEventId) { - continue; - } - - # Filter out excluded event IDs - if ($ExcludeUsername.Count -ne 0 -And $event.UserName -contains $ExcludeUsername) { - continue; - } - - # Filter out excluded event IDs - if ($ExcludeEntryType.Count -ne 0 -And $event.EntryType -contains $ExcludeEntryType) { - continue; - } - - [bool]$skip = $FALSE; - foreach ($exMessage in $ExcludeMessage) { - # Filter out excluded event IDs - if ([string]$event.Message -like [string]$exMessage) { - $skip = $TRUE; - break; - } - } - - if ($skip) { - continue; - } - - [bool]$skip = $TRUE; - - foreach ($inMessage in $IncludeMessage) { - # Filter for specific message content - if ([string]$event.Message -like [string]$inMessage) { - $skip = $FALSE; - break; - } - } - - if ($skip) { - continue; - } - - $filteredEvents += $event; - } - - $events = $filteredEvents; - } - - $groupedEvents = @{ - 'eventlog' = @{}; - 'events' = @{}; - }; - - foreach ($event in $events) { - [string]$EventIdentifier = [string]::Format('{0}-{1}', - $event.InstanceID, - $event.Message - ); - - [string]$EventHash = Get-StringSha1 $EventIdentifier; - - if ($groupedEvents.eventlog.ContainsKey($EventHash) -eq $FALSE) { - $groupedEvents.eventlog.Add( - $EventHash, - @{ - NewestEntry = $event.TimeGenerated; - OldestEntry = $event.TimeGenerated; - EventId = $event.InstanceID; - Message = $event.Message; - Severity = $event.EntryType; - Count = 1; - } - ); - } else { - $groupedEvents.eventlog[$EventHash].OldestEntry = $event.TimeGenerated; - $groupedEvents.eventlog[$EventHash].Count += 1; - } - - if ($groupedEvents.events.ContainsKey($event.InstanceID) -eq $FALSE) { - $groupedEvents.events.Add($event.InstanceID, 1); - } else { - $groupedEvents.events[$event.InstanceID] += 1; - } - } - - return $groupedEvents; -} diff --git a/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 b/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 deleted file mode 100644 index 81eedf9..0000000 --- a/lib/provider/memory/Get-IcingaMemoryPerformanceCounter.psm1 +++ /dev/null @@ -1,18 +0,0 @@ -function Get-IcingaMemoryPerformanceCounter() -{ - $MemoryPercent = New-IcingaPerformanceCounterArray -Counter "\Memory\% committed bytes in use","\Memory\Available Bytes","\Paging File(_Total)\% usage" - [hashtable]$Initial = @{}; - [hashtable]$MemoryData = @{}; - - foreach ($item in $MemoryPercent.Keys) { - $Initial.Add($item, $MemoryPercent[$item]); - } - - $MemoryData.Add('Memory Available Bytes', [decimal]($Initial.'\Memory\Available Bytes'.value)); - $MemoryData.Add('Memory Total Bytes', (Get-CimInstance Win32_ComputerSystem).TotalPhysicalMemory); - $MemoryData.Add('Memory Used Bytes', $MemoryData.'Memory Total Bytes' - $MemoryData.'Memory Available Bytes'); - $MemoryData.Add('Memory Used %', 100 - ($MemoryData.'Memory Available Bytes' / $MemoryData.'Memory Total Bytes' * 100)); - $MemoryData.Add('PageFile %', $Initial.'\Paging File(_Total)\% usage'.value); - - return $MemoryData; -} \ No newline at end of file diff --git a/lib/provider/memory/Get-IcingaMemoryUsage.psm1 b/lib/provider/memory/Get-IcingaMemoryUsage.psm1 deleted file mode 100644 index bf206a1..0000000 --- a/lib/provider/memory/Get-IcingaMemoryUsage.psm1 +++ /dev/null @@ -1,14 +0,0 @@ -function Get-IcingaMemoryUsage() -{ - $MEMUsageInformations = Get-CimInstance Win32_OperatingSystem; - - [hashtable]$MEMUsageData = @{ - 'FreePhysicalMemory' = $MEMUsageInformations.FreePhysicalMemory; - 'FreeVirtualMemory' = $MEMUsageInformations.FreeVirtualMemory; - 'TotalVirtualMemorySize' = $MEMUsageInformations.TotalVirtualMemorySize; - 'TotalVisibleMemorySize' = $MEMUsageInformations.TotalVisibleMemorySize; - 'MaxProcessMemorySize' = $MEMUsageInformations.MaxProcessMemorySize; - } - - return $MEMUsageData; -} diff --git a/lib/provider/memory/Icinga_ProviderMemory.psm1 b/lib/provider/memory/Icinga_ProviderMemory.psm1 deleted file mode 100644 index 68ab0ed..0000000 --- a/lib/provider/memory/Icinga_ProviderMemory.psm1 +++ /dev/null @@ -1,148 +0,0 @@ -Import-IcingaLib provider\enums; -function Get-IcingaMemory() -{ - <# Collects the most important Memory informations, - e.g. name, version, manufacturer#> - $MEMInformation = Get-CimInstance Win32_PhysicalMemory; - - [hashtable]$MEMData = @{}; - - foreach($memory in $MEMInformation) { - - $TypeDetail = @(); - $ProviderEnums.MemoryTypeDetail.Keys | Where-Object { - $_ -band $memory.TypeDetail - } | ForEach-Object { - $TypeDetail += $ProviderEnums.MemoryTypeDetail.Get_Item($_); - }; - - $MEMData.Add( - $memory.tag.trim("Physical Memory"), @{ - 'metadata' = @{ - 'Caption' = $memory.Name; - 'Description'= $memory.Description; - 'Manufacturer'= $memory.Manufacturer; - 'Model'= $memory.Model; - 'OtherIdentifyingInfo'= $memory.OtherIdentifyingInfo; - 'PartNumber'= $memory.PartNumber; - 'SerialNumber'= $memory.SerialNumber; - 'Tag'= $memory.Tag; - 'SMBIOSMemoryType'= $memory.SMBIOSMemoryType; - 'DeviceLocator' = $memory.DeviceLocator; - 'PositionInRow' = $memory.PositionInRow; - 'Version' = $memory.Version; - 'PoweredOn' = $memory.PoweredOn; - 'Status' = $memory.Status; - 'InstallDate' = $memory.InstallDate; - 'BankLabel' = $memory.BankLabel; - 'InterleaveDataDepth' = $memory.InterleaveDataDepth; - 'Attributes' = $memory.Attributes; - 'Replaceable' = $memory.Replaceable; - 'Removable' = $memory.Removable; - 'HotSwappable' = $memory.HotSwappable; - 'FormFactor' = @{ - 'raw' = $memory.FormFactor; - 'value' = $ProviderEnums.MemoryFormFactor[[int]$memory.FormFactor]; - }; - 'InterleavePosition' = @{ - 'raw' = $memory.InterleavePosition; - 'value' = $ProviderEnums.MemoryInterleavePosition[[int]$memory.InterleavePosition]; - }; - 'MemoryType' = @{ - 'raw' = $memory.MemoryType; - 'value' = $ProviderEnums.MemoryMemoryType[[int]$memory.MemoryType]; - }; - 'TypeDetail' = @{ - 'raw' = $memory.TypeDetail; - 'value' = $TypeDetail; - }; - }; - 'specs' = @{ - 'MaxVoltage' = $memory.MaxVoltage; - 'MinVoltage' = $memory.MinVoltage; - 'ConfiguredVoltage' = $memory.ConfiguredVoltage; - 'ConfiguredClockSpeed' = $memory.ConfiguredClockSpeed; - 'TotalWidth' = $memory.TotalWidth; - 'DataWidth' = $memory.DataWidth; - 'Speed' = $memory.Speed; - 'Capacity' = $memory.Capacity; - } - } - ); - } - - return $MEMData; -} - -function Get-IcingaMemoryInformation() -{ - <# Fetches the information for other more specific Get-IcingaMemory-functions - e.g. Get-IcingaMemoryMaxVoltage; Get-IcingaMemoryTotalWidth. - Can be used to fetch information regarding a value of your choice. #> - param( - [string]$Parameter - ); - $MEMInformation = Get-CimInstance Win32_PhysicalMemory; - [hashtable]$MEMData = @{}; - - foreach ($memory in $MEMInformation) { - $MEMData.Add($memory.tag.trim("Physical Memory"), $memory.$Parameter); - } - - return $MEMData; -} -function Get-IcingaMemoryMaxVoltage() -{ - $MemoryMaxVoltage = Get-IcingaMemoryInformation -Parameter MaxVoltage; - - return @{'value' = $MemoryMaxVoltage; 'name' = 'MaxVoltage'}; -} - -function Get-IcingaMemoryMinVoltage() -{ - $MemoryMinVoltage = Get-IcingaMemoryInformation -Parameter MinVoltage; - - return @{'value' = $MemoryMinVoltage; 'name' = 'MinVoltage'}; -} - -function Get-IcingaMemoryConfiguredVoltage() -{ - $MemoryConfiguredVoltage = Get-IcingaMemoryInformation -Parameter ConfiguredVoltage; - - return @{'value' = $MemoryConfiguredVoltage; 'name' = 'ConfiguredVoltage'}; -} - -function Get-IcingaMemoryConfiguredClockSpeed() -{ - $MemoryConfiguredClockSpeed = Get-IcingaMemoryInformation -Parameter ConfiguredClockSpeed; - - return @{'value' = $MemoryConfiguredClockSpeed; 'name' = 'ConfiguredClockSpeed'}; -} - -function Get-IcingaMemoryTotalWidth() -{ - $MemoryTotalWidth = Get-IcingaMemoryInformation -Parameter TotalWidth; - - return @{'value' = $MemoryTotalWidth; 'name' = 'TotalWidth'}; -} - -function Get-IcingaMemoryDataWidth() -{ - $MemoryDataWidth = Get-IcingaMemoryInformation -Parameter DataWidth; - - return @{'value' = $MemoryDataWidth; 'name' = 'DataWidth'}; -} - -function Get-IcingaMemorySpeed() -{ - $MemorySpeed = Get-IcingaMemoryInformation -Parameter Speed; - - return @{'value' = $MemorySpeed; 'name' = 'Speed'}; -} - -function Get-IcingaMemoryCapacity() -{ - $MemoryCapacity = Get-IcingaMemoryInformation -Parameter Capacity; - - return @{'value' = $MemoryCapacity; 'name' = 'Capacity'}; -} \ No newline at end of file diff --git a/lib/provider/memory/Show-IcingaMemoryData.psm1 b/lib/provider/memory/Show-IcingaMemoryData.psm1 deleted file mode 100644 index bd2a28c..0000000 --- a/lib/provider/memory/Show-IcingaMemoryData.psm1 +++ /dev/null @@ -1,51 +0,0 @@ -function Show-IcingaMemoryData () -{ - $MEMInformation = Get-CimInstance Win32_PhysicalMemory; - - [hashtable]$MEMData = @{}; - - foreach($memory in $MEMInformation) { - $MEMData.Add( - $memory.tag.trim("Physical Memory"), @{ - 'Caption' = $memory.Name; - 'Description' = $memory.Description; - 'Name' = $memory.Name; - 'InstallDate' = $memory.InstallDate; - 'Status' = $memory.Status - 'CreationClassName'= $memory.CreationClassName - 'Manufacturer'= $memory.Manufacturer - 'Model'= $memory.Model - 'OtherIdentifyingInfo'= $memory.OtherIdentifyingInfo - 'PartNumber'= $memory.PartNumber - 'PoweredOn'= $memory.PoweredOn - 'SerialNumber'= $memory.SerialNumber - 'SKU'= $memory.SKU - 'Tag'= $memory.Tag - 'Version'= $memory.Version - 'HotSwappable'= $memory.HotSwappable - 'Removable'= $memory.Removable - 'Replaceable'= $memory.Replaceable - 'FormFactor'= $memory.FormFactor - 'BankLabel'= $memory.BankLabel - 'Capacity'= $memory.Capacity - 'DataWidth'= $memory.DataWidth - 'InterleavePosition'= $memory.InterleavePosition - 'MemoryType'= $memory.MemoryType - 'PositionInRow'= $memory.PositionInRow - 'Speed'= $memory.Speed - 'TotalWidth'= $memory.TotalWidth - 'Attributes'= $memory.Attributes - 'ConfiguredClockSpeed'= $memory.ConfiguredClockSpeed - 'ConfiguredVoltage'= $memory.ConfiguredVoltage - 'DeviceLocator'= $memory.DeviceLocator - 'InterleaveDataDepth'= $memory.InterleaveDataDepth - 'MaxVoltage'= $memory.MaxVoltage - 'MinVoltage'= $memory.MinVoltage - 'SMBIOSMemoryType'= $memory.SMBIOSMemoryType - 'TypeDetail'= $memory.TypeDetail - 'PSComputerName'= $memory.PSComputerName - } - ); - } - return $MEMData; -} \ No newline at end of file diff --git a/lib/provider/process/Icinga_ProviderProcess.psm1 b/lib/provider/process/Icinga_ProviderProcess.psm1 deleted file mode 100644 index 5f81296..0000000 --- a/lib/provider/process/Icinga_ProviderProcess.psm1 +++ /dev/null @@ -1,109 +0,0 @@ -Import-IcingaLib provider\enums; -Import-IcingaLib provider\cpu; - -function Add-IcingaProcessPerfData() -{ - param($ProcessList, $ProcessKey, $Process); - - if ($ProcessList.ContainsKey($ProcessKey) -eq $FALSE) { - $ProcessList.Add($ProcessKey, $Process.$ProcessKey); - } else { - $ProcessList[$ProcessKey] += $Process.$ProcessKey; - } -} - -function Get-IcingaProcessData { - - param( - [array]$Process - ); - - $ProcessInformation = Get-WmiObject Win32_Process; - $ProcessPerfDataList = Get-WmiObject Win32_PerfFormattedData_PerfProc_Process; - $CPUCoreCount = Get-IcingaCPUCount; - - - [hashtable]$ProcessData = @{}; - [hashtable]$ProcessList = @{}; - [hashtable]$ProcessNamesUnique = @{}; - [hashtable]$ProcessIDsByName = @{}; - - foreach ($processinfo in $ProcessInformation) { - [string]$processName = $processinfo.Name.Replace('.exe', ''); - - If ($null -ne $Process) { - If (-Not ($Process.Contains($processName))) { - continue; - } - } - - if ($ProcessList.ContainsKey($processName) -eq $FALSE) { - $ProcessList.Add($processName, @{ - 'ProcessList' = @{}; - 'PerformanceData' = @{} - }); - } - - $ProcessList[$processName]['ProcessList'].Add( - [string]$processinfo.ProcessID, @{ - 'Name' = $processinfo.Name; - 'ProcessId' = $processinfo.ProcessId; - 'Priority' = $processinfo.Priority; - 'PageFileUsage' = $processinfo.PageFileUsage; - 'ThreadCount' = $processinfo.ThreadCount; - 'KernelModeTime' = $processinfo.KernelModeTime; - 'UserModeTime' = $processinfo.UserModeTime; - 'WorkingSetSize' = $processinfo.WorkingSetSize; - 'CommandLine' = $processinfo.CommandLine; - } - ); - - Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'ThreadCount' -Process $processinfo; - Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'PageFileUsage' -Process $processinfo; - Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'KernelModeTime' -Process $processinfo; - Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'UserModeTime' -Process $processinfo; - Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'WorkingSetSize' -Process $processinfo; - } - - foreach ($processinfo in $ProcessPerfDataList) { - if ($processinfo.Name -eq '_Total' -Or $processinfo.Name -eq 'Idle') { - continue; - } - - If ($null -ne $Process) { - If (-Not ($Process.Contains($processName))) { - continue; - } - } - - [string]$processName = $processinfo.Name.Split('#')[0]; - [string]$ProcessId = $processinfo.IDProcess; - - if ($ProcessList.ContainsKey($processName) -eq $FALSE) { - continue; - } - - if ($ProcessList[$processName]['ProcessList'].ContainsKey($ProcessId) -eq $FALSE) { - continue; - } - - $ProcessList[$processName]['ProcessList'][$ProcessId].Add( - 'WorkingSetPrivate', $processinfo.WorkingSetPrivate - ); - $ProcessList[$processName]['ProcessList'][$ProcessId].Add( - 'PercentProcessorTime', ($processinfo.PercentProcessorTime / $CPUCoreCount) - ); - - Add-IcingaProcessPerfData -ProcessList $ProcessList[$processName]['PerformanceData'] -ProcessKey 'WorkingSetPrivate' -Process $process; - if ($ProcessList[$processName]['PerformanceData'].ContainsKey('PercentProcessorTime') -eq $FALSE) { - $ProcessList[$processName]['PerformanceData'].Add('PercentProcessorTime', ($processinfo.PercentProcessorTime / $CPUCoreCount)); - } else { - $ProcessList[$processName]['PerformanceData']['PercentProcessorTime'] += ($processinfo.PercentProcessorTime / $CPUCoreCount); - } - } - - $ProcessData.Add('Process Count', $ProcessInformation.Count); - $ProcessData.add('Processes', $ProcessList); - - return $ProcessData; -} \ No newline at end of file diff --git a/lib/provider/services/ConvertTo-ServiceStatusCode.psm1 b/lib/provider/services/ConvertTo-ServiceStatusCode.psm1 deleted file mode 100644 index ce04d84..0000000 --- a/lib/provider/services/ConvertTo-ServiceStatusCode.psm1 +++ /dev/null @@ -1,15 +0,0 @@ -Import-IcingaLib core\tools; -Import-IcingaLib provider\enums; - -function ConvertTo-ServiceStatusCode() -{ - param ( - $Status - ) - - if (Test-Numeric $Status) { - return [int]$Status - } - - return [int]($ProviderEnums.ServiceStatus.$Status); -} diff --git a/lib/provider/services/Get-IcingaServiceCheckName.psm1 b/lib/provider/services/Get-IcingaServiceCheckName.psm1 deleted file mode 100644 index 8d8b4b3..0000000 --- a/lib/provider/services/Get-IcingaServiceCheckName.psm1 +++ /dev/null @@ -1,20 +0,0 @@ -function Get-IcingaServiceCheckName() -{ - param ( - [string]$ServiceInput, - $Service - ); - - if ($null -eq $Service) { - return [string]::Format( - 'Service "{0}"', - $ServiceInput - ); - } - - return [string]::Format( - 'Service "{0} ({1})"', - $Service.Values.metadata.DisplayName, - $Service.Values.metadata.ServiceName - ); -} diff --git a/lib/provider/services/Icinga_ProviderServices.psm1 b/lib/provider/services/Icinga_ProviderServices.psm1 deleted file mode 100644 index a6e5a0f..0000000 --- a/lib/provider/services/Icinga_ProviderServices.psm1 +++ /dev/null @@ -1,85 +0,0 @@ -function Get-IcingaServices() -{ - param ( - [array]$Service - ); - - $ServiceInformation = Get-Service -Name $Service -ErrorAction SilentlyContinue; - $ServiceWmiInfo = $null; - - if ($Service.Count -eq 0) { - $ServiceWmiInfo = Get-WmiObject Win32_Service; - } else { - $ServiceWmiInfo = Get-WmiObject -Class Win32_Service | Where-Object { $Service -Contains $_.Name } | Select-Object StartName, Name; - } - - if ($null -eq $ServiceInformation) { - return $null; - } - - [hashtable]$ServiceData = @{}; - - foreach ($service in $ServiceInformation) { - - [array]$DependentServices = $null; - [array]$DependingServices = $null; - [string]$ServiceUser = ''; - - foreach ($wmiService in $ServiceWmiInfo) { - if ($wmiService.Name -eq $service.ServiceName) { - $ServiceUser = $wmiService.StartName; - break; - } - } - - #Dependent / Child - foreach ($dependency in $service.DependentServices) { - if ($null -eq $DependentServices) { - $DependentServices = @(); - } - $DependentServices += $dependency.Name; - } - - #Depends / Parent - foreach ($dependency in $service.ServicesDependedOn) { - if ($null -eq $DependingServices) { - $DependingServices = @(); - } - $DependingServices += $dependency.Name; - } - - $ServiceData.Add( - $service.Name, @{ - 'metadata' = @{ - 'DisplayName' = $service.DisplayName; - 'ServiceName' = $service.ServiceName; - 'Site' = $service.Site; - 'Container' = $service.Container; - 'ServiceHandle' = $service.ServiceHandle; - 'Dependent' = $DependentServices; - 'Depends' = $DependingServices; - }; - 'configuration' = @{ - 'CanPauseAndContinue' = $service.CanPauseAndContinue; - 'CanShutdown' = $service.CanShutdown; - 'CanStop' = $service.CanStop; - 'Status' = @{ - 'raw' = [int]$service.Status; - 'value' = $service.Status; - }; - 'ServiceType' = @{ - 'raw' = [int]$service.ServiceType; - 'value' = $service.ServiceType; - }; - 'ServiceHandle' = $service.ServiceHandle; - 'StartType' = @{ - 'raw' = [int]$service.StartType; - 'value' = $service.StartType; - }; - 'ServiceUser' = $ServiceUser; - } - } - ); - } - return $ServiceData; -} diff --git a/lib/provider/updates/Get-IcingaUpdatesHotfix.psm1 b/lib/provider/updates/Get-IcingaUpdatesHotfix.psm1 deleted file mode 100644 index 2f62185..0000000 --- a/lib/provider/updates/Get-IcingaUpdatesHotfix.psm1 +++ /dev/null @@ -1,29 +0,0 @@ -function Get-IcingaUpdatesHotfix (){ - -[hashtable]$HotfixInfo = @{}; -[hashtable]$HotfixNameCache = @{}; - -# First fetch all of our hotfixes -$Hotfixes = Get-Hotfix; - -foreach ($property in $Hotfixes) { - [hashtable]$HotfixData = @{}; - foreach ($hotfix in $property.Properties) { - $HotfixData.Add($hotfix.Name, $hotfix.Value); - } - - [string]$name = [string]::Format('{0} [{1}]', $HotfixData.HotFixID, $HotfixData.InstalledOn); - - if ($HotfixNameCache.ContainsKey($name) -eq $FALSE) { - $HotfixNameCache.Add($name, 1); - } else { - $HotfixNameCache[$name] += 1; - $name = [string]::Format('{0} ({1})', $name, $HotfixNameCache[$name]); - } - - $HotfixInfo.Add($name, $HotfixData); -} - -return $HotfixInfo; - -} \ No newline at end of file diff --git a/lib/provider/updates/Get-IcingaUpdatesInstalled.psm1 b/lib/provider/updates/Get-IcingaUpdatesInstalled.psm1 deleted file mode 100644 index a294303..0000000 --- a/lib/provider/updates/Get-IcingaUpdatesInstalled.psm1 +++ /dev/null @@ -1,75 +0,0 @@ -function Get-IcingaUpdatesInstalled () -{ - -# Fetch all informations about installed updates and add them -$WindowsUpdates = New-Object -ComObject "Microsoft.Update.Session"; -$SearchIndex = $WindowsUpdates.CreateUpdateSearcher(); -[hashtable]$UpdateList = @{}; -[hashtable]$UpdateInstalled = @{}; -[hashtable]$UpdateUninstalled = @{}; -[hashtable]$UpdateOther = @{}; - -# Operation ID's -# 1: Installed -# 2: Uninstalled -# 3: Other - -# At first get a list of our Windows Update history -$Updates = $SearchIndex.QueryHistory(0, $SearchIndex.GetTotalHistoryCount()) | - Select-Object Operation, ResultCode, HResult, Date, Title, Description, ServiceID, SupportUrl; - -foreach ($update in $Updates) { - [string]$UpdateKey = [string]::Format('{0} [{1}|{2}]', $update.Title, $update.Date, $update.HResult); - switch ($update.Operation) { - 1 { - if ($UpdateInstalled.ContainsKey($UpdateKey) -eq $FALSE) { - $UpdateInstalled.Add($UpdateKey, $update); - } else { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - [string]::Format( - 'Unable to add update "{0}" to update list. The key with content "{1}" is already present', - $UpdateKey, - $update - ) - ); - } - }; - 2 { - if ($UpdateUninstalled.ContainsKey($UpdateKey) -eq $FALSE) { - $UpdateUninstalled.Add($UpdateKey, $update); - } else { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - [string]::Format( - 'Unable to add update "{0}" to update list. The key with content "{1}" is already present', - $UpdateKey, - $update - ) - ); - } - }; - default { - if ($UpdateOther.ContainsKey($UpdateKey) -eq $FALSE) { - $UpdateOther.Add($UpdateKey, $update); - } else { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - [string]::Format( - 'Unable to add update "{0}" to update list. The key with content "{1}" is already present', - $UpdateKey, - $update - ) - ); - } - }; - } -} - -$UpdateList.Add('installed', $UpdateInstalled); -$UpdateList.Add('uninstalled', $UpdateUninstalled); -$UpdateList.Add('other', $UpdateOther); - -return $UpdateList; - -} \ No newline at end of file diff --git a/lib/provider/updates/Get-IcingaUpdatesPending.psm1 b/lib/provider/updates/Get-IcingaUpdatesPending.psm1 deleted file mode 100644 index 5917f99..0000000 --- a/lib/provider/updates/Get-IcingaUpdatesPending.psm1 +++ /dev/null @@ -1,79 +0,0 @@ -function Get-IcingaUpdatesPending () -{ - - [hashtable]$PendingUpdates = @{}; - [hashtable]$PendingUpdateNameCache = @{}; - # Fetch all informations about installed updates and add them - $WindowsUpdates = New-Object -ComObject "Microsoft.Update.Session"; - $SearchIndex = $WindowsUpdates.CreateUpdateSearcher(); - - try { - # Get a list of current pending updates which are not yet installed on the system - $Pending = $SearchIndex.Search("IsInstalled=0"); - $PendingUpdates.Add('count', $Pending.Updates.Count); - $PendingUpdates.Add('updates', @{ }); - - foreach ($update in $Pending.Updates) { - [hashtable]$PendingUpdateDetails = @{}; - $PendingUpdateDetails.Add('Title', $update.Title); - $PendingUpdateDetails.Add('Deadline', $update.Deadline); - $PendingUpdateDetails.Add('Description', $update.Description); - $PendingUpdateDetails.Add('IsBeta', $update.IsBeta); - $PendingUpdateDetails.Add('IsDownloaded', $update.IsDownloaded); - $PendingUpdateDetails.Add('IsHidden', $update.IsHidden); - $PendingUpdateDetails.Add('IsInstalled', $update.IsInstalled); - $PendingUpdateDetails.Add('IsMandatory', $update.IsMandatory); - $PendingUpdateDetails.Add('IsUninstallable', $update.IsUninstallable); - $PendingUpdateDetails.Add('Languages', $update.Languages); - $PendingUpdateDetails.Add('LastDeploymentChangeTime', $update.LastDeploymentChangeTime); - $PendingUpdateDetails.Add('MaxDownloadSize', $update.MaxDownloadSize); - $PendingUpdateDetails.Add('MinDownloadSize', $update.MinDownloadSize); - $PendingUpdateDetails.Add('MoreInfoUrls', $update.MoreInfoUrls); - $PendingUpdateDetails.Add('MsrcSeverity', $update.MsrcSeverity); - $PendingUpdateDetails.Add('RecommendedCpuSpeed', $update.RecommendedCpuSpeed); - $PendingUpdateDetails.Add('RecommendedHardDiskSpace', $update.RecommendedHardDiskSpace); - $PendingUpdateDetails.Add('RecommendedMemory', $update.RecommendedMemory); - $PendingUpdateDetails.Add('ReleaseNotes', $update.ReleaseNotes); - $PendingUpdateDetails.Add('SecurityBulletinIDs', $update.SecurityBulletinIDs); - $PendingUpdateDetails.Add('SupersededUpdateIDs', $update.SupersededUpdateIDs); - $PendingUpdateDetails.Add('SupportUrl', $update.SupportUrl); - $PendingUpdateDetails.Add('Type', $update.Type); - $PendingUpdateDetails.Add('UninstallationNotes', $update.UninstallationNotes); - $PendingUpdateDetails.Add('UninstallationBehavior', $update.UninstallationBehavior); - $PendingUpdateDetails.Add('UninstallationSteps', $update.UninstallationSteps); - $PendingUpdateDetails.Add('KBArticleIDs', $update.KBArticleIDs); - $PendingUpdateDetails.Add('DeploymentAction', $update.DeploymentAction); - $PendingUpdateDetails.Add('DownloadPriority', $update.DownloadPriority); - $PendingUpdateDetails.Add('RebootRequired', $update.RebootRequired); - $PendingUpdateDetails.Add('IsPresent', $update.IsPresent); - $PendingUpdateDetails.Add('CveIDs', $update.CveIDs); - $PendingUpdateDetails.Add('BrowseOnly', $update.BrowseOnly); - $PendingUpdateDetails.Add('PerUser', $update.PerUser); - $PendingUpdateDetails.Add('AutoSelection', $update.AutoSelection); - $PendingUpdateDetails.Add('AutoDownload', $update.AutoDownload); - - [string]$name = [string]::Format('{0} [{1}]', $update.Title, $update.LastDeploymentChangeTime); - - if ($PendingUpdateNameCache.ContainsKey($name) -eq $FALSE) { - $PendingUpdateNameCache.Add($name, 1); - } else { - $PendingUpdateNameCache[$name] += 1; - $name = [string]::Format('{0} ({1})', $name, $PendingUpdateNameCache[$name]); - } - - $PendingUpdates.updates.Add($name, $PendingUpdateDetails); - } - } catch { - if ($PendingUpdates.ContainsKey('Count') -eq $FALSE) { - $PendingUpdates.Add('count', 0); - } else { - $PendingUpdates['count'] = 0; - } - $PendingUpdates.Add('error', [string]::Format( - 'Failed to query Windows Update server: {0}', - $_.Exception.Message - )); - } - - return $PendingUpdates; -} \ No newline at end of file diff --git a/lib/provider/users/Get-IcingaLoggedOnUsers.psm1 b/lib/provider/users/Get-IcingaLoggedOnUsers.psm1 deleted file mode 100644 index 351525c..0000000 --- a/lib/provider/users/Get-IcingaLoggedOnUsers.psm1 +++ /dev/null @@ -1,43 +0,0 @@ -function Get-IcingaLoggedOnUsers() -{ - param( - [array]$UserFilter = @() - ); - - [hashtable]$UserList = @{}; - [int]$UserCount = 0; - $UserList.Add('users', @{ }); - - $Users = Get-CIMInstance Win32_LoggedOnUser | Select-Object Antecedent, Dependent; - - foreach ($user in $Users) { - [string]$username = $user.Antecedent.Name; - - if ($UserFilter.Count -ne 0) { - if (-Not $UserFilter.Contains($username)) { - continue; - } - } - - $UserCount += 1; - - if ($UserList.users.ContainsKey($username) -eq $FALSE) { - $UserList.users.Add( - $username, - @{ - 'domains' = @($user.Antecedent.Domain); - 'logonid' = @($user.Dependent.LogonId); - 'count' = 1; - } - ); - } else { - $UserList.users[$username].domains += $user.Antecedent.Domain; - $UserList.users[$username].logonid += $user.Dependent.LogonId; - $UserList.users[$username].count += 1; - } - } - - $UserList.Add('count', $UserCount); - - return $UserList; -} diff --git a/lib/provider/users/Get-IcingaUsers.psm1 b/lib/provider/users/Get-IcingaUsers.psm1 deleted file mode 100644 index 01ec6ed..0000000 --- a/lib/provider/users/Get-IcingaUsers.psm1 +++ /dev/null @@ -1,17 +0,0 @@ -function Get-IcingaUsers() -{ - param ( - [array]$Username - ); - - if ($null -eq $Username) { - return Get-LocalUser; - } else { - [array]$UserInformation = @(); - foreach ($UniqueUser in $Username) { - $UserInformation += (Get-LocalUser -Name $UniqueUser); - } - } - - return $UserInformation; -} diff --git a/lib/provider/windows/Icinga_ProviderWindows.psm1 b/lib/provider/windows/Icinga_ProviderWindows.psm1 deleted file mode 100644 index 126d016..0000000 --- a/lib/provider/windows/Icinga_ProviderWindows.psm1 +++ /dev/null @@ -1,53 +0,0 @@ -Import-IcingaLib provider\enums; - -function Get-IcingaWindows() -{ - $WindowsInformations = Get-CimInstance Win32_OperatingSystem; - - $OSProductSuite = @(); - $ProviderEnums.WindowsOSProductSuite.Keys | Where-Object { - $_ -band $WindowsInformations.OSProductSuite - } | ForEach-Object { - $OSProductSuite += $ProviderEnums.WindowsOSProductSuite.Get_Item($_); - }; - - $windows_datails = @{}; - $windows_datails.Add( - 'windows', @{ - 'metadata' = @{ - 'Version' = $WindowsInformations.Version; - 'CurrentTimeZone' = $WindowsInformations.CurrentTimeZone; - 'InstallDate' = $WindowsInformations.InstallDate; - 'SystemDevice' = $WindowsInformations.SystemDevice; - 'SystemDirectory' = $WindowsInformations.SystemDirectory; - 'BuildType' = $WindowsInformations.BuildType; - 'BuildNumber' = $WindowsInformations.BuildNumber; - 'OSArchitecture' = $WindowsInformations.OSArchitecture; - 'NumberOfUsers' = $WindowsInformations.NumberOfUsers; - 'Uptime' = @{ - 'raw' = $WindowsInformations.LastBootUpTime; - 'value' = ((Get-Date) - $WindowsInformations.LastBootUpTime).TotalSeconds; - }; - 'OSType' = @{ - 'raw' = $WindowsInformations.OSType; - 'value' = $ProviderEnums.WindowsOSType[[int]$WindowsInformations.OSType]; - }; - 'OSProductSuite' = @{ - 'raw' = $WindowsInformations.OSProductSuite; - 'value' = $OSProductSuite; - }; - 'ProductType' = @{ - 'raw' = $WindowsInformations.ProductType; - 'value' = $ProviderEnums.WindowsProductType[[int]$WindowsInformations.ProductType]; - }; - }; - 'language' = @{ - 'CountryCode' = $WindowsInformations.CountryCode; - 'OSLanguage' = $WindowsInformations.OSLanguage; - 'Locale' = $WindowsInformations.Locale; - } - } - ); - - return $windows_datails; -} \ No newline at end of file diff --git a/lib/provider/windows/Show-IcingaWindowsData.psm1 b/lib/provider/windows/Show-IcingaWindowsData.psm1 deleted file mode 100644 index 0d40c7d..0000000 --- a/lib/provider/windows/Show-IcingaWindowsData.psm1 +++ /dev/null @@ -1,11 +0,0 @@ -function Show-IcingaWindowsData() -{ - $WindowsInformations = Get-CimInstance Win32_OperatingSystem; - - $windows_datails = @{}; - foreach($cpu_core in $WindowsInformations.CimInstanceProperties) { - $windows_datails.Add($cpu_core.Name, $cpu_core.Value); - } - - return $windows_datails; -} \ No newline at end of file From 11cf3d589c5d2d0dd59cbad004112af4027a6b86 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 11:59:08 +0100 Subject: [PATCH 235/259] Add support to autoload plugins Icinga Plugin repo --- icinga-powershell-framework.psm1 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/icinga-powershell-framework.psm1 b/icinga-powershell-framework.psm1 index cb5181f..2818aa0 100644 --- a/icinga-powershell-framework.psm1 +++ b/icinga-powershell-framework.psm1 @@ -16,6 +16,12 @@ function Use-Icinga() [switch]$Daemon = $FALSE ); + # Ensure we autoload the Icinga Plugin collection, provided by the external + # module 'icinga-powershell-plugins' + if (Get-Command 'Use-IcingaPlugins' -ErrorAction SilentlyContinue) { + Use-IcingaPlugins; + } + # This function will allow us to load this entire module including possible # actions, making it available within our shell environment # First load our custom modules From 5d681ac65df8f9fd05f476842fdf3123f6d1b6d7 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 15:54:01 +0100 Subject: [PATCH 236/259] Fixes manifest file and setting major variables --- icinga-powershell-framework.psd1 | 100 +++++++------------------------ 1 file changed, 23 insertions(+), 77 deletions(-) diff --git a/icinga-powershell-framework.psd1 b/icinga-powershell-framework.psd1 index 86f8eed..7115173 100644 --- a/icinga-powershell-framework.psd1 +++ b/icinga-powershell-framework.psd1 @@ -1,78 +1,24 @@ @{ - -# Script module or binary module file associated with this manifest. -ModuleToProcess = 'icinga-powershell-framework.psm1' - -# Module version number -ModuleVersion = '0.0.1' - -# ID for this module -GUID = 'fcd7a805-a41b-49f9-afee-9d17a2b76d42' - -# Autor of this Moduls -Author = 'Lord Hepipud' - -# Company -CompanyName = '' - -# Copyright -Copyright = '(c) 2018 Lord Hepipud. Alle Rechte vorbehalten.' - -# Description of this module -Description = 'Icinga 2 Windows Agent Module, which allows to entirely monitor the Windows Host system.' - -# Die für dieses Modul mindestens erforderliche Version des Windows PowerShell-Moduls -PowerShellVersion = '3.0' - -# Aus diesem Modul zu exportierende Funktionen. Um optimale Leistung zu erzielen, verwenden Sie keine Platzhalter und löschen den Eintrag nicht. Verwenden Sie ein leeres Array, wenn keine zu exportierenden Funktionen vorhanden sind. -FunctionsToExport = @( 'Use-Icinga', 'Import-IcingaLib', 'Publish-IcingaModuleManifests', 'Get-IcingaPluginDir', 'Get-IcingaCustomPluginDir', 'Get-IcingaCacheDir', 'Get-IcingaPowerShellConfigDir', 'Get-IcingaFrameworkRootPath', 'Get-IcingaPowerShellModuleFile' ) - -# Aus diesem Modul zu exportierende Cmdlets. Um optimale Leistung zu erzielen, verwenden Sie keine Plat'zhalter und löschen den Eintrag nicht. Verwenden Sie ein leeres Array, wenn keine zu exportierenden Cmdlets vorhanden sind. -CmdletsToExport = @() - -# Die aus diesem Modul zu exportierenden Variablen -VariablesToExport = '*' - -# Aus diesem Modul zu exportierende Aliase. Um optimale Leistung zu erzielen, verwenden Sie keine Platzhalter und löschen den Eintrag nicht. Verwenden Sie ein leeres Array, wenn keine zu exportierenden Aliase vorhanden sind. -AliasesToExport = @() - -# Aus diesem Modul zu exportierende DSC-Ressourcen -# DscResourcesToExport = @() - -# Liste aller Module in diesem Modulpaket -# ModuleList = @() - -# Liste aller Dateien in diesem Modulpaket -# FileList = @() - -# Die privaten Daten, die an das in "RootModule/ModuleToProcess" angegebene Modul übergeben werden sollen. Diese können auch eine PSData-Hashtabelle mit zusätzlichen von PowerShell verwendeten Modulmetadaten enthalten. -PrivateData = @{ - - PSData = @{ - - # 'Tags' wurde auf das Modul angewendet und unterstützt die Modulermittlung in Onlinekatalogen. - # Tags = @() - - # Eine URL zur Lizenz für dieses Modul. - # LicenseUri = '' - - # Eine URL zur Hauptwebsite für dieses Projekt. - # ProjectUri = '' - - # Eine URL zu einem Symbol, das das Modul darstellt. - # IconUri = '' - - # 'ReleaseNotes' des Moduls - # ReleaseNotes = '' - - } # Ende der PSData-Hashtabelle - -} # Ende der PrivateData-Hashtabelle - -# HelpInfo-URI dieses Moduls -# HelpInfoURI = '' - -# Standardpräfix für Befehle, die aus diesem Modul exportiert werden. Das Standardpräfix kann mit "Import-Module -Prefix" überschrieben werden. -# DefaultCommandPrefix = '' - -} \ No newline at end of file + ModuleToProcess = 'icinga-powershell-framework.psm1' + ModuleVersion = '1.0.0' + GUID = 'fcd7a805-a41b-49f9-afee-9d17a2b76d42' + Author = 'Lord Hepipud' + CompanyName = 'Icinga GmbH' + Copyright = '(c) 2019 Icinga GmbH. All rights reserved.' + Description = 'Icinga 2 Windows Agent Module, which allows to entirely monitor the Windows Host system.' + PowerShellVersion = '4.0' + FunctionsToExport = @( 'Use-Icinga', 'Import-IcingaLib', 'Publish-IcingaModuleManifests', 'Get-IcingaPluginDir', 'Get-IcingaCustomPluginDir', 'Get-IcingaCacheDir', 'Get-IcingaPowerShellConfigDir', 'Get-IcingaFrameworkRootPath', 'Get-IcingaPowerShellModuleFile' ) + CmdletsToExport = @() + VariablesToExport = '*' + AliasesToExport = @() + PrivateData = @{ + PSData = @{ + Tags = @( 'icinga', 'icinga2', 'icinga 2', 'Icinga PowerShell Framework', 'Icinga PowerShell', 'Icinga for Windows', 'Icinga Windows') + LicenseUri = 'https://github.com/Icinga/icinga-powershell-framework/blob/master/LICENSE' + ProjectUri = 'https://github.com/Icinga/icinga-powershell-framework' + ReleaseNotes = 'https://github.com/Icinga/icinga-powershell-framework/releases' + }; + Version = 'v1.0.0-rc1'; + } + HelpInfoURI = 'https://github.com/Icinga/icinga-powershell-framework' +} From e937195e163dc0f9c4a9122f5577f40d6bbaab8f Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 15:54:25 +0100 Subject: [PATCH 237/259] Add support to fetch custom version of Icinga modules --- .../Get-IcingaPowerShellModuleVersion.psm1 | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 lib/core/framework/Get-IcingaPowerShellModuleVersion.psm1 diff --git a/lib/core/framework/Get-IcingaPowerShellModuleVersion.psm1 b/lib/core/framework/Get-IcingaPowerShellModuleVersion.psm1 new file mode 100644 index 0000000..14d9d4c --- /dev/null +++ b/lib/core/framework/Get-IcingaPowerShellModuleVersion.psm1 @@ -0,0 +1,14 @@ +function Get-IcingaPowerShellModuleVersion() +{ + param( + $ModuleName + ); + + $ModuleDetails = Get-Module -Name $ModuleName; + + if ($null -eq $ModuleDetails) { + return $null; + } + + return $ModuleDetails.PrivateData.Version; +} From f6f6acf9fc73104b614a6a266d15d6424442ab76 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 15:55:08 +0100 Subject: [PATCH 238/259] Add function to recursively unblock PowerShell files --- .../framework/Unblock-IcingaPowerShellFiles.psm1 | 14 ++++++++++++++ 1 file changed, 14 insertions(+) create mode 100644 lib/core/framework/Unblock-IcingaPowerShellFiles.psm1 diff --git a/lib/core/framework/Unblock-IcingaPowerShellFiles.psm1 b/lib/core/framework/Unblock-IcingaPowerShellFiles.psm1 new file mode 100644 index 0000000..9f6ef5c --- /dev/null +++ b/lib/core/framework/Unblock-IcingaPowerShellFiles.psm1 @@ -0,0 +1,14 @@ +function Unblock-IcingaPowerShellFiles() +{ + param( + $Path + ); + + if ([string]::IsNullOrEmpty($Path)) { + Write-Host 'The specified directory was not found'; + return; + } + + Write-Host 'Unblocking Icinga PowerShell Files'; + Get-ChildItem -Path $Path -Recurse | Unblock-File; +} From ddb85898f85433c279a50de7b6da99055330177d Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 15:57:57 +0100 Subject: [PATCH 239/259] Add support to install and update PowerShell plugins --- .../Install-IcingaFrameworkPlugins.psm1 | 98 +++++++++++++++++++ 1 file changed, 98 insertions(+) create mode 100644 lib/core/framework/Install-IcingaFrameworkPlugins.psm1 diff --git a/lib/core/framework/Install-IcingaFrameworkPlugins.psm1 b/lib/core/framework/Install-IcingaFrameworkPlugins.psm1 new file mode 100644 index 0000000..7a6cc9c --- /dev/null +++ b/lib/core/framework/Install-IcingaFrameworkPlugins.psm1 @@ -0,0 +1,98 @@ +function Install-IcingaFrameworkPlugins() +{ + param( + [string]$PluginsUrl + ); + + $ProgressPreference = "SilentlyContinue"; + $Tag = 'Unknown'; + + if ([string]::IsNullOrEmpty($PluginsUrl)) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you provide a custom repository for the Icinga Plugins?' -Default 'n').result -eq 1) { + $branch = (Get-IcingaAgentInstallerAnswerInput 'Which version to you want to install? (snapshot/stable)' -Default 'v' -DefaultInput 'stable').answer + if ($branch.ToLower() -eq 'snapshot') { + $PluginsUrl = 'https://github.com/Icinga/icinga-powershell-plugins/archive/master.zip'; + } else { + $LatestRelease = (Invoke-WebRequest -Uri 'https://github.com/Icinga/icinga-powershell-plugins/releases/latest' -UseBasicParsing).BaseResponse.ResponseUri.AbsoluteUri; + $PluginsUrl = $LatestRelease.Replace('/releases/tag/', '/archive/'); + $Tag = $PluginsUrl.Split('/')[-1]; + $PluginsUrl = [string]::Format('{0}/{1}.zip', $PluginsUrl, $Tag); + + $CurrentVersion = Get-IcingaPowerShellModuleVersion 'icinga-powershell-plugins'; + + if ($null -ne $CurrentVersion -And $CurrentVersion -eq $Tag) { + Write-Host 'Your Icinga Plugins are already up-to-date'; + return @{ + 'PluginUrl' = $PluginsUrl + }; + } + } + } else { + $PluginsUrl = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the full path to your Icinga Plugin repository' -Default 'v').answer; + } + } + + $ModuleDirectory = Get-IcingaFrameworkRootPath; + $DownloadPath = (Join-Path -Path $ENv:TEMP -ChildPath 'icinga-powershell-plugins.zip'); + Write-Host ([string]::Format('Downloading Icinga Plugins into "{0}"', $DownloadPath)); + + Invoke-WebRequest -UseBasicParsing -Uri $PluginsUrl -OutFile $DownloadPath; + + Write-Host ([string]::Format('Installing plugins into "{0}"', ($ModuleDirectory))); + Expand-IcingaZipArchive -Path $DownloadPath -Destination $ModuleDirectory | Out-Null; + + $FolderContent = Get-ChildItem -Path $ModuleDirectory; + $Extracted = ''; + + foreach ($entry in $FolderContent) { + if ($entry -eq 'icinga-powershell-plugins') { + # Skip the plugins directory directly + continue; + } + if ($entry -like 'icinga-powershell-plugins-*') { + $Extracted = $entry; + } + } + + if ([string]::IsNullOrEmpty($Extracted)) { + Write-Host 'No update package could be found.' + return @{ + 'PluginUrl' = $PluginsUrl + }; + } + + $NewDirectory = (Join-Path -Path $ModuleDirectory -ChildPath 'icinga-powershell-plugins'); + $ExtractDir = (Join-Path -Path $ModuleDirectory -ChildPath $Extracted); + $BackupDir = (Join-Path -Path $ExtractDir -ChildPath 'previous'); + $OldBackupDir = (Join-Path -Path $NewDirectory -ChildPath 'previous'); + + if ((Test-Path $NewDirectory)) { + Write-Host 'Creating backup directory'; + if ((Test-Path $OldBackupDir)) { + Write-Host 'Importing old backups into new module version...'; + Move-Item -Path $OldBackupDir -Destination $ExtractDir; + } else { + Write-Host 'No previous backups found. Creating new backup space'; + if ((Test-Path $BackupDir) -eq $FALSE) { + New-Item -Path $BackupDir -ItemType Container | Out-Null; + } + } + Write-Host 'Moving old module into backup directory'; + Move-Item -Path $NewDirectory -Destination (Join-Path -Path $BackupDir -ChildPath (Get-Date -Format "MM-dd-yyyy-HH-mm-ffff")); + } + + Write-Host ([string]::Format('Installing new module version "{0}"', $Tag)); + Start-Sleep -Seconds 2; + Move-Item -Path (Join-Path -Path $ModuleDirectory -ChildPath $Extracted) -Destination $NewDirectory; + + Unblock-IcingaPowerShellFiles -Path $NewDirectory; + # In case the plugins are not installed before, load the framework again to + # include the plugins + Use-Icinga; + + Write-Host 'Icinga Plugin update has been completed'; + + return @{ + 'PluginUrl' = $PluginsUrl + }; +} From 090d25f27e4d55807f9e796bf26092ba32e379b2 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 15:59:33 +0100 Subject: [PATCH 240/259] Fixes crashes on Framework updater, adds version check --- .../Install-IcingaFrameworkUpdate.psm1 | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 b/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 index eb5867c..a6b9d4f 100644 --- a/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 +++ b/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 @@ -5,10 +5,11 @@ function Install-IcingaFrameworkUpdate() ); $ProgressPreference = "SilentlyContinue"; + $Tag = 'Unknown'; if ([string]::IsNullOrEmpty($FrameworkUrl)) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you provide a custom repository of the framework?' -Default 'n').result -eq 1) { - $branch = (Read-IcingaWizardAnswerInput -Prompt 'Which version to you want to install? (snapshot/stable)' -Default 'v' -DefaultInput 'stable').answer + $branch = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Which version to you want to install? (snapshot/stable)' -Default 'v' -DefaultInput 'stable').answer if ($branch.ToLower() -eq 'snapshot') { $FrameworkUrl = 'https://github.com/Icinga/icinga-powershell-framework/archive/master.zip'; } else { @@ -16,6 +17,13 @@ function Install-IcingaFrameworkUpdate() $FrameworkUrl = $LatestRelease.Replace('/releases/tag/', '/archive/'); $Tag = $FrameworkUrl.Split('/')[-1]; $FrameworkUrl = [string]::Format('{0}/{1}.zip', $FrameworkUrl, $Tag); + + $CurrentVersion = Get-IcingaPowerShellModuleVersion 'icinga-powershell-framework'; + + if ($null -ne $CurrentVersion -And $CurrentVersion -eq $Tag) { + Write-Host 'Your Icinga Framework is already up-to-date'; + return; + } } } else { $FrameworkUrl = (Get-IcingaAgentInstallerAnswerInput -Prompt 'Please enter the full path to your icinga framework repository' -Default 'v').answer; @@ -23,7 +31,7 @@ function Install-IcingaFrameworkUpdate() } $ModuleDirectory = Get-IcingaFrameworkRootPath; - $DownloadPath = (Join-Path -Path $ENv:TEMP -ChildPath 'icinga-powershell-framework-zip'); + $DownloadPath = (Join-Path -Path $ENv:TEMP -ChildPath 'icinga-powershell-framework.zip'); Write-Host ([string]::Format('Downloading Icinga Framework into "{0}"', $DownloadPath)); Invoke-WebRequest -UseBasicParsing -Uri $FrameworkUrl -OutFile $DownloadPath; @@ -77,10 +85,11 @@ function Install-IcingaFrameworkUpdate() Move-Item -Path $NewDirectory -Destination (Join-Path -Path $BackupDir -ChildPath (Get-Date -Format "MM-dd-yyyy-HH-mm-ffff")); } - Write-Host 'Installing new module version'; - Move-Item -Path (Join-Path -Path $Destination -ChildPath $Extracted) -Destination $NewDirectory; + Write-Host ([string]::Format('Installing new module version "{0}"', $Tag)); + Start-Sleep -Seconds 2; + Move-Item -Path (Join-Path -Path $ModuleDirectory -ChildPath $Extracted) -Destination $NewDirectory; - Unblock-IcingaFramework -Path $NewDirectory; + Unblock-IcingaPowerShellFiles -Path $NewDirectory; Test-IcingaAgent; From 5039171707fb672819a4eb5a7fa586f228c40080 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 16:07:00 +0100 Subject: [PATCH 241/259] Fixes docs for kickstart script url --- doc/installation/01-KickstartScript.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/doc/installation/01-KickstartScript.md b/doc/installation/01-KickstartScript.md index 8ac9d1d..ae09dfb 100644 --- a/doc/installation/01-KickstartScript.md +++ b/doc/installation/01-KickstartScript.md @@ -12,7 +12,7 @@ Getting Started [Net.ServicePointManager]::SecurityProtocol = "tls12, tls11"; $ProgressPreference = "SilentlyContinue"; -$global:IcingaFrameworkKickstartSource = 'https://raw.githubusercontent.com/Icinga/icinga-framework-kickstart/master/script/icinga-framework-kickstart.ps1'; +$global:IcingaFrameworkKickstartSource = 'https://raw.githubusercontent.com/Icinga/icinga-powershell-kickstart/master/script/icinga-powershell-kickstart.ps1'; $Script = (Invoke-WebRequest -UseBasicParsing -Uri $global:IcingaFrameworkKickstartSource).Content; $Script += "`r`n`r`n Start-IcingaFrameworkWizard;"; From 6005a6203f7133a1053d03df41959066874658a5 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 16:15:46 +0100 Subject: [PATCH 242/259] Add missing IcingaSevices Cmdlet --- lib/core/tools/Get-IcingaServices.psm1 | 85 ++++++++++++++++++++++++++ 1 file changed, 85 insertions(+) create mode 100644 lib/core/tools/Get-IcingaServices.psm1 diff --git a/lib/core/tools/Get-IcingaServices.psm1 b/lib/core/tools/Get-IcingaServices.psm1 new file mode 100644 index 0000000..a6e5a0f --- /dev/null +++ b/lib/core/tools/Get-IcingaServices.psm1 @@ -0,0 +1,85 @@ +function Get-IcingaServices() +{ + param ( + [array]$Service + ); + + $ServiceInformation = Get-Service -Name $Service -ErrorAction SilentlyContinue; + $ServiceWmiInfo = $null; + + if ($Service.Count -eq 0) { + $ServiceWmiInfo = Get-WmiObject Win32_Service; + } else { + $ServiceWmiInfo = Get-WmiObject -Class Win32_Service | Where-Object { $Service -Contains $_.Name } | Select-Object StartName, Name; + } + + if ($null -eq $ServiceInformation) { + return $null; + } + + [hashtable]$ServiceData = @{}; + + foreach ($service in $ServiceInformation) { + + [array]$DependentServices = $null; + [array]$DependingServices = $null; + [string]$ServiceUser = ''; + + foreach ($wmiService in $ServiceWmiInfo) { + if ($wmiService.Name -eq $service.ServiceName) { + $ServiceUser = $wmiService.StartName; + break; + } + } + + #Dependent / Child + foreach ($dependency in $service.DependentServices) { + if ($null -eq $DependentServices) { + $DependentServices = @(); + } + $DependentServices += $dependency.Name; + } + + #Depends / Parent + foreach ($dependency in $service.ServicesDependedOn) { + if ($null -eq $DependingServices) { + $DependingServices = @(); + } + $DependingServices += $dependency.Name; + } + + $ServiceData.Add( + $service.Name, @{ + 'metadata' = @{ + 'DisplayName' = $service.DisplayName; + 'ServiceName' = $service.ServiceName; + 'Site' = $service.Site; + 'Container' = $service.Container; + 'ServiceHandle' = $service.ServiceHandle; + 'Dependent' = $DependentServices; + 'Depends' = $DependingServices; + }; + 'configuration' = @{ + 'CanPauseAndContinue' = $service.CanPauseAndContinue; + 'CanShutdown' = $service.CanShutdown; + 'CanStop' = $service.CanStop; + 'Status' = @{ + 'raw' = [int]$service.Status; + 'value' = $service.Status; + }; + 'ServiceType' = @{ + 'raw' = [int]$service.ServiceType; + 'value' = $service.ServiceType; + }; + 'ServiceHandle' = $service.ServiceHandle; + 'StartType' = @{ + 'raw' = [int]$service.StartType; + 'value' = $service.StartType; + }; + 'ServiceUser' = $ServiceUser; + } + } + ); + } + return $ServiceData; +} From f67224114a78cfc9357cc5adca01ba7721547757 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 16:31:02 +0100 Subject: [PATCH 243/259] Fixes cache folder permissions after update --- lib/core/framework/Install-IcingaFrameworkUpdate.psm1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 b/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 index a6b9d4f..bce23d5 100644 --- a/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 +++ b/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 @@ -90,6 +90,8 @@ function Install-IcingaFrameworkUpdate() Move-Item -Path (Join-Path -Path $ModuleDirectory -ChildPath $Extracted) -Destination $NewDirectory; Unblock-IcingaPowerShellFiles -Path $NewDirectory; + # Fix new permissions for cache folder + Set-IcingaAcl -Directory (Get-IcingaCacheDir); Test-IcingaAgent; From cfba374227fb6ac48c3603d82dd2aac12ee87d91 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 16:59:45 +0100 Subject: [PATCH 244/259] Fixes PowerShell daemon service registration --- lib/core/framework/Install-IcingaFrameworkService.psm1 | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/lib/core/framework/Install-IcingaFrameworkService.psm1 b/lib/core/framework/Install-IcingaFrameworkService.psm1 index ebf4db2..7fecc27 100644 --- a/lib/core/framework/Install-IcingaFrameworkService.psm1 +++ b/lib/core/framework/Install-IcingaFrameworkService.psm1 @@ -27,5 +27,11 @@ function Install-IcingaFrameworkService() throw ([string]::Format('Failed to install Icinga PowerShell Service: {0}{1}', $ServiceCreation.Message, $ServiceCreation.Error)); } + # This is just a hotfix to ensure we setup the service properly before assigning it to + # a proper user, like 'NT Authority\NetworkService'. For some reason the NetworkService + # will not start without this workaround. + # Todo: Figure out the reason and fix it properly + Set-IcingaAgentServiceUser -User 'LocalSystem' -Service 'icingapowershell' | Out-Null; + return (Set-IcingaAgentServiceUser -User $User -Password $Password -Service 'icingapowershell'); } From eb700279516de77952db553e6f7db38a75d66111 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 17:07:47 +0100 Subject: [PATCH 245/259] Add support to install plugins during setup wizard --- .../misc/Start-IcingaAgentInstallWizard.psm1 | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index 1cd10ae..7cddad4 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -34,7 +34,9 @@ function Start-IcingaAgentInstallWizard() [bool]$SkipDirectorQuestion = $FALSE, [string]$DirectorUrl, [string]$SelfServiceAPIKey = $null, - $OverrideDirectorVars = $null + $OverrideDirectorVars = $null, + $InstallFrameworkPlugins = $null, + $PluginsUrl = $null ); [array]$InstallerArguments = @(); @@ -363,6 +365,17 @@ function Start-IcingaAgentInstallWizard() } } + if ($null -eq $InstallFrameworkPlugins) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to install the Icinga Plugins?' -Default 'y').result -eq 1) { + $result = Install-IcingaFrameworkPlugins -PluginsUrl $PluginsUrl; + $PluginsUrl = $result.PluginsUrl; + $InstallerArguments += "-InstallFrameworkPlugins 1"; + $InstallerArguments += "-$PluginsUrl '$PluginsUrl'"; + } else { + $InstallerArguments += "-InstallFrameworkPlugins 0"; + } + } + if ($null -eq $InstallFrameworkService) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to install the PowerShell Framework as a Service?' -Default 'y').result -eq 1) { $result = Get-IcingaFrameworkServiceBinary; From 9209a4e671815f81aa6649401d3db31d1d83d724 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 17:32:17 +0100 Subject: [PATCH 246/259] Fixes the icingapowershell daemon as it has to run atleast once --- lib/core/framework/Install-IcingaFrameworkService.psm1 | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/core/framework/Install-IcingaFrameworkService.psm1 b/lib/core/framework/Install-IcingaFrameworkService.psm1 index 7fecc27..8c2a409 100644 --- a/lib/core/framework/Install-IcingaFrameworkService.psm1 +++ b/lib/core/framework/Install-IcingaFrameworkService.psm1 @@ -32,6 +32,9 @@ function Install-IcingaFrameworkService() # will not start without this workaround. # Todo: Figure out the reason and fix it properly Set-IcingaAgentServiceUser -User 'LocalSystem' -Service 'icingapowershell' | Out-Null; + Restart-IcingaService 'icingapowershell'; + Start-Sleep -Seconds 1; + Stop-IcingaService 'icingapowershell'; return (Set-IcingaAgentServiceUser -User $User -Password $Password -Service 'icingapowershell'); } From 709402e9c35430fc27f39650cfaccb111bf3b891 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 18:01:54 +0100 Subject: [PATCH 247/259] Add easier handling to set user permissions --- .../icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 | 6 +----- .../icingaagent/setters/Set-IcingaAgentServiceUser.psm1 | 8 +++++++- .../icingaagent/setters/Set-IcingaUserPermissions.psm1 | 7 +++++++ 3 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 lib/core/icingaagent/setters/Set-IcingaUserPermissions.psm1 diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index 7cddad4..19057d9 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -421,11 +421,7 @@ function Start-IcingaAgentInstallWizard() if ($RunInstaller) { if ((Install-IcingaAgent -Version $AgentVersion -Source $PackageSource -AllowUpdates $AllowVersionChanges) -Or $Reconfigure) { Move-IcingaAgentDefaultConfig; - Set-IcingaAgentServiceUser -User $ServiceUser -Password $ServicePass | Out-Null; - Set-IcingaAgentServicePermission | Out-Null; - Set-IcingaAcl "$Env:ProgramData\icinga2\etc"; - Set-IcingaAcl "$Env:ProgramData\icinga2\var"; - Set-IcingaAcl (Get-IcingaCacheDir); + Set-IcingaAgentServiceUser -User $ServiceUser -Password $ServicePass -SetPermission | Out-Null; Install-IcingaFrameworkService -Path $ServiceBin -User $ServiceUser -Password $ServicePass | Out-Null; Register-IcingaBackgroundDaemon -Command 'Start-IcingaServiceCheckDaemon'; Install-IcingaAgentBaseFeatures; diff --git a/lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 b/lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 index d627efe..b105821 100644 --- a/lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 +++ b/lib/core/icingaagent/setters/Set-IcingaAgentServiceUser.psm1 @@ -3,7 +3,8 @@ function Set-IcingaAgentServiceUser() param( [string]$User, [securestring]$Password, - [string]$Service = 'icinga2' + [string]$Service = 'icinga2', + [switch]$SetPermission ); if ([string]::IsNullOrEmpty($User)) { @@ -26,6 +27,11 @@ function Set-IcingaAgentServiceUser() -FlushNewLines $TRUE; if ($Output.ExitCode -eq 0) { + + if ($SetPermission) { + Set-IcingaUserPermissions; + } + Write-Host 'Service User successfully updated' return $TRUE; } else { diff --git a/lib/core/icingaagent/setters/Set-IcingaUserPermissions.psm1 b/lib/core/icingaagent/setters/Set-IcingaUserPermissions.psm1 new file mode 100644 index 0000000..e1123d0 --- /dev/null +++ b/lib/core/icingaagent/setters/Set-IcingaUserPermissions.psm1 @@ -0,0 +1,7 @@ +function Set-IcingaUserPermissions() +{ + Set-IcingaAgentServicePermission | Out-Null; + Set-IcingaAcl "$Env:ProgramData\icinga2\etc"; + Set-IcingaAcl "$Env:ProgramData\icinga2\var"; + Set-IcingaAcl (Get-IcingaCacheDir); +} From 47a505ea775a4044cf79edf6033fdb968f7cc1c3 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 19:22:28 +0100 Subject: [PATCH 248/259] Add support for managing Windows Firewall config --- .../firewall/Disable-IcingaFirewall.psm1 | 30 ++++++++++++++++ .../firewall/Enable-IcingaFirewall.psm1 | 35 ++++++++++++++++++ .../firewall/Get-IcingaFirewallConfig.psm1 | 36 +++++++++++++++++++ .../misc/Start-IcingaAgentInstallWizard.psm1 | 20 +++++++++++ 4 files changed, 121 insertions(+) create mode 100644 lib/core/icingaagent/firewall/Disable-IcingaFirewall.psm1 create mode 100644 lib/core/icingaagent/firewall/Enable-IcingaFirewall.psm1 create mode 100644 lib/core/icingaagent/firewall/Get-IcingaFirewallConfig.psm1 diff --git a/lib/core/icingaagent/firewall/Disable-IcingaFirewall.psm1 b/lib/core/icingaagent/firewall/Disable-IcingaFirewall.psm1 new file mode 100644 index 0000000..749d17c --- /dev/null +++ b/lib/core/icingaagent/firewall/Disable-IcingaFirewall.psm1 @@ -0,0 +1,30 @@ +function Disable-IcingaFirewall() +{ + param( + [switch]$LegacyOnly + ); + + $FirewallConfig = Get-IcingaFirewallConfig -NoOutput; + + if ($FirewallConfig.LegacyFirewall) { + $Firewall = Start-IcingaProcess -Executable 'netsh' -Arguments 'advfirewall firewall delete rule name="Icinga 2 Agent Inbound by PS-Module"'; + if ($Firewall.ExitCode -ne 0) { + Write-Host ([string]::Format('Failed to remove legacy firewall: {0}{1}', $Firewall.Message, $Firewall.Error)); + } else { + Write-Host 'Successfully removed legacy Firewall rule'; + } + } + + if ($LegacyOnly) { + return; + } + + if ($FirewallConfig.IcingaFirewall) { + $Firewall = Start-IcingaProcess -Executable 'netsh' -Arguments 'advfirewall firewall delete rule name="Icinga Agent Inbound"'; + if ($Firewall.ExitCode -ne 0) { + Write-Host ([string]::Format('Failed to remove Icinga firewall: {0}{1}', $Firewall.Message, $Firewall.Error)); + } else { + Write-Host 'Successfully removed Icinga Firewall rule'; + } + } +} diff --git a/lib/core/icingaagent/firewall/Enable-IcingaFirewall.psm1 b/lib/core/icingaagent/firewall/Enable-IcingaFirewall.psm1 new file mode 100644 index 0000000..88b353c --- /dev/null +++ b/lib/core/icingaagent/firewall/Enable-IcingaFirewall.psm1 @@ -0,0 +1,35 @@ +function Enable-IcingaFirewall() +{ + param( + [int]$IcingaPort = 5665, + [switch]$Force + ); + + $FirewallConfig = Get-IcingaFirewallConfig -NoOutput; + + if ($FirewallConfig.IcingaFirewall -And $Force -eq $FALSE) { + Write-Host 'Icinga Firewall is already enabled' + return; + } + + if ($Force) { + Disable-IcingaFirewall; + } + + $IcingaBinary = Get-IcingaAgentBinary; + [string]$FirewallRule = [string]::Format( + 'advfirewall firewall add rule dir=in action=allow program="{0}" name="{1}" description="{2}" enable=yes remoteip=any localip=any localport={3} protocol=tcp', + $IcingaBinary, + 'Icinga Agent Inbound', + 'Inbound Firewall Rule to allow Icinga 2 masters / satellites to connect to the Icinga 2 Agent installed on this system.', + $IcingaPort + ); + + $FirewallResult = Start-IcingaProcess -Executable 'netsh' -Arguments $FirewallRule; + + if ($FirewallResult.ExitCode -ne 0) { + Write-Host ([string]::Format('Failed to open Icinga firewall for port "{0}": {1}[2}', $IcingaPort, $FirewallResult.Message, $FirewallResult.Error)); + } else { + Write-Host ([string]::Format('Successfully enabled firewall for port "{0}"', $IcingaPort)); + } +} diff --git a/lib/core/icingaagent/firewall/Get-IcingaFirewallConfig.psm1 b/lib/core/icingaagent/firewall/Get-IcingaFirewallConfig.psm1 new file mode 100644 index 0000000..6caa144 --- /dev/null +++ b/lib/core/icingaagent/firewall/Get-IcingaFirewallConfig.psm1 @@ -0,0 +1,36 @@ +function Get-IcingaFirewallConfig() +{ + param( + [switch]$NoOutput + ); + + [bool]$LegacyFirewallPresent = $FALSE; + [bool]$IcingaFirewallPresent = $FALSE; + + $LegacyFirewall = Start-IcingaProcess -Executable 'netsh' -Arguments 'advfirewall firewall show rule name="Icinga 2 Agent Inbound by PS-Module"'; + + if ($LegacyFirewall.ExitCode -eq 0) { + if ($NoOutput -eq $FALSE) { + Write-Host 'Legacy firewall configuration has been detected.'; + } + $LegacyFirewallPresent = $TRUE; + } + + $IcingaFirewall = Start-IcingaProcess -Executable 'netsh' -Arguments 'advfirewall firewall show rule name="Icinga Agent Inbound"'; + + if ($IcingaFirewall.ExitCode -eq 0) { + if ($NoOutput -eq $FALSE) { + Write-Host 'Icinga firewall is present.'; + } + $IcingaFirewallPresent = $TRUE; + } else { + if ($NoOutput -eq $FALSE) { + Write-Host 'Icinga firewall is not present'; + } + } + + return @{ + 'LegacyFirewall' = $LegacyFirewallPresent; + 'IcingaFirewall' = $IcingaFirewallPresent; + } +} diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index 19057d9..837fbf8 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -12,6 +12,7 @@ function Start-IcingaAgentInstallWizard() [string]$AgentVersion, $AllowVersionChanges, $UpdateAgent = $null, + $AddFirewallRule = $null, $AcceptConnections = $null, [array]$Endpoints = @(), [array]$EndpointConnections = @(), @@ -99,6 +100,9 @@ function Start-IcingaAgentInstallWizard() $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AcceptConnections' -Value $AcceptConnections -InstallerArguments $InstallerArguments; $AcceptConnections = $Result.Value; $InstallerArguments = $Result.Args; + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'AddFirewallRule' -Value $AddFirewallRule -InstallerArguments $InstallerArguments; + $AddFirewallRule = $Result.Value; + $InstallerArguments = $Result.Args; $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'ServiceUser' -Value $ServiceUser -InstallerArguments $InstallerArguments; $ServiceUser = $Result.Value; $InstallerArguments = $Result.Args; @@ -239,6 +243,18 @@ function Start-IcingaAgentInstallWizard() } } + if ($AcceptConnections -eq 0) { + if ($null -eq $AddFirewallRule) { + if ((Get-IcingaAgentInstallerAnswerInput -Prompt ([string]::Format('Do you want to open the Windows Firewall for incoming traffic on Port "{0}"?', $CAPort)) -Default 'y').result -eq 1) { + $InstallerArguments += "-AddFirewallRule 1"; + $AddFirewallRule = $TRUE; + } else { + $InstallerArguments += "-AddFirewallRule 0"; + $AddFirewallRule = $FALSE; + } + } + } + if ($EndpointConnections.Count -eq 0 -And $AcceptConnections -eq 1) { $NetworkDefault = ''; foreach ($Endpoint in $Endpoints) { @@ -428,6 +444,10 @@ function Start-IcingaAgentInstallWizard() Install-IcingaAgentCertificates -Hostname $Hostname -Endpoint $CAEndpoint -Port $CAPort -CACert $CAFile -Ticket $Ticket | Out-Null; Write-IcingaAgentApiConfig -Port $CAPort; Write-IcingaAgentZonesConfig -Endpoints $Endpoints -EndpointConnections $EndpointConnections -ParentZone $ParentZone -GlobalZones $GlobalZoneConfig -Hostname $Hostname; + if ($AddFirewallRule) { + # First cleanup the system by removing all old Firewalls + Enable-IcingaFirewall -IcingaPort $CAPort -Force; + } Test-IcingaAgent; Restart-IcingaService 'icingapowershell'; Restart-IcingaService 'icinga2'; From 011cf54d1c51ef644264639ee8df712037f01d6e Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 19:32:41 +0100 Subject: [PATCH 249/259] Fixes CA endpoint configuration --- .../misc/Convert-IcingaDirectorSelfServiceArguments.psm1 | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/lib/core/icingaagent/misc/Convert-IcingaDirectorSelfServiceArguments.psm1 b/lib/core/icingaagent/misc/Convert-IcingaDirectorSelfServiceArguments.psm1 index 156bc8d..f6cf406 100644 --- a/lib/core/icingaagent/misc/Convert-IcingaDirectorSelfServiceArguments.psm1 +++ b/lib/core/icingaagent/misc/Convert-IcingaDirectorSelfServiceArguments.psm1 @@ -15,7 +15,7 @@ function Convert-IcingaDirectorSelfServiceArguments() AllowVersionChanges = $JsonInput.allow_updates; GlobalZones = $JsonInput.global_zones; ParentZone = $JsonInput.parent_zone; - CAEndpoint = $JsonInput.ca_server; + #CAEndpoint = $JsonInput.ca_server; Endpoints = $JsonInput.parent_endpoints; AddFirewallRule = $JsonInput.agent_add_firewall_rule; AcceptConnections = $JsonInput.agent_add_firewall_rule; @@ -58,6 +58,11 @@ function Convert-IcingaDirectorSelfServiceArguments() $DirectorArguments.Add( 'EndpointConnections', $NetworkDefault ); + + $EndpointConnections = $NetworkDefault.Split(','); + $DirectorArguments.Add( + 'CAEndpoint', (Get-IPConfigFromString $EndpointConnections[0]).address + ); } return $DirectorArguments; From 64458d2bcbcb9bb47d1dd4219ed414e293a3a32a Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 19:47:42 +0100 Subject: [PATCH 250/259] Fixes missing Icinga CA Ticket handling --- .../icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 | 8 +++++--- .../icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 | 2 ++ 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 index b8ad7a2..855e894 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentDirectorWizard.psm1 @@ -51,9 +51,6 @@ function Start-IcingaAgentDirectorWizard() } if ($HostKnown -eq $FALSE) { - Write-Host $SelfServiceAPIKey; - Write-Host (Get-IcingaHostname @Arguments); - Write-Host $DirectorUrl; $SelfServiceAPIKey = Register-IcingaDirectorSelfServiceHost -DirectorUrl $DirectorUrl -ApiKey $SelfServiceAPIKey -Hostname (Get-IcingaHostname @Arguments); # Host is already registered @@ -74,9 +71,14 @@ function Start-IcingaAgentDirectorWizard() } } + $IcingaTicket = Get-IcingaDirectorSelfServiceTicket -DirectorUrl $DirectorUrl -ApiKey $SelfServiceAPIKey; + $DirectorOverrideArgs.Add( 'DirectorUrl', $DirectorUrl ); + $DirectorOverrideArgs.Add( + 'Ticket', $IcingaTicket + ); if ([string]::IsNullOrEmpty($TemplateKey) -eq $FALSE) { $DirectorOverrideArgs.Add( 'SelfServiceAPIKey', $TemplateKey diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index 837fbf8..e7083b0 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -70,6 +70,8 @@ function Start-IcingaAgentInstallWizard() $SelfServiceAPIKey = $Result.Value; $InstallerArguments = $Result.Args; } + $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'Ticket' -Value $Ticket -InstallerArguments $InstallerArguments; + $Ticket = $Result.Value; $Result = Set-IcingaWizardArgument -DirectorArgs $DirectorArgs -WizardArg 'PackageSource' -Value $PackageSource -InstallerArguments $InstallerArguments; $PackageSource = $Result.Value; $InstallerArguments = $Result.Args; From ed733881f01e8c771c5433fedccad185aeae5d79 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 19:55:24 +0100 Subject: [PATCH 251/259] Fixes Plugin Url repo binding --- lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index e7083b0..9272fda 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -386,9 +386,9 @@ function Start-IcingaAgentInstallWizard() if ($null -eq $InstallFrameworkPlugins) { if ((Get-IcingaAgentInstallerAnswerInput -Prompt 'Do you want to install the Icinga Plugins?' -Default 'y').result -eq 1) { $result = Install-IcingaFrameworkPlugins -PluginsUrl $PluginsUrl; - $PluginsUrl = $result.PluginsUrl; + $PluginsUrl = $result.PluginUrl; $InstallerArguments += "-InstallFrameworkPlugins 1"; - $InstallerArguments += "-$PluginsUrl '$PluginsUrl'"; + $InstallerArguments += "-PluginsUrl '$PluginsUrl'"; } else { $InstallerArguments += "-InstallFrameworkPlugins 0"; } From 05f67d6a1a095e33b6425e0b01d0c27979678ea6 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 20:08:43 +0100 Subject: [PATCH 252/259] Fixes accidental conversion of array to string while they should be arrays --- .../misc/Start-IcingaAgentInstallWizard.psm1 | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 index 9272fda..e5c25f0 100644 --- a/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 +++ b/lib/core/icingaagent/misc/Start-IcingaAgentInstallWizard.psm1 @@ -474,7 +474,7 @@ function Set-IcingaWizardArgument() } $InstallerArguments += "-$WizardArg $Override"; return @{ - 'Value' = $Override; + 'Value' = $DirectorArgs.Overrides[$WizardArg]; 'Args' = $InstallerArguments; }; } @@ -483,15 +483,13 @@ function Set-IcingaWizardArgument() if ($DirectorArgs.Arguments.ContainsKey($WizardArg)) { $RetValue = $DirectorArgs.Arguments[$WizardArg]; - if ($Value -is [array]) { - $RetValue = [string]::Join(',', $RetValue); - } } else { if ($null -ne $Value -Or [string]::IsNullOrEmpty($Value) -eq $FALSE) { + $TmpValue = $Value; if ($Value -is [array]) { - $Value = [string]::Join(',', $Value); + $TmpValue = [string]::Join(',', $TmpValue); } - $InstallerArguments += "-$WizardArg $Value"; + $InstallerArguments += "-$WizardArg $TmpValue"; return @{ 'Value' = $Value; 'Args' = $InstallerArguments; @@ -505,10 +503,11 @@ function Set-IcingaWizardArgument() } if ([string]::IsNullOrEmpty($Value) -eq $FALSE) { + $TmpValue = $Value; if ($Value -is [array]) { - $Value = [string]::Join(',', $Value); + $TmpValue = [string]::Join(',', $Value); } - $InstallerArguments += "-$WizardArg $Value"; + $InstallerArguments += "-$WizardArg $TmpValue"; return @{ 'Value' = $Value; 'Args' = $InstallerArguments; From 71e90a8ab5f309b1d33cbf52267144c3613fecc0 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 21:43:00 +0100 Subject: [PATCH 253/259] Remove disclaimer note in README.md --- README.md | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/README.md b/README.md index 5654e5f..bde1421 100644 --- a/README.md +++ b/README.md @@ -1,9 +1,7 @@ Icinga Module for Windows ============== -**This Module is a Technical-Preview and should **NOT** be used actively in production!** - -The Icinga PowerShell Framework provides a wide range of configurarion and check possibilities to ensure an easy integration and full monitoring of windows environments. +The Icinga PowerShell Framework provides a wide range of configuration and check possibilities to ensure an easy integration and full monitoring of Windows environments. Each single chapter of this documentation will describe parts of the module and the possibilities. Before you continue, please take a look on the [installation guide](doc/02-Installation.md) From be24dbff2d19009ea4676a54f55de174e6a5704c Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 21:44:29 +0100 Subject: [PATCH 254/259] Add support for long-term caching of check metrics --- .../Start-IcingaServiceCheckDaemon.psm1 | 23 +++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/lib/daemons/ServiceCheckDaemon/Start-IcingaServiceCheckDaemon.psm1 b/lib/daemons/ServiceCheckDaemon/Start-IcingaServiceCheckDaemon.psm1 index bff4d41..afbaa08 100644 --- a/lib/daemons/ServiceCheckDaemon/Start-IcingaServiceCheckDaemon.psm1 +++ b/lib/daemons/ServiceCheckDaemon/Start-IcingaServiceCheckDaemon.psm1 @@ -46,6 +46,7 @@ function Start-IcingaServiceCheckTask() $PassedTime = 0; $SortedResult = $null; $OldData = @{}; + $PerfCache = @{}; if (-Not ($IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler.ContainsKey($CheckCommand))) { $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler.Add($CheckCommand, [hashtable]::Synchronized(@{})); @@ -53,6 +54,23 @@ function Start-IcingaServiceCheckTask() $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand].Add('average', [hashtable]::Synchronized(@{})); } + $LoadedCacheData = Get-IcingaCacheData -Space 'sc_daemon' -CacheStore 'checkresult_store' -KeyName $CheckCommand; + + if ($null -ne $LoadedCacheData) { + foreach ($entry in $LoadedCacheData.PSObject.Properties) { + $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand]['results'].Add( + $entry.name, + [hashtable]::Synchronized(@{}) + ); + foreach ($item in $entry.Value.PSObject.Properties) { + $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand]['results'][$entry.name].Add( + $item.Name, + $item.Value + ); + } + } + } + while ($TRUE) { if ($PassedTime -ge $Interval) { try { @@ -63,6 +81,7 @@ function Start-IcingaServiceCheckTask() foreach ($result in $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand]['results'].Keys) { $SortedResult = $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand]['results'][$result].GetEnumerator() | Sort-Object name -Descending; Add-IcingaHashtableItem -Hashtable $OldData -Key $result -Value @{}; + Add-IcingaHashtableItem -Hashtable $PerfCache -Key ([string]$result) -Value @{}; foreach ($index in $TimeIndexes) { $ObjectCount = 0; @@ -74,6 +93,7 @@ function Start-IcingaServiceCheckTask() $ObjectCount += 1; $ObjectValue += $timeEntry.Value; Remove-IcingaHashtableItem -Hashtable $OldData[$result] -Key $timeEntry; + Add-IcingaHashtableItem -Hashtable $PerfCache[$result] -Key ([string]$timeEntry.Key) -Value ([string]$timeEntry.Value); } else { Add-IcingaHashtableItem -Hashtable $OldData[$result] -Key $timeEntry -Value $null; } @@ -96,6 +116,8 @@ function Start-IcingaServiceCheckTask() } Set-IcingaCacheData -Space 'sc_daemon' -CacheStore 'checkresult' -KeyName $CheckCommand -Value $IcingaDaemonData.BackgroundDaemon.ServiceCheckScheduler[$CheckCommand]['average']; + # Write collected metrics to disk in case we reload the daemon. We will load them back into the module after reload then + Set-IcingaCacheData -Space 'sc_daemon' -CacheStore 'checkresult_store' -KeyName $CheckCommand -Value $PerfCache; } catch { # Todo: Add error reporting / handling } @@ -103,6 +125,7 @@ function Start-IcingaServiceCheckTask() $PassedTime = 0; $SortedResult = $null; $OldData = @{}; + $PerfCache = @{}; } $PassedTime += 1; Start-Sleep -Seconds 1; From f3b19145ac6154ee1ccc76f121137ac44baec735 Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 22:17:31 +0100 Subject: [PATCH 255/259] Add service start/stop if required while upgrading framework --- lib/core/framework/Install-IcingaFrameworkUpdate.psm1 | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 b/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 index bce23d5..ee00576 100644 --- a/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 +++ b/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 @@ -57,6 +57,12 @@ function Install-IcingaFrameworkUpdate() return; } + $ServiceStatus = (Get-Service 'icingapowershell' -ErrorAction SilentlyContinue).Status; + + if ($ServiceStatus -eq 'Running') { + Stop-IcingaService 'icingapowershell'; + } + $NewDirectory = (Join-Path -Path $ModuleDirectory -ChildPath 'icinga-powershell-framework'); $ExtractDir = (Join-Path -Path $ModuleDirectory -ChildPath $Extracted); $BackupDir = (Join-Path -Path $ExtractDir -ChildPath 'previous'); @@ -95,5 +101,9 @@ function Install-IcingaFrameworkUpdate() Test-IcingaAgent; + if ($ServiceStatus -eq 'Running') { + Start-IcingaService 'icingapowershell'; + } + Write-Host 'Framework update has been completed'; } From 8e62cdb8366464a64f8e018e03b1636d7706645a Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 22:19:06 +0100 Subject: [PATCH 256/259] Fixed missing config migration during upgrade --- lib/core/framework/Install-IcingaFrameworkUpdate.psm1 | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 b/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 index ee00576..e84b8b0 100644 --- a/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 +++ b/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 @@ -77,6 +77,10 @@ function Install-IcingaFrameworkUpdate() Write-Host 'Importing custom modules into new module version...'; Copy-Item -Path (Join-Path -Path $NewDirectory -ChildPath 'custom') -Destination $ExtractDir -Force -Recurse; } + if ((Test-Path (Join-Path -Path $NewDirectory -ChildPath 'config'))) { + Write-Host 'Importing config into new module version...'; + Copy-Item -Path (Join-Path -Path $NewDirectory -ChildPath 'config') -Destination $ExtractDir -Force -Recurse; + } Write-Host 'Creating backup directory'; if ((Test-Path $OldBackupDir)) { Write-Host 'Importing old backups into new module version...'; From 6ffd3ac0ec9b088292e07ca15ad1bb80ebdf6f9b Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 22:44:35 +0100 Subject: [PATCH 257/259] Remove remaining legacy code of module --- core/config.ps1 | 142 ------- core/include/APIResponse.ps1 | 100 ----- core/include/App.ps1 | 15 - core/include/Checker.ps1 | 105 ----- core/include/ClientJobs.ps1 | 292 -------------- core/include/ClientProtocol.ps1 | 225 ----------- core/include/Config.ps1 | 24 -- core/include/Enums.ps1 | 83 ---- core/include/Log.ps1 | 128 ------ core/include/NetworkProtocol.ps1 | 192 --------- core/include/PidManager.ps1 | 149 ------- core/include/ServerProtocol.ps1 | 223 ----------- core/include/Service.ps1 | 183 --------- core/include/System.ps1 | 23 -- core/include/TCPDaemon.ps1 | 76 ---- core/include/TCPSocket.ps1 | 161 -------- core/include/Utils.ps1 | 12 - core/include/utils/AdminShell.ps1 | 12 - core/include/utils/AuthHelper.ps1 | 63 --- core/include/utils/IniParser.ps1 | 75 ---- core/include/utils/Modules.ps1 | 154 ------- core/include/utils/SSL.ps1 | 111 ------ core/include/utils/SecureString.ps1 | 29 -- core/include/utils/WebHelper.ps1 | 296 -------------- core/init.ps1 | 100 ----- core/monitoring.ps1 | 118 ------ core/perfcounter.ps1 | 577 --------------------------- core/setup.ps1 | 97 ----- modules/bios.ps1 | 21 - modules/certificates.ps1 | 112 ------ modules/cpu.ps1 | 18 - modules/disk.ps1 | 96 ----- modules/hardware.ps1 | 6 - modules/include/hardware/cpu.ps1 | 19 - modules/include/hardware/disks.ps1 | 70 ---- modules/include/hardware/memory.ps1 | 59 --- modules/include/updates/hotfixes.ps1 | 27 -- modules/include/updates/pending.ps1 | 76 ---- modules/include/updates/updates.ps1 | 72 ---- modules/memory.ps1 | 32 -- modules/network.ps1 | 154 ------- modules/ntp.ps1 | 34 -- modules/process.ps1 | 113 ------ modules/services.ps1 | 62 --- modules/updates.ps1 | 6 - modules/windows.ps1 | 16 - 46 files changed, 4758 deletions(-) delete mode 100644 core/config.ps1 delete mode 100644 core/include/APIResponse.ps1 delete mode 100644 core/include/App.ps1 delete mode 100644 core/include/Checker.ps1 delete mode 100644 core/include/ClientJobs.ps1 delete mode 100644 core/include/ClientProtocol.ps1 delete mode 100644 core/include/Config.ps1 delete mode 100644 core/include/Enums.ps1 delete mode 100644 core/include/Log.ps1 delete mode 100644 core/include/NetworkProtocol.ps1 delete mode 100644 core/include/PidManager.ps1 delete mode 100644 core/include/ServerProtocol.ps1 delete mode 100644 core/include/Service.ps1 delete mode 100644 core/include/System.ps1 delete mode 100644 core/include/TCPDaemon.ps1 delete mode 100644 core/include/TCPSocket.ps1 delete mode 100644 core/include/Utils.ps1 delete mode 100644 core/include/utils/AdminShell.ps1 delete mode 100644 core/include/utils/AuthHelper.ps1 delete mode 100644 core/include/utils/IniParser.ps1 delete mode 100644 core/include/utils/Modules.ps1 delete mode 100644 core/include/utils/SSL.ps1 delete mode 100644 core/include/utils/SecureString.ps1 delete mode 100644 core/include/utils/WebHelper.ps1 delete mode 100644 core/init.ps1 delete mode 100644 core/monitoring.ps1 delete mode 100644 core/perfcounter.ps1 delete mode 100644 core/setup.ps1 delete mode 100644 modules/bios.ps1 delete mode 100644 modules/certificates.ps1 delete mode 100644 modules/cpu.ps1 delete mode 100644 modules/disk.ps1 delete mode 100644 modules/hardware.ps1 delete mode 100644 modules/include/hardware/cpu.ps1 delete mode 100644 modules/include/hardware/disks.ps1 delete mode 100644 modules/include/hardware/memory.ps1 delete mode 100644 modules/include/updates/hotfixes.ps1 delete mode 100644 modules/include/updates/pending.ps1 delete mode 100644 modules/include/updates/updates.ps1 delete mode 100644 modules/memory.ps1 delete mode 100644 modules/network.ps1 delete mode 100644 modules/ntp.ps1 delete mode 100644 modules/process.ps1 delete mode 100644 modules/services.ps1 delete mode 100644 modules/updates.ps1 delete mode 100644 modules/windows.ps1 diff --git a/core/config.ps1 b/core/config.ps1 deleted file mode 100644 index 0f80ab4..0000000 --- a/core/config.ps1 +++ /dev/null @@ -1,142 +0,0 @@ -param( - [string]$AddKey = '', - [Object]$AddValue = '', - [string]$GetConfig = '', - [string]$RemoveConfig = '', - [boolean]$ListConfig = $FALSE, - [boolean]$Reload = $FALSE -); - -function ClassConfig() -{ - param( - [string]$AddKey = '', - [Object]$AddValue = '', - [string]$GetConfig = '', - [string]$RemoveConfig = '', - [boolean]$ListConfig = $FALSE, - [boolean]$Reload = $FALSE - ); - - $instance = New-Object -TypeName PSObject; - - $instance | Add-Member -membertype NoteProperty -name 'ConfigDirectory' -value (Join-Path $Icinga2.App.RootPath -ChildPath 'agent\config'); - $instance | Add-Member -membertype NoteProperty -name 'ConfigFile' -value (Join-Path $instance.ConfigDirectory -ChildPath 'config.conf'); - - $instance | Add-Member -membertype ScriptMethod -name 'Init' -value { - if ($ListConfig) { - return $this.DumpConfig(); - } - - if ($Reload) { - return $this.ReloadConfig(); - } - - if ([string]::IsNullOrEmpty($GetConfig) -eq $FALSE) { - return $this.GetAttribute(); - } - - if ([string]::IsNullOrEmpty($AddKey) -eq $FALSE) { - return $this.SetAttribute(); - } - - if ([string]::IsNullOrEmpty($RemoveConfig) -eq $FALSE) { - return $this.RemoveAttribute(); - } - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - '{ Invalid or insufficient arguments specified. }' - ); - return 1; - } - - $instance | Add-Member -membertype ScriptMethod -name 'ReloadConfig' -value { - $Icinga2.Config = & (Join-Path $Icinga2.App.RootPath -ChildPath '\core\include\Config.ps1'); - } - - $instance | Add-Member -membertype ScriptMethod -name 'WriteConfig' -value { - If ((Test-Path ($this.ConfigDirectory)) -eq $FALSE) { - $Icinga2.Log.WriteConsole( - $Icinga2.Enums.LogState.Warning, - 'Config Directory is not present. Please run "Icinga-Setup" for the base installation' - ); - return 1; - } - $config = ConvertTo-Json $Icinga2.Config -Depth 100; - [System.IO.File]::WriteAllText($this.ConfigFile, $config); - return 0; - } - - $instance | Add-Member -membertype ScriptMethod -name 'DumpConfig' -value { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - ([string]::Format('Config location: {0}', $this.ConfigFile)) - ); - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - $Icinga2.Config - ); - return 0; - } - - $instance | Add-Member -membertype ScriptMethod -name 'GetAttribute' -value { - return $Icinga2.Config.$GetConfig; - } - - $instance | Add-Member -membertype ScriptMethod -name 'SetAttribute' -value { - $value = $AddValue; - - if ([string]::IsNullOrEmpty($AddValue)) { - $value = $null; - } - - if ([bool]($Icinga2.Config.PSobject.Properties.Name -eq $AddKey) -eq $FALSE) { - $Icinga2.Config | Add-Member -membertype NoteProperty -name $AddKey -value $value; - } else { - $Icinga2.Config.$AddKey = $value; - } - - if ($this.WriteConfig() -eq 0) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - ([string]::Format('{0} Set config attribute "{1}" to "{2}. {3}', '{', $AddKey, $value, '}')) - ); - return 0; - } - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Error, - ([string]::Format('{0} Unable to write config file to disk. Failed to update attribute "{1}" to "{2}. {3}', '{', $AddKey, $value, '}')) - ); - return 1; - } - - $instance | Add-Member -membertype ScriptMethod -name 'RemoveAttribute' -value { - if ([bool]($Icinga2.Config.PSobject.Properties.Name -eq $RemoveConfig) -eq $TRUE) { - $Icinga2.Config.PSobject.Members.Remove($RemoveConfig); - if ($this.WriteConfig() -eq 0) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - ([string]::Format('{0} Successfully removed config attribute "{1}" {2}', '{', $RemoveConfig, '}')) - ); - return 0; - } - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Error, - ([string]::Format('{0} Config attribute "{1}" was removed, but storing the new config file failed. {2}', '{', $RemoveConfig, '}')) - ); - return 1; - } - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - ([string]::Format('{0} Unable to remove attribute "{1}". Attribute not found {2}', '{', $RemoveConfig, '}')) - ); - return 1; - } - - return $instance.Init(); -} - -return ClassConfig -AddKey $AddKey -AddValue $AddValue -GetConfig $GetConfig -RemoveConfig $RemoveConfig -ListConfig $ListConfig -Reload $Reload; \ No newline at end of file diff --git a/core/include/APIResponse.ps1 b/core/include/APIResponse.ps1 deleted file mode 100644 index 12137f3..0000000 --- a/core/include/APIResponse.ps1 +++ /dev/null @@ -1,100 +0,0 @@ -$APIResponse = New-Object -TypeName PSObject; - -$APIResponse | Add-Member -membertype NoteProperty -name 'static' -value $FALSE; -$APIResponse | Add-Member -membertype NoteProperty -name 'statuscode' -value 200; -$APIResponse | Add-Member -membertype NoteProperty -name 'message' -value ''; -$APIResponse | Add-Member -membertype NoteProperty -name 'content' -value $null; -$APIResponse | Add-Member -membertype NoteProperty -name 'authheader' -value ''; - -$APIResponse | Add-Member -membertype ScriptMethod -name 'setContent' -value { - param([object]$content); - - $this.content = $content; -} - -$APIResponse | Add-Member -membertype ScriptMethod -name 'CustomBadRequest' -value { - param([string]$message); - - $this.statuscode = 400; - $this.message = $message; -} - -$APIResponse | Add-Member -membertype ScriptMethod -name 'InternalServerError' -value { - $this.statuscode = 500; - $this.message = 'An internal server error occured while parsing your request.'; -} - -$APIResponse | Add-Member -membertype ScriptMethod -name 'HTTPSRequired' -value { - $this.statuscode = 403; - $this.message = 'This API only supports connections over HTTPS.'; -} - -$APIResponse | Add-Member -membertype ScriptMethod -name 'AuthenticationRequired' -value { - $this.statuscode = 401; - $this.message = 'You require to login in order to access this ressource.'; - $this.authheader = [string]::Format( - 'WWW-Authenticate: Basic realm="Icinga Windows Daemon"{0}', - "`r`n" - ); -} - -$APIResponse | Add-Member -membertype ScriptMethod -name 'CompileMessage' -value { - # If our message is empty, do nothing - if ([string]::IsNullOrEmpty($this.message)) { - return; - } - - # In case we assigned custom content, do not override this content - if ($this.content -ne $null) { - return; - } - - $this.content = @{ - response = $this.statuscode; - message = $this.message; - }; -} - -$APIResponse | Add-Member -membertype ScriptMethod -name 'Compile' -value { - - $this.CompileMessage(); - - [string]$ContentLength = ''; - [string]$HTMLContent = ''; - if ($this.content -ne $null) { - $json = ConvertTo-Json $this.content -Depth 100 -Compress; - $bytes = [System.Text.Encoding]::UTF8.GetBytes($json); - $HTMLContent = [System.Text.Encoding]::UTF8.GetString($bytes); - if ($bytes.Length -gt 0) { - $ContentLength = [string]::Format( - 'Content-Length: {0}{1}', - $bytes.Length, - "`r`n" - ); - } - } - - return -Join( - [string]::Format( - 'HTTP/1.1 {0} {1}{2}', - $this.statuscode, - $Icinga2.Enums.HttpStatusCodes.$this.statuscode, - "`r`n" - ), - [string]::Format( - 'Server: {0}{1}', - (Get-WmiObject Win32_ComputerSystem).Name, - "`r`n" - ), - [string]::Format( - 'Content-Type: application/json{0}', - "`r`n" - ), - $this.authheader, - $ContentLength, - "`r`n", - $HTMLContent - ); -} - -return $APIResponse; \ No newline at end of file diff --git a/core/include/App.ps1 b/core/include/App.ps1 deleted file mode 100644 index 8bc5082..0000000 --- a/core/include/App.ps1 +++ /dev/null @@ -1,15 +0,0 @@ -# App configuration -$App = @{ - LogSeverity = [PSCustomObject]@{ - PSTypeName = "LogSeverity" - Info = 0 - Warning = 1 - Error = 2 - Exception = 3 - Debug = 4 - }; - RootPath = $_InternalTempVariables.RootPath; - ModuleName = $_InternalTempVariables.ModuleName; -} - -return $App; \ No newline at end of file diff --git a/core/include/Checker.ps1 b/core/include/Checker.ps1 deleted file mode 100644 index 97720eb..0000000 --- a/core/include/Checker.ps1 +++ /dev/null @@ -1,105 +0,0 @@ -$Checker = New-Object -TypeName PSObject; - -$Checker | Add-Member -membertype NoteProperty -name 'os' -value ''; -$Checker | Add-Member -membertype NoteProperty -name 'version' -value ''; -$Checker | Add-Member -membertype NoteProperty -name 'fqdn' -value ''; -$Checker | Add-Member -membertype NoteProperty -name 'bind' -value 'wdt'; -$Checker | Add-Member -membertype NoteProperty -name 'time_offset' -value 0; - -$Checker | Add-Member -membertype ScriptMethod -name 'Start' -value { - - $Icinga2.PidManager.StopProcessByBind($this.bind); - - Start-Sleep 1; - - $Icinga2.PidManager.CreatePidFile($this.bind); - - $WindowsInformations = Get-CimInstance Win32_OperatingSystem; - $this.version = $WindowsInformations.CimInstanceProperties['Version'].Value; - $this.os = $WindowsInformations.CimInstanceProperties['Caption'].Value; - $this.fqdn = [System.Net.Dns]::GetHostEntry('localhost').HostName; - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - 'Starting checker component of module.' - ); - - $Icinga2.ClientProtocol.setFQDN($this.fqdn); - $Icinga2.Cache.Checker.ModuleScheduler = @{ }; - - while($true) { - - $StopWatchHandler = [System.Diagnostics.StopWatch]::StartNew() - $this.ScheduleWindowsHello($FALSE); - $this.UpdateModuleTimer(); - $Icinga2.ClientJobs.ParseJobResults(); - - # This part will help us to keep the gap between module execution as low as possible - # We will check how many seconds have been passed while the modules were executed - # This value will then be added to our module timings, ensuring that in general - # they will become executed right on time - $StopWatchHandler.Stop(); - $this.time_offset = [math]::Round($StopWatchHandler.Elapsed.TotalSeconds, 0); - $Icinga2.ClientJobs.AddTicks($this.time_offset); - - Start-Sleep -Seconds 1; - } - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - 'Stopping checker component of module.' - ); -} - -$Checker | Add-Member -membertype ScriptMethod -name 'UpdateModuleTimer' -value { - if ($Icinga2.Cache.Checker.ModuleConfig -eq $null) { - return; - } - - foreach ($module in $Icinga2.Cache.Checker.ModuleConfig.Keys) { - if ($Icinga2.Cache.Checker.ModuleScheduler.ContainsKey($module) -eq $FALSE) { - $Icinga2.Cache.Checker.ModuleScheduler.Add($module, 0); - } else { - $Icinga2.Cache.Checker.ModuleScheduler[$module] += (1 + $this.time_offset); - - if ($Icinga2.Cache.Checker.ModuleScheduler[$module] -ge $Icinga2.Cache.Checker.ModuleConfig[$module]) { - $Icinga2.Cache.Checker.ModuleScheduler[$module] = 0; - $this.ScheduleModuleJob($module); - } - } - } - $this.time_offset = 0; -} - -$Checker | Add-Member -membertype ScriptMethod -name 'ScheduleModuleJob' -value { - param([string]$module); - - $Icinga2.ClientJobs.ScheduleJob($module); -} - -$Checker | Add-Member -membertype ScriptMethod -name 'ScheduleWindowsHello' -value { - param([bool]$force); - $this.WriteLogOutput($Icinga2.ClientJobs.WindowsHello( - $this.os, - $this.fqdn, - $this.version, - $force - )); -} - -$Checker | Add-Member -membertype ScriptMethod -name 'WriteLogOutput' -value { - param($response); - - if ($response -ne $null) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - $response - ); - } -} - -$Checker | Add-Member -membertype ScriptMethod -name 'Stop' -value { - $Icinga2.PidManager.StopProcessByBind($this.bind); -} - -return $Checker; \ No newline at end of file diff --git a/core/include/ClientJobs.ps1 b/core/include/ClientJobs.ps1 deleted file mode 100644 index d54c084..0000000 --- a/core/include/ClientJobs.ps1 +++ /dev/null @@ -1,292 +0,0 @@ -$ClientJobs = New-Object -TypeName PSObject; - -$ClientJobs | Add-Member -membertype NoteProperty -name 'hello_counter' -value 0; -$ClientJobs | Add-Member -membertype NoteProperty -name 'module_scheduler' -value @( ); -$ClientJobs | Add-Member -membertype NoteProperty -name 'module_output' -value $null; - -$ClientJobs | Add-Member -membertype ScriptMethod -name 'AddTicks' -value { - param([int]$ticks); - - $this.hello_counter += $ticks; -} - -$ClientJobs | Add-Member -membertype ScriptMethod -name 'WindowsHello' -value { - param([string]$os, [string]$fqdn, [string]$version, [bool]$force); - - if ($this.hello_counter -ge 30) { - $this.hello_counter = 0; - } - - if ($this.hello_counter -eq 0 -Or $force -eq $TRUE) { - [hashtable]$hello = @{ - 'os' = $os; - 'fqdn' = $fqdn; - 'version' = $version; - 'port' = $Icinga2.Config.'tcp.socket.port'; - }; - - [string]$token = $this.getAuthToken(); - if ([string]::isNullOrEmpty($token) -eq $FALSE) { - $hello.Add( - 'modules', - (New-Icinga-Monitoring -ListModules) - ) - } - - $response = $Icinga2.ClientProtocol.NewRequest( - @('X-Windows-Hello: 1'), - ($hello | ConvertTo-Json -Depth 2 -Compress), - $Icinga2.Config.'checker.server.host', - $token - ); - - $this.hello_counter += 1; - - if ($response -eq $null) { - return $null; - } - - try { - $json = $response | ConvertFrom-Json; - $Icinga2.Cache.Checker.Authenticated = $TRUE; - $Icinga2.ClientProtocol.parseWindowsHelloResponse($json); - return $null; - } catch { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - $_.Exception.Message - ); - } - - $Icinga2.Cache.Checker.Authenticated = $FALSE; - - return $response; - } - - $this.hello_counter += 1; - - return $null; -} - -$ClientJobs | Add-Member -membertype ScriptMethod -name 'getAuthToken' -value { - [string]$token = ''; - if ($Icinga2.Cache.Checker.Authenticated -eq $TRUE -And $Icinga2.Cache.Checker.AuthToken -ne $null) { - $token = [string]::Format('?token={0}', $Icinga2.Cache.Checker.AuthToken); - } - - return $token; -} - -$ClientJobs | Add-Member -membertype ScriptMethod -name 'ScheduleJob' -value { - param([string]$module); - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - [string]::Format( - 'Scheduling execution check for module: {0}', - $module - ) - ); - - $this.module_scheduler += $module; - return; - - # This would be the best, but will cause too much overhead and system load - Start-Job -Name $module -ScriptBlock { - return New-Icinga-Monitoring -include $args[0]; - } -ArgumentList $module; -} - -$ClientJobs | Add-Member -membertype ScriptMethod -name 'ParseJobResults' -value { - - if ($this.module_scheduler.Count -eq 0) { - return; - } - - $moduleOutput = New-Icinga-Monitoring -Include ($this.module_scheduler) -Config $Icinga2.Cache.Checker.ModuleArguments; - - [string]$token = $this.getAuthToken(); - - [string]$modules = $this.module_scheduler -Join "," - - if ([string]::isNullOrEmpty($token) -eq $TRUE) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - 'Unable to send job results to server. No auth token is specified' - ); - $this.FlushModuleCache($TRUE); - return; - } - - if ($Icinga2.ClientProtocol.GetConnectionState($Icinga2.Config.'checker.server.host') -eq $FALSE) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - [string]::Format( - 'Module results for "{0}" will not be send to {1}. A previous connection failed. Re-Trying in some seconds...', - $modules, - $Icinga2.Config.'checker.server.host' - ) - ); - $this.FlushModuleCache($TRUE); - return; - } - - $this.module_output = ($moduleOutput | ConvertTo-Json -Depth 100 -Compress); - - $response = $Icinga2.ClientProtocol.NewRequest( - @('X-Windows-Result: 1'), - $this.module_output, - $Icinga2.Config.'checker.server.host', - [string]::Format( - '{0}&results=1', - $token - ) - ); - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - [string]::Format( - 'Send modules {0} results to server. Received result: {1}', - $modules, - $response - ) - ); - - $this.ParseResponse($response); - return; - - # This would be the best, but will cause too much overhead and system load - [hashtable]$moduleOutput = @{ }; - - Get-Job -State Completed | Where-Object { - $moduleOutput.Add( - $_.Name, - (Receive-Job -Id $_.Id) - ); - Remove-Job -Id $_.Id; - }; - - [string]$token = $this.getAuthToken(); - - if ([string]::isNullOrEmpty($token) -eq $TRUE) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - 'Unable to send job results to server. No auth token is specified' - ); - return; - } - - if ($Icinga2.ClientProtocol.GetConnectionState($Icinga2.Config.'checker.server.host') -eq $FALSE) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - [string]::Format( - 'Module results for "{0}" will not be send to {1}. A previous connection failed. Re-Trying in some seconds...', - $modules, - $Icinga2.Config.'checker.server.host' - ) - ); - return; - } - - $response = $Icinga2.ClientProtocol.NewRequest( - @('X-Windows-Result: 1'), - ($moduleOutput | ConvertTo-Json -Depth 100 -Compress), - $Icinga2.Config.'checker.server.host', - [string]::Format( - '{0}&results=1', - $token - ) - ); - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - [string]::Format( - 'Send modules {0} results to server. Received result: {1}', - ($moduleOutput | Out-String), - $response - ) - ); -} - -$ClientJobs | Add-Member -membertype ScriptMethod -name 'FlushModuleCache' -value { - param([bool]$flush); - - if ($flush -eq $TRUE) { - foreach($module in $this.module_scheduler) { - $Icinga2.Utils.Modules.FlushModuleCache($module); - } - } - - $this.module_scheduler = @(); -} - -$ClientJobs | Add-Member -membertype ScriptMethod -name 'ParseResponse' -value { - param([string]$response); - - if ([string]::IsNullOrEmpty($response) -eq $TRUE) { - $this.FlushModuleCache($TRUE); - return; - } - - # Re-Try to send the informations once in case we are not authorized - if ($response -eq '401') { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - 'Received Unauthorized (401) response. Trying to re-send results after requesting permission.' - ); - $Icinga2.Checker.ScheduleWindowsHello($TRUE); - [string]$token = $this.getAuthToken(); - $response = $Icinga2.ClientProtocol.NewRequest( - @('X-Windows-Result: 1'), - $this.module_output, - $Icinga2.Config.'checker.server.host', - [string]::Format( - '{0}&results=1', - $token - ) - ); - - if ([string]::IsNullOrEmpty($response) -eq $TRUE) { - $this.FlushModuleCache($TRUE); - return; - } - } - - try { - $json = ConvertFrom-Json $response -ErrorAction Stop -WarningAction Stop; - } catch { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Error, - [string]::Format( - 'Received invalid JSON response from request: {0}', - $response - ) - ); - $this.FlushModuleCache($TRUE); - return; - } - - try { - if ($json.response -ne $null) { - if ($json.response -ne 200) { - $this.FlushModuleCache($TRUE); - return; - } - } - } catch { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Error, - [string]::Format( - 'Failed to properly parse JSON response: {0} . Exception Message: {1}', - $response, - $_.Exception.Message - ) - ); - $this.FlushModuleCache($TRUE); - return; - } - - $this.FlushModuleCache($FALSE); -} - -return $ClientJobs; \ No newline at end of file diff --git a/core/include/ClientProtocol.ps1 b/core/include/ClientProtocol.ps1 deleted file mode 100644 index e0fbbe3..0000000 --- a/core/include/ClientProtocol.ps1 +++ /dev/null @@ -1,225 +0,0 @@ -$ClientProtocol = New-Object -TypeName PSObject; - -$ClientProtocol | Add-Member -membertype NoteProperty -name 'fqdn' -value ''; - -$ClientProtocol | Add-Member -membertype ScriptMethod -name 'setFQDN' -value { - param([string]$fqdn); - - $this.fqdn = $fqdn; -} - -$ClientProtocol | Add-Member -membertype ScriptMethod -name 'SetConnectionState' -value { - param([string]$remoteAddress, [bool]$reachable); - - if ($Icinga2.Cache.Checker.RemoteServices -eq $null) { - $Icinga2.Cache.Checker.RemoteServices = @{ }; - } - - if ($Icinga2.Cache.Checker.RemoteServices.ContainsKey($remoteAddress) -eq $FALSE) { - $Icinga2.Cache.Checker.RemoteServices.Add($remoteAddress, $reachable); - return; - } - - $Icinga2.Cache.Checker.RemoteServices[$remoteAddress] = $reachable; -} - -$ClientProtocol | Add-Member -membertype ScriptMethod -name 'GetConnectionState' -value { - param([string]$remoteAddress); - - if ($Icinga2.Cache.Checker.RemoteServices.ContainsKey($remoteAddress) -eq $FALSE) { - return $TRUE; - } - - return $Icinga2.Cache.Checker.RemoteServices[$remoteAddress]; -} - -$ClientProtocol | Add-Member -membertype ScriptMethod -name 'NewRequest' -value { - param([array]$headers, [string]$content, [string]$remoteAddress, [string]$url); - - $url = [string]::Format( - '{0}{1}', - $remoteAddress, - $url - ); - - $httpRequest = [System.Net.HttpWebRequest]::Create( - $url - ); - $httpRequest.Method = 'POST'; - $httpRequest.Accept = 'application/json'; - $httpRequest.ContentType = 'application/json'; - $httpRequest.Headers.Add( - [string]::Format( - 'X-Windows-CheckResult: {0}', - $this.fqdn - ) - ); - - # Add possible custom header - foreach ($header in $headers) { - $httpRequest.Headers.Add($header); - } - $httpRequest.TimeOut = 60000; - - # If we are using self-signed certificates for example, the HTTP request will - # fail caused by the SSL certificate. With this we can allow even faulty - # certificates. This should be used with caution - if (-Not $Icinga2.Config.'checker.ssl.verify') { - [System.Net.ServicePointManager]::ServerCertificateValidationCallback = { $true } - } - - try { - # Only send data in case we want to send some data - if ($content -ne '') { - $transmitBytes = [System.Text.Encoding]::UTF8.GetBytes($content); - $httpRequest.ContentLength = $transmitBytes.Length; - [System.IO.Stream]$httpOutput = [System.IO.Stream]$httpRequest.GetRequestStream() - $httpOutput.Write($transmitBytes, 0, $transmitBytes.Length) - $httpOutput.Close() - } - } catch [System.Net.WebException] { - $this.SetConnectionState($remoteAddress, $FALSE); - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Exception, - [string]::Format('Exception while trying to connect to "{0}". Possible a connection error. Message: {1}', - $url, - $_.Exception.Message - ) - ); - return $null; - } catch { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Exception, - $_.Exception.Message - ); - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Exception, - $_.Exception.StackTrace - ); - return $null; - } - - try { - - $this.SetConnectionState($remoteAddress, $TRUE); - return $this.readResponseStream($httpRequest.GetResponse()); - - } catch [System.Net.WebException] { - # Print an exception message and the possible body in case we received one - # to make troubleshooting easier - [string]$errorResponse = $this.readResponseStream($_.Exception.Response); - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - $_.Exception.Message - ); - if ($errorResponse -ne '') { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - $errorResponse - ); - } - - $exceptionMessage = $_.Exception.Response; - if ($exceptionMessage.StatusCode) { - return [int][System.Net.HttpStatusCode]$exceptionMessage.StatusCode; - } else { - return 900; - } - } - - return $null; -} - -$ClientProtocol | Add-Member -membertype ScriptMethod -name 'readResponseStream' -value { - param([System.Object]$response); - - try { - if ($response) { - $responseStream = $response.getResponseStream(); - $streamReader = New-Object IO.StreamReader($responseStream); - $result = $streamReader.ReadToEnd(); - $response.close() - $streamReader.close() - - return $result; - } - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Exception, - 'The received response from the remote server is NULL. This might be caused by SSL errors or wrong Webserver configuration.' - ); - } catch { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Exception, - $_.Exception.Message - ); - } - - return $null; -} - -$ClientProtocol | Add-Member -membertype ScriptMethod -name 'parseWindowsHelloResponse' -value { - param($json); - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - [string]::Format( - 'Remote Server Output: {0}', - $json - ) - ); - - $Icinga2.Cache.Checker.AuthToken = $json.token; - if ($Icinga2.Cache.Checker.ModuleConfig -eq $null) { - $Icinga2.Cache.Checker.ModuleConfig = @{}; - } - - $Icinga2.Cache.Checker.ModuleArguments = $json.module_arguments; - - [hashtable]$activeModules = @{}; - - foreach ($module in $json.modules) { - if ($Icinga2.Cache.Checker.ModuleConfig.ContainsKey($module.name)) { - $Icinga2.Cache.Checker.ModuleConfig[$module.name] = $module.check_interval; - } else { - $Icinga2.Cache.Checker.ModuleConfig.Add($module.name, $module.check_interval); - } - $activeModules.Add($module.name, $TRUE); - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - [string]::Format( - 'Adding module {0} with check intervall {1}', - $module.name, - $module.check_interval - ) - ); - } - - # We might have disabled some modules. Lets handle this by setting the - # execution timer to -1 - foreach ($module in $Icinga2.Cache.Checker.ModuleConfig.Keys) { - if ($activeModules.ContainsKey($module) -eq $FALSE) { - $activeModules.Add($module, $FALSE); - } - } - - # We require a second loop to ensure we won't crash because of a changed hashtable - foreach($module in $activeModules.Keys) { - if ($activeModules[$module] -eq $FALSE) { - if ($Icinga2.Cache.Checker.ModuleConfig.ContainsKey($module)) { - $Icinga2.Cache.Checker.ModuleConfig.Remove($module); - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - [string]::Format( - 'Disabling module {0}', - $module - ) - ); - } - } - } -} - -return $ClientProtocol; \ No newline at end of file diff --git a/core/include/Config.ps1 b/core/include/Config.ps1 deleted file mode 100644 index 17266eb..0000000 --- a/core/include/Config.ps1 +++ /dev/null @@ -1,24 +0,0 @@ -# Inetrnal variable to store the root directory path -[string]$RootDirectory = ''; - -# In case we load the module for the first time, this variable contains the root path -# of our module -if ($_InternalTempVariables -ne $null) { - $RootDirectory = $_InternalTempVariables.RootPath; -} else { - # In case we want to reload the configuration, we simply can access the namespace - # variable we already loaded - $RootDirectory = $Icinga2.App.RootPath; -} - -# Build the Config directory and file path -[string]$ConfigDirectory = (Join-Path $RootDirectory -ChildPath 'agent\config'); -[string]$ConfigFile = (Join-Path $ConfigDirectory -ChildPath 'config.conf'); - -# In case the config file does not exist, return an empty hashtable -if ((Test-Path ($ConfigFile)) -eq $FALSE) { - return ('{ }' | ConvertFrom-Json); -} - -# Return the content of the file as objects (config is stored as JSON) -return ([System.IO.File]::ReadAllText($ConfigFile) | ConvertFrom-Json); \ No newline at end of file diff --git a/core/include/Enums.ps1 b/core/include/Enums.ps1 deleted file mode 100644 index d97bdab..0000000 --- a/core/include/Enums.ps1 +++ /dev/null @@ -1,83 +0,0 @@ -<# - # This script will provide 'Enums' we can use within our module to - # easier access constants and to maintain a better overview of the - # entire components - #> - -[hashtable]$LogState = @{ - Info = 0; - Warning = 1; - Error = 2; - Exception = 3; - Debug = 4; -}; - -[hashtable]$LogSeverity = @{ - 0 = 'Info'; - 1 = 'Warning'; - 2 = 'Error'; - 3 = 'Exception'; - 4 = 'Debug'; -}; - -[hashtable]$EventLogType = @{ - 0 = 'Information'; - 1 = 'Warning'; - 2 = 'Error'; - 3 = 'Error'; - 4 = 'Information'; -}; - -[hashtable]$LogColor = @{ - 0 = 'DarkGreen'; - 1 = 'Yellow'; - 2 = 'Red'; - 3 = 'DarkRed'; - 4 = 'Magenta'; -}; - -[hashtable]$ServiceStatus = @{ - 'NotInstalled' = 'The Icinga service for this module is not installed. Please run Install-Icinga to install the service.'; - 'Running' = 'The Icinga service is running.'; - 'Stopped' = 'The Icinga service is not running.'; - 'Starting' = 'The Icinga service is about to start.'; - 'Stopping' = 'The Icinga service is shutting down.'; -} - -[hashtable]$SCErrorCodes = @{ - 5 = 'Failed to execute Icinga 2 Service operation: Permission denied.'; - 1053 = 'Failed to start the Icinga 2 Service: The Service did not respond in time to the start or operation request.'; - 1056 = 'Failed to start the Icinga 2 Service: The Service is already running.'; - 1060 = 'Failed to apply action for Icinga 2 Service: The Service is not installed.'; - 1062 = 'Failed to stop the Icinga 2 Service: The Service is not running.'; - 1072 = 'Failed to uninstall the Icinga 2 Service: The Service is already marked for deletion.'; - 1073 = 'Failed to install the Icinga 2 Service: The Service is already installed.'; -}; - -[hashtable]$HttpStatusCodes = @{ - 200 = 'Ok'; - 400 = 'Bad Request'; - 401 = 'Unauthorized'; - 403 = 'Forbidden'; - 404 = 'Not Found' - 500 = 'Internal Server Error'; -}; - -<# - # Once we defined a new enum hashtable above, simply add it to this list - # to make it available within the entire module. - # - # Example usage: - # $Icinga2.Enums.LogState.Info - #> -[hashtable]$Enums = @{ - LogSeverity = $LogSeverity; - EventLogType = $EventLogType; - LogColor = $LogColor; - LogState = $LogState; - ServiceStatus = $ServiceStatus; - SCErrorCodes = $SCErrorCodes; - HttpStatusCodes = $HttpStatusCodes; -} - -return $Enums; \ No newline at end of file diff --git a/core/include/Log.ps1 b/core/include/Log.ps1 deleted file mode 100644 index 356aae0..0000000 --- a/core/include/Log.ps1 +++ /dev/null @@ -1,128 +0,0 @@ -<# - # Handle the entire logging process of the module by sending the events - # to console, the event log and if configured into an own log file. - # This entire script will return a 'function' handler, dealing with - # all events. - # To create log events, simply use the following example: - # - # $Icinga2.Log.Write($Icinga2.Enums.LogState.Info, 'This is a info message'); - #> - -$IcingaLogger = New-Object -TypeName PSObject; - -$IcingaLogger | Add-Member -membertype NoteProperty -name 'noconsole' -value $FALSE; - -$IcingaLogger | Add-Member -membertype ScriptMethod -name 'DisableConsole' -value { - $this.noconsole = $TRUE; -} - -$IcingaLogger | Add-Member -membertype ScriptMethod -name 'Write' -value { - param($Severity, [string]$Message); - - # Only write debug output if enabled - if ($Severity -eq $Icinga2.Enums.LogState.Debug -And $Icinga2.Config.'logger.debug' -eq $FALSE) { - return; - } - - [string]$SeverityToString = $this.GetSeverityAsString($Severity); - - # Format a timestamp to get to know the exact date and time. Example: 2017-13-07 22:09:13.263.263 - $timestamp = Get-Date -Format "yyyy-dd-MM HH:mm:ss.fff"; - [string]$LogMessage = [string]::Format('{0} [{1}]: {2}', $timestamp, $SeverityToString, $Message); - - $this.WriteConsole($Severity, $LogMessage); - $this.WriteEventLog($Severity, $Message); - $this.WriteLogFile($Severity, $LogMessage); -} - -$IcingaLogger | Add-Member -membertype ScriptMethod -name 'GetConsoleColorFromSeverity' -value { - param([int]$Severity); - - if ($Icinga2.Enums.LogColor.ContainsKey($Severity) -eq $FALSE) { - return 'White'; - } - - return $Icinga2.Enums.LogColor[$Severity]; -} - -$IcingaLogger | Add-Member -membertype ScriptMethod -name 'GetSeverityAsString' -value { - param([int]$Severity); - - if ($Icinga2.Enums.LogSeverity.ContainsKey($Severity) -eq $FALSE) { - return 'Undefined'; - } - - return $Icinga2.Enums.LogSeverity[$Severity]; -} - -$IcingaLogger | Add-Member -membertype ScriptMethod -name 'WriteLogFile' -value { - param([int]$Severity, [string]$Message); - - [string]$LogDirectory = $Icinga2.Config.'logger.directory'; - - if ([string]::IsNullOrEmpty($LogDirectory)) { - return; - } - - if (-Not (Test-Path $LogDirectory)) { - New-Item $LogDirectory -ItemType Directory | Out-Null; - - # Something went wrong while trying to create the directory - if (-Not (Test-Path $LogDirectory)) { - $this.WriteConsole($Icinga2.Enums.LogState.Error, - [string]::Format('Failed to create logfile directory at location "{0}"', $LogDirectory) - ) - return; - } - } - - [string]$LogFile = Join-Path $LogDirectory -ChildPath 'icinga2.log'; - - try { - $LogStream = New-Object System.IO.FileStream( - $LogFile, - [System.IO.FileMode]::Append, - [System.IO.FileAccess]::Write, - [IO.FileShare]::Read - ); - $LogWriter = New-Object System.IO.StreamWriter($LogStream); - $LogWriter.writeLine($Message); - } catch { - $this.WriteConsole($Icinga2.Enums.LogState.Error, - [string]::Format('Failed to write into logfile: "{0}"', $_.Exception.Message) - ) - } finally { - $LogWriter.Dispose(); - } -} - -$IcingaLogger | Add-Member -membertype ScriptMethod -name 'WriteEventLog' -value { - param([int]$Severity, [string]$Message); - - try { - Write-EventLog -LogName "Application" ` - -Source $Icinga2.Service.servicedisplayname ` - -EventID (1000 + $Severity) ` - -EntryType $Icinga2.Enums.EventLogType.$Severity ` - -Message $Message ` - -Category $Severity ` - -ErrorAction Stop; - } catch { - $this.WriteLogFile( - $Icinga2.Enums.LogState.Error, - $_.Exception.Message - ); - } -} - -$IcingaLogger | Add-Member -membertype ScriptMethod -name 'WriteConsole' -value { - param([int]$Severity, [string]$Message); - - if ($this.noconsole) { - return; - } - - Write-Host $Message -ForegroundColor ($this.GetConsoleColorFromSeverity($Severity)) -} - -return $IcingaLogger; \ No newline at end of file diff --git a/core/include/NetworkProtocol.ps1 b/core/include/NetworkProtocol.ps1 deleted file mode 100644 index 6b96296..0000000 --- a/core/include/NetworkProtocol.ps1 +++ /dev/null @@ -1,192 +0,0 @@ -$NetworkProtocol = New-Object -TypeName PSObject; - -$NetworkProtocol | Add-Member -membertype NoteProperty -name 'static' -value $FALSE; -$NetworkProtocol | Add-Member -membertype NoteProperty -name 'sslstream' -value $null; -$NetworkProtocol | Add-Member -membertype NoteProperty -name 'networkstream' -value $null; -$NetworkProtocol | Add-Member -membertype NoteProperty -name 'encrypted' -value $null; - -$NetworkProtocol | Add-Member -membertype ScriptMethod -name 'Create' -value { - param($Stream); - - $this.networkstream = $Stream; - $this.sslstream = $this.CreateSSLStream($Stream); -} - -$NetworkProtocol | Add-Member -membertype ScriptMethod -name 'CreateSSLStream' -value { - param($Stream); - - try { - $sslStream = New-Object System.Net.Security.SslStream( - $Stream, - $false - ) - $sslStream.AuthenticateAsServer( - $Icinga2.Cache.Certificates.Server, - 0, - [System.Security.Authentication.SslProtocols]::Tls, - 1 - ); - $sslStream.ReadTimeout = 2000; - $this.encrypted = $TRUE; - - return $sslStream; - } catch [System.IO.IOException] { - # Exceptions which occure when connecting from HTTP to this API, as we force HTTPS - # Use the client's non-ssl stream to inform the user about our forced - # HTTPS handling and set an internal variable to not send any data - # to our client over HTTP - $this.encrypted = $FALSE; - $Stream.ReadTimeout = 2000; - $Stream.WriteTimeout = 2000; - return $Stream; - } catch [System.NotSupportedException] { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Exception, - 'The used SSL certificate is not providing a linked private key and cannot be used as Server certificate' - ); - } catch { - # Handle every other error here - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Exception, - $_.Exception.Message - ); - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Exception, - $_.Exception - ); - } - - return $null; -} - -$NetworkProtocol | Add-Member -membertype ScriptMethod -name 'ReadMessage' -value { - param([int]$BytesToRead) - - # If we have no bytes to read, do nothing - if ($BytesToRead -eq 0) { - return $null; - } - - [string]$content = ''; - [SecureString]$SecureContent = $null; - [int]$TotalMessageSize = 0; - # Define our buffer size to ensure we read a certain - # amount of bytes each read attempt only - [int]$BufferSize = 1024; - # If we read the message and don't know if there is a content available - # we have to read until we reach EOF. In case we have the exact size - # of the content, we can read the possible rest - [bool]$IsSizeKnown = $FALSE; - - # This will allow us to read a fixed amount of data from our - # stream and terminate the operation afterwards - if ($BytesToRead -gt 0) { - $BufferSize = $BytesToRead; - $IsSizeKnown = $TRUE; - } - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - 'Reading new message from TCP NetworkStream of Client' - ); - - # Handle errors while reading the SSL Stream - try { - # Read the stream as long as we receive data from it - while ($true) { - - # Create a new byte array with a fixed buffer size - [byte[]]$bytes = New-Object byte[] $BufferSize; - - # Read the actual data from the stream - $bytesRead = $this.sslstream.Read($bytes, 0, $bytes.Length); - $TotalMessageSize += $bytesRead; - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - [string]::Format( - 'Reading {0} bytes from TCP connection', - $bytesRead - ) - ); - - # Build a output message from our received as string and perform - # possible required cleanup in addition - if ($bytesRead -ne 0) { - [string]$message = [System.Text.Encoding]::UTF8.GetString($bytes); - - # In case we receive a larger message, append the message content - # to our string value - $content = -Join( - $content, - $message - ); - - # Ensure our output string is always matching the correct length - # but only apply this in case we are unsure about the real length - if ($IsSizeKnown -eq $FALSE) { - $content = $content.Substring( - 0, - $TotalMessageSize - ); - } - - # EOF reached or the amount of bytes to read was known - # and we should abort here - if ($content.Contains("`r`n`r`n") -Or $IsSizeKnown) { - break; - } - } else { - break; - } - } - } catch { - # Might be good too remove this, as errors will occure very likely in case the SSLStream - # timed out after 2 seconds because no new data have been received. - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Exception, - [string]::Format( - 'Failed to read Message from stream: {0}', - $_.Exception.Message - ) - ); - - return $null; - } - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - [string]::Format( - 'Finished reading {0} bytes from current NetworkMessage', - $TotalMessageSize - ) - ); - - # In case we read no message from the stream, we should do nothing - if ($TotalMessageSize -eq 0) { - return $null; - } - - $SecureContent = $Icinga2.Utils.SecureString.ConvertTo($content); - $content = $null; - - return $SecureContent; -} - -$NetworkProtocol | Add-Member -membertype ScriptMethod -name 'WriteMessage' -value { - param($message); - - try { - $bytes = [System.Text.Encoding]::UTF8.GetBytes($message); - $Client.SendBufferSize = $bytes.Length; - $this.sslstream.Write($bytes, 0, $bytes.Length); - $this.sslstream.Flush(); - } catch { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Exception, - 'Failed to write message into data stream' - ); - } -} - -return $NetworkProtocol; \ No newline at end of file diff --git a/core/include/PidManager.ps1 b/core/include/PidManager.ps1 deleted file mode 100644 index 5c9770e..0000000 --- a/core/include/PidManager.ps1 +++ /dev/null @@ -1,149 +0,0 @@ -$PidManager = New-Object -TypeName PSObject; - -$PidManager | Add-Member -membertype ScriptMethod -name 'PidExists' -value { - param([string]$bind); - - [string]$PidFile = $this.PidFileName($bind); - - return (Test-Path ($this.FullPidPath($PidFile))); -} - -$PidManager | Add-Member -membertype ScriptMethod -name 'CreatePidFile' -value { - param([string]$bind); - - [string]$PidFile = $this.PidFileName($bind); - - Add-Content -Path ($this.FullPidPath($PidFile)) -Value $pid; -} - -$PidManager | Add-Member -membertype ScriptMethod -name 'PidFileName' -value { - param([string]$bind); - - return [string]::Format( - 'icingabind{0}.pid', - $bind - ); -} - -$PidManager | Add-Member -membertype ScriptMethod -name 'FullPidPath' -value { - param([string]$PidFile); - - return (Join-Path $Icinga2.App.RootPath -ChildPath ( - [string]::Format( - '\agent\state\{0}', - $PidFile - ) - )); -} - -$PidManager | Add-Member -membertype ScriptMethod -name 'ProcessID' -value { - param([string]$FullPidFile); - - if ((Test-Path $FullPidFile) -eq $FALSE) { - return 0; - } - - return Get-Content -Path $FullPidFile; -} - -$PidManager | Add-Member -membertype ScriptMethod -name 'GetPIDByBind' -value { - param([string]$bind); - - return $this.ProcessID( - $this.FullPidPath( - $this.PidFileName( - $bind - ) - ) - ); -} - -$PidManager | Add-Member -membertype ScriptMethod -name 'GetPIDPathByBind' -value { - param([string]$bind); - - return $this.FullPidPath( - $this.PidFileName( - $bind - ) - ); -} - -$PidManager | Add-Member -membertype ScriptMethod -name 'RemovePidFile' -value { - param([string]$FullPidPath, [string]$bind); - - [string]$PidFile = $this.PidFileName($bind); - - if (Test-Path $FullPidPath) { - Remove-Item $FullPidPath | Out-Null; - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - [string]::Format( - 'Removing PID-File "{0}" for bind "{1}"', - $PidFile, - $bind - ) - ); - } else { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - [string]::Format( - 'PID File "{0}" for bind "{1}" does not exist and could therefor not be removed', - $PidFile, - $bind - ) - ); - } -} - -$PidManager | Add-Member -membertype ScriptMethod -name 'PidProcess' -value { - param([int]$ProcessID); - - if ($ProcessID -eq 0) { - return $null; - } - - # Look for the Process over WMI, as we might run as Service User and require - # to fetch the entire scope of running processes - $ProcessList = Get-WmiObject Win32_Process | Select-Object ProcessName, ProcessId -ErrorAction Stop; - - foreach ($process in $ProcessList) { - if ($process.ProcessId -eq $ProcessID) { - if ($process.ProcessName -eq 'powershell.exe') { - return $process; - } - } - } - - return $null; -} - -$PidManager | Add-Member -membertype ScriptMethod -name 'StopProcessByBind' -value { - param([string]$bind); - - if ($this.PidExists($bind)) { - $ProcessId = $this.GetPIDByBind($bind); - $this.ShutdownProcess($ProcessId); - $this.RemovePidFile( - $this.GetPIDPathByBind($bind), - $bind - ); - } -} - -$PidManager | Add-Member -membertype ScriptMethod -name 'ShutdownProcess' -value { - param($ProcessID); - - # Close possible PowerShell instances - if ($Icinga2.PidManager.PidProcess($ProcessID) -ne $null) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - [string]::Format( - 'Trying to terminate process with PID "{0}"', - $ProcessID - ) - ); - Stop-Process -Id $ProcessID -Force; - } -} - -return $PidManager; \ No newline at end of file diff --git a/core/include/ServerProtocol.ps1 b/core/include/ServerProtocol.ps1 deleted file mode 100644 index b19660f..0000000 --- a/core/include/ServerProtocol.ps1 +++ /dev/null @@ -1,223 +0,0 @@ -$ServerProtocoll = New-Object -TypeName PSObject; - -$ServerProtocoll | Add-Member -membertype NoteProperty -name 'static' -value $FALSE; -$ServerProtocoll | Add-Member -membertype NoteProperty -name 'Client' -value $Null; -$ServerProtocoll | Add-Member -membertype NoteProperty -name 'Network' -value (Get-Icinga-Lib -Include 'NetworkProtocol'); -$ServerProtocoll | Add-Member -membertype NoteProperty -name 'Response' -value (Get-Icinga-Lib -Include 'APIResponse'); -$ServerProtocoll | Add-Member -membertype NoteProperty -name 'Timer' -value $Null; -$ServerProtocoll | Add-Member -membertype NoteProperty -name 'Message' -value $Null; -$ServerProtocoll | Add-Member -membertype NoteProperty -name 'Commands' -value @{}; - -$ServerProtocoll | Add-Member -membertype ScriptMethod -name 'Create' -value { - param([System.Net.Sockets.TcpClient]$Client); - - $this.Client = $Client; - $this.Client.SendTimeout = 2000 - $this.Client.NoDelay = $TRUE; - - $this.Timer = [System.Diagnostics.Stopwatch]::StartNew(); - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - 'New incoming TCP Client connection' - ); - - $this.Network.Create($Client.GetStream()); - - # Just in case we received connections over HTTP, send a short answer message - # back and close the client request - if ($this.Network.encrypted -eq $FALSE) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - 'Received client connection over HTTP. Rejecting client request.' - ); - $this.Response.HTTPSRequired(); - $this.Network.WriteMessage( - $this.Response.Compile() - ); - $this.Close(); - return $FALSE; - } - - return $TRUE; -} - -$ServerProtocoll | Add-Member -membertype ScriptMethod -name 'ParseRequest' -value { - # Tell our network protocol to read all messages until - # EOF is reached - [SecureString]$message = $this.Network.ReadMessage(-1); - - if ($message -eq $null) { - return; - } - - [hashtable]$ApiMessage = $Icinga2.Utils.WebHelper.ParseApiMessage($message); - - if ($ApiMessage -eq $null -Or $ApiMessage.Count -eq 0) { - $this.SendInternalServerError(); - return; - } - - if ($Icinga2.Config.'authentication.enabled') { - [int]$Authenticated = $Icinga2.Utils.AuthHelper.Login( - $ApiMessage.credentials.user, - $ApiMessage.credentials.password, - $ApiMessage.credentials.domain - ); - if ($Authenticated -eq 0) { - $this.SendAuthenticationRequired(); - return; - } - } - - if ($ApiMessage.headers.ContainsKey('content-length')) { - [int]$ContentLength = ($ApiMessage.headers['content-length'] - $ApiMessage.content.Length); - $ApiMessage.content += $Icinga2.Utils.SecureString.ConvertFrom( - $this.Network.ReadMessage( - $ContentLength - ) - ); - } - - $this.Message = $ApiMessage; - $this.ParseQuery(); - $this.ExecuteQuery(); -} - -$ServerProtocoll | Add-Member -membertype ScriptMethod -name 'ParseQuery' -value { - [string]$QueryString = $this.Message.base.query; - if ($QueryString[0] -eq '?') { - $QueryString = $QueryString.Substring( - 1, - $QueryString.Length - 1 - ); - } - - [array]$SplitCommand = $QueryString.Split('&'); - foreach ($command in $SplitCommand) { - [hashtable]$data = $Icinga2.Utils.WebHelper.ParseUrlCommand($command); - if ($this.Commands.ContainsKey(($data.GetEnumerator() | Select-Object -First 1).Key) -eq $FALSE) { - $this.Commands += $data; - } - } -} - -$ServerProtocoll | Add-Member -membertype ScriptMethod -name 'ExecuteQuery' -value { - switch($this.IsUrlPathValid(0)) { - '' { - switch($this.IsUrlPathValid(1)) { - 'v1' { - switch($this.IsUrlPathValid(2)) { - 'data' { - $this.ParseDataV1(); - }; - 'modules' { - $this.ParseModulesV1(); - }; - default { - $this.SendBadRequest( - 'Unsupported Cmdlets specified. The following Cmdlets are supported: data, modules' - ); - }; - } - }; - default { - $this.SendBadRequest( - 'Unsupported API version specified. The following versions are supported: v1' - ); - }; - } - }; - default { - $this.SendInternalServerError(); - }; - } -} - -$ServerProtocoll | Add-Member -membertype ScriptMethod -name 'GetExecutionTime' -value { - return $this.Timer.Elapsed.TotalSeconds; -} - -$ServerProtocoll | Add-Member -membertype ScriptMethod -name 'ParseDataV1' -value { - [hashtable]$data = - @{ - data = New-Icinga-Monitoring -Include $this.Commands.include -Exclude $this.Commands.exclude; - execution = $this.GetExecutionTime(); - }; - - $this.Response.setContent($data); - $this.SendOkResponse(); -} - -$ServerProtocoll | Add-Member -membertype ScriptMethod -name 'ParseModulesV1' -value { - [hashtable]$modules = - @{ - modules = New-Icinga-Monitoring -ListModules $TRUE; - execution = $this.GetExecutionTime(); - }; - - $this.Response.setContent($modules); - $this.SendOkResponse(); -} - -$ServerProtocoll | Add-Member -membertype ScriptMethod -name 'IsUrlPathValid' -value { - param([int]$Index); - - [string]$path = $this.Message.base.segments[$Index]; - - if ([string]::IsNullOrEmpty($path) -eq $TRUE) { - return 'default'; - } - - return $path.Replace('/', ''); -} - -$ServerProtocoll | Add-Member -membertype ScriptMethod -name 'SendOkResponse' -value { - $this.Network.WriteMessage( - $this.Response.Compile() - ); - $this.Close(); -} - -$ServerProtocoll | Add-Member -membertype ScriptMethod -name 'SendInternalServerError' -value { - $this.Response.InternalServerError(); - $this.Network.WriteMessage( - $this.Response.Compile() - ); - $this.Close(); -} - -$ServerProtocoll | Add-Member -membertype ScriptMethod -name 'SendAuthenticationRequired' -value { - $this.Response.AuthenticationRequired(); - $this.Network.WriteMessage( - $this.Response.Compile() - ); - $this.Close(); -} - -$ServerProtocoll | Add-Member -membertype ScriptMethod -name 'SendBadRequest' -value { - param([string]$message); - - $this.Response.CustomBadRequest($message); - $this.Network.WriteMessage( - $this.Response.Compile() - ); - $this.Close(); -} - -$ServerProtocoll | Add-Member -membertype ScriptMethod -name 'Close' -value { - try { - $this.Timer.Stop(); - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - 'Closing TCP Client connection' - ) - $this.Client.Close(); - $this.Client.Dispose() - $this.Client = $Null; - } catch { - # Nothing to handle. If the connection is closed already, ignore it. - } -} - -return $ServerProtocoll; \ No newline at end of file diff --git a/core/include/Service.ps1 b/core/include/Service.ps1 deleted file mode 100644 index f8a3658..0000000 --- a/core/include/Service.ps1 +++ /dev/null @@ -1,183 +0,0 @@ -$Service = New-Object -TypeName PSObject; - -$Service | Add-Member -membertype NoteProperty -name 'servicename' -value 'IcingaWindowsModule'; -$Service | Add-Member -membertype NoteProperty -name 'servicedisplayname' -value 'Icinga Windows Service'; - -$Service | Add-Member -membertype ScriptMethod -name 'Install' -value { - param([string]$ServiceBinaryPath); - - if ([string]::IsNullOrEmpty($ServiceBinaryPath) -eq $TRUE) { - return 'Please specify a valid service binary path.'; - } - - # Test if our binary does exist - if (-Not (Test-Path $ServiceBinaryPath)) { - return ([string]::Format( - 'Failed to install the Icinga service. The service binary specified at "{0}" does not exist.', - $ServiceBinaryPath - )); - } - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - 'Trying to install Icinga 2 Service...' - ); - - # Now add the script root which we require to include to the service - $ServiceBinaryPath = [string]::Format( - '{0} \"{1}\"', - $ServiceBinaryPath, - (Join-Path -Path $Icinga2.App.RootPath -ChildPath $Icinga2.App.ModuleName) - ); - - $result = & sc.exe create $this.servicename binPath= "$ServiceBinaryPath" DisplayName= $this.servicedisplayname start= auto; - - if ($this.HandleServiceError($LASTEXITCODE) -eq $TRUE) { - return $FALSE; - } - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - 'Successfully installed the Icinga 2 Windows Service.' - ); - - return $TRUE; -} - -$Service | Add-Member -membertype ScriptMethod -name 'Uninstall' -value { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - 'Trying to uninstall Icinga Service...' - ); - - # Stop the service before uninstalling it - $this.Stop(); - - $result = & sc.exe delete $this.servicename; - - if ($this.HandleServiceError($LASTEXITCODE) -eq $TRUE) { - return $FALSE; - } - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - 'Successfully uninstalled the Icinga 2 Windows Service.' - ); - - return $TRUE; -} - -$Service | Add-Member -membertype ScriptMethod -name 'Start' -value { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - 'Trying to start Icinga 2 Service...' - ); - - $result = & sc.exe start $this.servicename; - - if ($this.HandleServiceError($LASTEXITCODE) -eq $TRUE) { - return; - } - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - 'Successfully started the Icinga 2 Service.' - ); - - $this.QueryStatus(); -} - -$Service | Add-Member -membertype ScriptMethod -name 'Stop' -value { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - 'Trying to stop Icinga 2 Service...' - ); - - $result = & sc.exe stop ($this.servicename); - - if ($this.HandleServiceError($LASTEXITCODE) -eq $TRUE) { - return; - } - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - 'Successfully stopped the Icinga 2 Service.' - ); - - $this.QueryStatus(); -} - -$Service | Add-Member -membertype ScriptMethod -name 'Restart' -value { - $this.Stop(); - # Wait two seconds before starting the service again - Start-Sleep -Seconds 2; - $this.Start(); -} - -$Service | Add-Member -membertype ScriptMethod -name 'QueryStatus' -value { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - 'Waiting to query the proper Icinga 2 Service status...' - ); - Start-Sleep -Seconds 1; - - $this.Status(); -} - -$Service | Add-Member -membertype ScriptMethod -name 'Status' -value { - $ServiceStatus = (Get-WMIObject win32_service -Filter ( - [string]::Format( - "Name='{0}'", - ($this.servicename) - ) - )).State; - - if ([string]::IsNullOrEmpty($ServiceStatus) -eq $TRUE) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - $Icinga2.Enums.ServiceStatus.NotInstalled - ); - - return; - } - - if ($Icinga2.Enums.ServiceStatus.ContainsKey($ServiceStatus)) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - $Icinga2.Enums.ServiceStatus.$ServiceStatus - ); - } else { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - [string]::Format( - 'The Icinga service status is {0}', - $ServiceStatus - ) - ); - } -} - -$Service | Add-Member -membertype ScriptMethod -name 'HandleServiceError' -value { - param([int]$ErrorCode); - - # Nothing to do as no error occured - if ($ErrorCode -eq 0) { - return $FALSE; - } - - if ($Icinga2.Enums.SCErrorCodes.ContainsKey($ErrorCode)) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Error, - $Icinga2.Enums.SCErrorCodes.$ErrorCode - ); - } else { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Error, - ([string]::Format('Failed to execute operation for Icinga 2 Service: {0}', $result)) - ); - } - - return $TRUE; -} - -return $Service; \ No newline at end of file diff --git a/core/include/System.ps1 b/core/include/System.ps1 deleted file mode 100644 index d1bfbb5..0000000 --- a/core/include/System.ps1 +++ /dev/null @@ -1,23 +0,0 @@ -$SystemCPU = Get-CimInstance -ClassName 'Win32_Processor'; - -[int]$NumberOfCPUCores = 0; -[int]$NumberOfCPUThreads = 0; - -if (($SystemCPU.NumberOfCores).GetType() -is [Object]) { - $SystemCPU.NumberOfCores | Foreach { $NumberOfCPUCores += $_; }; -} else { - $NumberOfCPUCores = $SystemCPU.NumberOfCores; -} - -if (($SystemCPU.NumberOfLogicalProcessors).GetType() -is [Object]) { - $SystemCPU.NumberOfLogicalProcessors | Foreach { $NumberOfCPUThreads += $_; }; -} else { - $NumberOfCPUThreads = $SystemCPU.NumberOfCores; -} - -[hashtable]$Overview = @{ - 'NumberOfCPUCores' = $NumberOfCPUCores; - 'NumberOfCPUThreads' = $NumberOfCPUThreads; -}; - -return $Overview; \ No newline at end of file diff --git a/core/include/TCPDaemon.ps1 b/core/include/TCPDaemon.ps1 deleted file mode 100644 index 270c7f1..0000000 --- a/core/include/TCPDaemon.ps1 +++ /dev/null @@ -1,76 +0,0 @@ -$TCPDaemon = New-Object -TypeName PSObject; - -$TCPDaemon | Add-Member -membertype ScriptMethod -name 'Start' -value { - - [int]$Port = $Icinga2.Config.'tcp.socket.port'; - - if (-Not $Icinga2.Cache.Certificates.Server) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Error, - [string]::Format( - 'Unable to start TCP socket daemon for port {0}. No valid SSL certificate was loaded.', - $Port - ) - ); - return; - } - - if ($Icinga2.TCPSocket.IsSocketOpenAndValid($Port) -eq $TRUE) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - [string]::Format( - 'A PowerShell instance for socket on port "{0}" is already running with PID "{1}"', - $Port, - $Icinga2.PidManager.GetPIDByBind($port) - ) - ); - return; - } - $TCPSocket = $Icinga2.TCPSocket.CreateTCPSocket($Port); - - if ($TCPSocket -eq $null) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Error, - [string]::Format( - 'Failed to start TCP socket on port "{0}"', - $Port - ) - ) - return; - } - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - [string]::Format( - 'Starting new API listener on port "{0}"', - $Port - ) - ); - - while($true) { - [System.Net.Sockets.TcpClient]$client = $TCPSocket.AcceptTcpClient(); - - $ServerProtocol = Get-Icinga-Lib -Include 'ServerProtocol'; - if ($ServerProtocol.Create($Client) -eq $FALSE) { - continue; - } - $ServerProtocol.ParseRequest(); - } - - $Icinga2.TCPSocket.CloseTCPSocket($Port); -} - -$TCPDaemon | Add-Member -membertype ScriptMethod -name 'Stop' -value { - if ($Icinga2.Utils.AdminShell.IsAdminShell() -eq $FALSE) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Error, - 'Please run this shell as Administrator in order to stop daemon processes' - ); - return; - } - [int]$Port = $Icinga2.Config.'tcp.socket.port'; - $Icinga2.TCPSocket.CloseTCPSocket($Port); - -} - -return $TCPDaemon; \ No newline at end of file diff --git a/core/include/TCPSocket.ps1 b/core/include/TCPSocket.ps1 deleted file mode 100644 index cbc8e89..0000000 --- a/core/include/TCPSocket.ps1 +++ /dev/null @@ -1,161 +0,0 @@ -$TCPSocket = New-Object -TypeName PSObject; - -$TCPSocket | Add-Member -membertype ScriptMethod -name 'CreateTCPSocket' -value { - param([int]$port); - - [string]$PidFile = $Icinga2.PidManager.PidFileName($port); - - try { - $TCPSocket = [System.Net.Sockets.TcpListener]$port; - $TCPSocket.Start(); - $Icinga2.Cache.Sockets.Add($PidFile, $TCPSocket); - $Icinga2.PidManager.CreatePidFile($port); - - return $TCPSocket; - } catch { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Exception, - [string]::Format( - 'Failed to create TCP socket on port "{0}": {1}', - $port, - $_.Exception.Message - ) - ); - } - - return $null; -} - -# Properly close sockets, flush PID Files or terminate PowerShell instances as owner of sockets -$TCPSocket | Add-Member -membertype ScriptMethod -name 'CloseTCPSocket' -value { - param([int]$port); - - [string]$PidFile = $Icinga2.PidManager.PidFileName($port); - [bool]$IsExternalSocket = $FALSE; - - # Clear our Socket cache - # In case the socket does not exist, create a new socket - if ($Icinga2.Cache.Sockets.ContainsKey($PidFile) -eq $FALSE) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - [string]::Format( - 'The socket of port "{0}" is not part of this PowerShell instance', - $port - ) - ); - $IsExternalSocket = $TRUE; - } else { - try { - $TCPSocket = $Icinga2.Cache.Sockets.$PidFile; - $TCPSocket.Stop(); - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - [string]::Format( - 'Closing TCP socket on port "{0}"', - $port - ) - ); - } catch { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Exception, - [string]::Format( - 'Failed to close TCP socket on port "{0}": {1}', - $port, - $_.Exception.Message - ) - ); - } - - $Icinga2.Cache.Sockets.Remove($PidFile); - } - - # Delete the PID file from disk in case it exists - [string]$FullPidPath = $Icinga2.PidManager.FullPidPath($PidFile); - [int]$ProcessID = $Icinga2.PidManager.ProcessID($FullPidPath); - - $Icinga2.PidManager.RemovePidFile($FullPidPath); - - # Close possible PowerShell instances - if ($Icinga2.PidManager.PidProcess($ProcessID) -ne $null) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - [string]::Format( - 'Trying to terminate process with PID "{0}"', - $ProcessID - ) - ); - Stop-Process -Id $ProcessID -Force; - } -} - -$TCPSocket | Add-Member -membertype ScriptMethod -name 'IsSocketOpenAndValid' -value { - param([int]$port); - - [string]$PidFile = $Icinga2.PidManager.PidFileName($port); - - [string]$FullPidPath = $Icinga2.PidManager.FullPidPath($PidFile); - - if ((Test-Path $FullPidPath) -eq $FALSE) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - [string]::Format( - 'No PID-File found for TCP socket on port "{0}". Trying to close socket...', - $port - ) - ); - - # Even when the PID-File does not exist, try to gracefull shutdown the socket - $this.CloseTCPSocket($port); - return $FALSE; - } - - [int]$ProcessID = $Icinga2.PidManager.ProcessID($FullPidPath); - - if ([string]::IsNullOrEmpty($ProcessID) -eq $TRUE) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - [string]::Format( - 'No process ID found for socket on port "{0}". Trying to close socket anyway...', - $port - ) - ); - - # Even when the PID-File does not exist, try to gracefull shutdown the socket - $this.CloseTCPSocket($port); - return $FALSE; - } - - try { - # Look for the Process over WMI, as we might run as Service User and require - # to fetch the entire scope of running processes - if ($Icinga2.PidManager.PidProcess($ProcessID) -ne $null) { - return $TRUE; - } - - # Socket does not exist or is not valid. Perform a cleanup and return false - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - [string]::Format( - 'The socket configuration for port "{0}" is not valid. Performing cleanup...', - $port - ) - ); - - $this.CloseTCPSocket($port); - return $FALSE; - } catch [System.Exception] { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Exception, - [string]::Format( - 'Exception while trying to lookup the process for socket port "{0}": {1}...', - $port, - $_.Exception.Message - ) - ); - } - - $this.CloseTCPSocket($port); - return $FALSE; -} - -return $TCPSocket; \ No newline at end of file diff --git a/core/include/Utils.ps1 b/core/include/Utils.ps1 deleted file mode 100644 index 5ea6af0..0000000 --- a/core/include/Utils.ps1 +++ /dev/null @@ -1,12 +0,0 @@ -# Provide a collection of utility functions for the module -[hashtable]$Utils = @{}; - -Get-ChildItem (Join-Path -Path $PSScriptRoot -ChildPath '\utils\') -Filter *.ps1 | - Foreach-Object { - $path = $_.FullName; - $name = $_.Name.Replace('.ps1', ''); - - $Utils.Add($name, (& $path)); - } - -return $Utils; \ No newline at end of file diff --git a/core/include/utils/AdminShell.ps1 b/core/include/utils/AdminShell.ps1 deleted file mode 100644 index 5961ea4..0000000 --- a/core/include/utils/AdminShell.ps1 +++ /dev/null @@ -1,12 +0,0 @@ -$AdminShell = New-Object -TypeName PSObject; -$AdminShell | Add-Member -membertype ScriptMethod -name 'IsAdminShell' -value { - $CurrentIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent(); - $WindowsPrincipal = New-Object System.Security.Principal.WindowsPrincipal($CurrentIdentity); - - if (-Not $WindowsPrincipal.IsInRole([System.Security.Principal.WindowsBuiltInRole]::Administrator)) { - return $FALSE; - } - return $TRUE; -} - -return $AdminShell; \ No newline at end of file diff --git a/core/include/utils/AuthHelper.ps1 b/core/include/utils/AuthHelper.ps1 deleted file mode 100644 index 9509bbc..0000000 --- a/core/include/utils/AuthHelper.ps1 +++ /dev/null @@ -1,63 +0,0 @@ -Add-Type -AssemblyName System.DirectoryServices.AccountManagement; - -$AuthHelper = New-Object -TypeName PSObject; - -<# - # This function will allow us to authenticate against either a - # Domain Controller or the local machine the module runs on. - # For security reasons, Username and Password have to be - # stored within a SecureString. If no Domain is specified, - # a login will always be attempted to the local machine - #> -$AuthHelper | Add-Member -membertype ScriptMethod -name 'Login' -value { - param([SecureString]$UserName, [SecureString]$Password, [String]$Domain); - - # Base handling: We try to authenticate against a local user on the machine - [string]$AuthMethod = [System.DirectoryServices.AccountManagement.ContextType]::Machine; - [string]$AuthDomain = $env:COMPUTERNAME; - - # If we specify a domain, we should authenticate against our Domain - if ([string]::IsNullOrEmpty($Domain) -eq $FALSE) { - $AuthMethod = [System.DirectoryServices.AccountManagement.ContextType]::Domain; - $AuthDomain = $Domain; - } - - try { - # Create an Account Management object based on the above determined settings - $AccountService = New-Object System.DirectoryServices.AccountManagement.PrincipalContext( - $AuthMethod, - $AuthDomain - ); - } catch { - # Regardless of the error, print the message and return false to prevent further execution - $Icinga2.Log.Write($Icinga2.Enums.LogState.Exception, $_.Exception.Message); - return 0; - } - - # In case we couldn't setup the Account Service, always return false - if ($AccountService -eq $null) { - return 0; - } - - try { - # Try to authenticate and either return true or false as integer - [int]$AuthResult = [int]($AccountService.ValidateCredentials( - $Icinga2.Utils.SecureString.ConvertFrom($UserName), - $Icinga2.Utils.SecureString.ConvertFrom($Password) - )); - - return $AuthResult; - } catch { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - [string]::Format( - 'Failed to authenticate with the provided user credentials. Error: {0}', - $_.Exception.Message - ) - ); - } - - return 0; -} - -return $AuthHelper; \ No newline at end of file diff --git a/core/include/utils/IniParser.ps1 b/core/include/utils/IniParser.ps1 deleted file mode 100644 index 8fad7f0..0000000 --- a/core/include/utils/IniParser.ps1 +++ /dev/null @@ -1,75 +0,0 @@ -<# - # Helper class allowing to read INI files basicly - # and return the content as Hashtable - #> - -$IniParser = New-Object -TypeName PSObject; - -$IniParser | Add-Member -membertype ScriptMethod -name 'LoadFromArray' -value { - param([array]$content, [bool]$CutLastSpace); - - [hashtable]$IniContent = @{}; - [string]$IniKey = ''; - [string]$SubIniKey = ''; - - # First, loop all lines of our NTP config - foreach ($item in $content) { - # At first we require to parse the section argument for the config - if ($item.Contains('[')) { - $IniKey = $item.Replace('[', '').Replace(']', ''); - $IniContent.Add($IniKey, @{ }); - continue; - } - - if ([string]::IsNullOrEmpty($item) -eq $TRUE) { - continue; - } - - # In case our entry does not contain ':', we are not loading a config entry - if ($item.Contains(':') -eq $FALSE) { - $SubIniKey = $item; - $IniContent[$IniKey].Add($SubIniKey, @{ }); - continue; - } - - # Now as we found an config entry point, split the result at first to get - # the key of our config. Afterwards we load the value by removing all - # spaces before the actual value - [array]$ConfigData = $item.Split(':'); - [string]$ConfigKey = $ConfigData[0]; - [string]$ConfigValue = $item.Substring($item.IndexOf(':') + 1, $item.Length - $item.IndexOf(':') - 1); - - # Some INI files (like NTP) add additional details behind the values if they - # are configured by Local or Remote for example. With this we can cut these - # informations out, idependently from our configured OS language - if ($CutLastSpace -eq $TRUE) { - $ConfigValue = $ConfigValue.Substring(0, $ConfigValue.LastIndexOf(' ')); - } - - while ($ConfigValue[0] -eq ' ') { - $ConfigValue = $ConfigValue.Substring(1, $ConfigValue.Length - 1); - } - - # It could happen that within a section keys are being overwritten again - # We should take care of this and update a possible added key with the - # next configured values to receive only the correct configuration as result - # as it is interpreted by the time service - if ([string]::IsNullOrEmpty($SubIniKey) -eq $TRUE) { - if ($IniContent[$IniKey].ContainsKey($ConfigKey) -eq $FALSE) { - $IniContent[$IniKey].Add($ConfigKey, $ConfigValue); - } else { - $IniContent[$IniKey][$ConfigKey] = $ConfigValue; - } - } else { - if ($IniContent[$IniKey][$SubIniKey].ContainsKey($ConfigKey) -eq $FALSE) { - $IniContent[$IniKey][$SubIniKey].Add($ConfigKey, $ConfigValue); - } else { - $IniContent[$IniKey][$SubIniKey][$ConfigKey] = $ConfigValue; - } - } - } - - return $IniContent; -} - -return $IniParser; \ No newline at end of file diff --git a/core/include/utils/Modules.ps1 b/core/include/utils/Modules.ps1 deleted file mode 100644 index dc75cbb..0000000 --- a/core/include/utils/Modules.ps1 +++ /dev/null @@ -1,154 +0,0 @@ -<# - # Helper class for accessing and handling modules in a - # more easier and managed way - #> - -$Modules = New-Object -TypeName PSObject; - -$Modules | Add-Member -membertype ScriptMethod -name 'LoadIncludes' -value { - param([string]$modulename, $Config); - - $modulename = $modulename.ToLower(); - $modulename = $modulename.Replace('.ps1', ''); - - [string]$ModuleDir = Join-Path ` - -Path $Icinga2.App.RootPath ` - -ChildPath ( - [string]::Format( - '\modules\include\{0}', - $modulename - ) - ) - - [hashtable]$ModuleIndludes = @{}; - - if ( (Test-Path $ModuleDir) -eq $FALSE) { - return $ModuleIndludes; - } - - Get-ChildItem $ModuleDir -Filter *.ps1 | - Foreach-Object { - [string]$name = $_.Name.ToLower().Replace( - '.ps1', - '' - ); - try { - $ModuleIndludes.Add( - $name, - (& $_.FullName -Config $Config) - ); - } catch { - $ModuleIndludes.Add( - $name, - [string]::Format( - 'Failed to execute include "{0}" for module "{1}". Exception: {2}', - $name, - $modulename, - $_.Exception.Message - ) - ); - } - } - - return $ModuleIndludes; -} - -$Modules | Add-Member -membertype ScriptMethod -name 'FlushModuleCache' -value { - param([string]$modulename); - - if ($Icinga2.Cache.Modules.ContainsKey($modulename) -eq $FALSE) { - return; - } - - $Icinga2.Cache.Modules[$modulename] = @{ }; -} - -$Modules | Add-Member -membertype ScriptMethod -name 'AddCacheElement' -value { - param([string]$modulename, [string]$cachename, $value); - - if ($Icinga2.Cache.Modules.ContainsKey($modulename) -eq $FALSE) { - $Icinga2.Cache.Modules.Add($modulename, @{ }); - } - - if ($Icinga2.Cache.Modules[$modulename].ContainsKey($cachename) -eq $FALSE) { - $Icinga2.Cache.Modules[$modulename].Add($cachename, $value); - } else { - $Icinga2.Cache.Modules[$modulename][$cachename] = $value; - } -} - -$Modules | Add-Member -membertype ScriptMethod -name 'GetCacheElement' -value { - param([string]$modulename, [string]$cachename); - - if ($Icinga2.Cache.Modules.ContainsKey($modulename) -eq $FALSE) { - return @{ }; - } - - if ($Icinga2.Cache.Modules[$modulename].ContainsKey($cachename) -eq $FALSE) { - return @{ }; - } - - return $Icinga2.Cache.Modules[$modulename][$cachename]; -} - -$Modules | Add-Member -membertype ScriptMethod -name 'GetHashtableDiff' -value { - param([hashtable]$new, [hashtable]$cache, [array]$addkeys); - - [hashtable]$DiffTable = @{ - FullList = @{ }; - Removed = @( ); - Added = $null; - Modified = @{ }; - } - - if ($cache -eq $null -or $cache.Count -eq 0) { - $DiffTable.FullList = $new; - } else { - # Each additional call will only send the diffs to the server - $int = 0; - foreach ($cachedProcess in $cache.Keys) { - $oldProcess = $cache[$cachedProcess]; - - # In case a service is no longer present on our system, send the process Id - # only so we can delete it from our database - if ($new.ContainsKey($cachedProcess) -eq $FALSE) { - $DiffTable['Removed'] += $oldProcess.ProcessId; - } else { - # If we know about a process, only send the values which have been updated - # since the last check - $newProcess = $new[$cachedProcess]; - - foreach ($entry in $newProcess.Keys) { - $oldValue = $oldProcess[$entry]; - $newValue = $newProcess[$entry]; - - if ($oldValue -ne $newValue) { - if ($DiffTable['Modified'].ContainsKey($cachedProcess) -eq $FALSE) { - $DiffTable['Modified'].Add($cachedProcess, @{ }); - } - $DiffTable['Modified'][$cachedProcess].Add($entry, $newValue); - } - } - - if ($DiffTable['Modified'].ContainsKey($cachedProcess) -eq $TRUE) { - foreach($entry in $addkeys) { - if ($DiffTable['Modified'][$cachedProcess].ContainsKey($entry) -eq $FALSE -and - $newProcess.ContainsKey($entry) -eq $TRUE) { - - $DiffTable['Modified'][$cachedProcess].Add($entry, $newProcess[$entry]); - } - } - } - - $new.Remove($cachedProcess); - } - } - - # All other processes are new and should be added - $DiffTable['Added'] = $new; - } - - return $DiffTable; -} - -return $Modules; \ No newline at end of file diff --git a/core/include/utils/SSL.ps1 b/core/include/utils/SSL.ps1 deleted file mode 100644 index a0f893d..0000000 --- a/core/include/utils/SSL.ps1 +++ /dev/null @@ -1,111 +0,0 @@ - -$SSL = New-Object -TypeName PSObject; -$SSL | Add-Member -membertype ScriptMethod -name 'LoadServerCertificate' -value { - - if ((Get-Icinga-Setup) -eq $FALSE) { - $Icinga2.Log.WriteConsole( - $Icinga2.Enums.LogState.Warning, - 'The module has not been configured yet. Skipping certificate loading' - ); - return; - } - - try { - $CertStore = New-Object System.Security.Cryptography.X509Certificates.X509Store( - $Icinga2.Config.'certstore.name', - $Icinga2.Config.'certstore.location' - ); - $CertStore.Open("ReadOnly"); - - $ServerCertificate = $null; - - [string]$CertName = $Icinga2.Config.'certstore.certificate.name'; - [string]$CertThumbprint = $Icinga2.Config.'certstore.certificate.thumbprint'; - - # Try to discover the certificate based on our FQDN - if ([string]::IsNullOrEmpty($CertName) -eq $TRUE -And [string]::IsNullOrEmpty($CertThumbprint) -eq $TRUE) { - $CertName = [System.Net.Dns]::GetHostEntry('localhost').HostName; - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - [string]::Format( - 'Trying to discover certificate for this host with FQDN "{0}"', - $CertName - ) - ); - } - - foreach ($cert in $CertStore.Certificates) { - if ([string]::IsNullOrEmpty($CertThumbprint) -eq $FALSE) { - if ($CertThumbprint.ToLower() -eq $cert.Thumbprint.ToLower()) { - $ServerCertificate = $cert; - break; - } - } - - if ([string]::IsNullOrEmpty($CertName) -eq $FALSE) { - [string]$CNCertName = [string]::Format('CN={0}', $CertName.ToLower()); - if ($CNCertName.ToLower() -eq $cert.Subject.ToLower()) { - $ServerCertificate = $cert; - - try { - $result = Test-Certificate -Cert $cert -ErrorAction SilentlyContinue -WarningAction SilentlyContinue; - if ($result -eq $FALSE) { - continue; - } - } catch { - continue; - } - - break; - } - } - } - - $certificate = $null; - - if ($ServerCertificate -ne $null) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - [string]::Format( - 'Using certificate "{0}" with thumbprint "{1}"', - $ServerCertificate.Subject, - $ServerCertificate.Thumbprint - ) - ); - $certificate = New-Object System.Security.Cryptography.X509Certificates.X509Certificate2; - $certificate.Import($ServerCertificate.RawData) - } - - $CertStore.Close(); - - return $certificate; - } catch [System.ComponentModel.Win32Exception] { - # This error occures in case we provide a cert store and location which is not accessable - # from our current user. We have to simply drop everything and close every possible - # connection - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Exception, - 'SSL-Error: Unable to access provided certificate from the user space this module is started with.' - ); - } catch [System.NotSupportedException] { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Exception, - 'The used SSL certificate is not providing a linked private key and cannot be used as Server certificate' - ); - } catch { - # Handle every other error here - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Exception, - $_.Exception.Message - ); - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Exception, - $_.Exception - ); - } - - return $null; -} - -return $SSL; \ No newline at end of file diff --git a/core/include/utils/SecureString.ps1 b/core/include/utils/SecureString.ps1 deleted file mode 100644 index 52848e9..0000000 --- a/core/include/utils/SecureString.ps1 +++ /dev/null @@ -1,29 +0,0 @@ -<# - # Helper class allowing to easily convert strings into SecureStrings - # and vice-versa - #> - -$SecureString = New-Object -TypeName PSObject; - -$SecureString | Add-Member -membertype ScriptMethod -name 'ConvertTo' -value { - param([string]$string); - - [SecureString]$SecureString = ConvertTo-SecureString -AsPlainText $string -Force; - - return $SecureString; -} - -$SecureString | Add-Member -membertype ScriptMethod -name 'ConvertFrom' -value { - param([SecureString]$SecureString); - - if ($SecureString -eq $null) { - return ''; - } - - [IntPtr]$BSTR = [System.Runtime.InteropServices.Marshal]::SecureStringToBSTR($SecureString) - [string]$String = [System.Runtime.InteropServices.Marshal]::PtrToStringAuto($BSTR) - - return $String; -} - -return $SecureString; \ No newline at end of file diff --git a/core/include/utils/WebHelper.ps1 b/core/include/utils/WebHelper.ps1 deleted file mode 100644 index dfdd2dd..0000000 --- a/core/include/utils/WebHelper.ps1 +++ /dev/null @@ -1,296 +0,0 @@ -$WebHelper = New-Object -TypeName PSObject; - -$WebHelper | Add-Member -membertype ScriptMethod -name 'ParseApiMessage' -value { - param([SecureString]$message); - - try { - [hashtable]$HeaderContent = @{}; - - if ($message -eq $null) { - return $HeaderContent; - } - - [string]$HTMLMessage = $Icinga2.Utils.SecureString.ConvertFrom($message); - - [string]$HTMLContent = ''; - if ($HTMLMessage.Contains("`r`n`r`n")) { - [int]$EOFIndex = $HTMLMessage.IndexOf("`r`n`r`n") + 4; - $HTMLContent = $HTMLMessage.Substring( - $EOFIndex, - $HTMLMessage.Length - $EOFIndex - ); - # Remove the content from our message - if ([string]::IsNullOrEmpty($HTMLContent) -eq $FALSE) { - $HTMLMessage = $HTMLMessage.Replace($HTMLContent, ''); - } - } - - [array]$SingleHeaders = $HTMLMessage.Split("`r`n"); - $HTMLMessage = $null; - - # At first read the method, the http call and the protocol - $HeaderContent.Add( - 'base', - $this.ParseMethodAndUrl($SingleHeaders[0]) - ); - # Now add possible content to our hashtable - $HeaderContent.Add( - 'content', - $HTMLContent - ); - # Drop the first entry of the array, as we no longer require it - $SingleHeaders = $SingleHeaders | Select-Object -Skip 1; - - # Read the headers from the array - $HeaderContent.Add( - 'headers', - $this.ParseHeaders($SingleHeaders) - ); - # Flush the array from the memory - $SingleHeaders = $null; - - if ($HeaderContent.headers.ContainsKey('Authorization')) { - $HeaderContent.Add( - 'credentials', - $this.ParseUserCredentials( - $HeaderContent.headers.Authorization - ) - ); - $HeaderContent.headers.Remove('Authorization'); - } - - return $HeaderContent; - } - catch { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Exception, - [string]::Format( - 'Failed to parse HTTP content and headers. Error {0}', - $_.Exception.Message - ) - ); - } - - return $null; -} - -$WebHelper | Add-Member -membertype ScriptMethod -name 'ParseMethodAndUrl' -value { - param([string]$message); - - [array]$Content = $message.Split(' '); - [uri]$UriData = [uri][string]::Format( - 'https://localhost{0}', - $Content[1] - ); - - return @{ - method = $Content[0]; - call = [System.Web.HttpUtility]::UrlDecode( - $Content[1] - ); - protocol = $Content[2]; - segments = $UriData.Segments; - query = [System.Web.HttpUtility]::UrlDecode( - $UriData.Query - ); - } -} - -$WebHelper | Add-Member -membertype ScriptMethod -name 'ParseHeaders' -value { - param([array]$message); - - [hashtable]$Headers = @{}; - - foreach ($header in $message) { - [string]$HeaderName = ''; - [string]$HeaderValue = ''; - # Skip empty array values - if ([string]::IsNullOrEmpty($header) -eq $FALSE) { - if ($header.Contains(':')) { - [array]$Element = $header.Split(':'); - $HeaderName = $Element[0]; - - if ($Element.Count -gt 1) { - for ($i = 1; $i -le ($Element.Count - 1); $i++) { - $HeaderValue = -Join( - $HeaderValue, - $Element[$i], - ':' - ); - } - } - - # Remove the last added ':' at the end of the string - if ($HeaderValue.Length -gt 1) { - $HeaderValue = $HeaderValue.Substring( - 0, - $HeaderValue.Length - 1 - ); - } - - # In case the first letter of our value is a space, remove it - while ($HeaderValue[0] -eq ' ') { - $HeaderValue = $HeaderValue.Substring( - 1, - $HeaderValue.Length - 1 - ); - } - - if ($Headers.ContainsKey($HeaderName) -eq $FALSE) { - # We have to modify the Authorization header value a little more and also - # ensure we store it as secure string within our module - if ($HeaderName -eq 'Authorization') { - [array]$AuthArray = $HeaderValue.Split(' '); - # TODO: Shall we handle each auth type differently? - $Headers.Add( - $HeaderName, - $Icinga2.Utils.SecureString.ConvertTo($AuthArray[1]) - ); - $AuthArray = $null; - } else { - $Headers.Add($HeaderName, $HeaderValue); - } - } - } else { - $Headers.Add($header, $null); - } - } - } - - return $Headers; -} - -$WebHelper | Add-Member -membertype ScriptMethod -name 'ParseUserCredentials' -value { - param([SecureString]$Base64String); - - [hashtable]$Credentials = @{}; - - if ($Base64String -eq $null) { - return $Credentials; - } - - # Convert the Base64 Secure String back to a normal string - [string]$PlainAuth = [System.Text.Encoding]::UTF8.GetString( - [System.Convert]::FromBase64String( - $Icinga2.Utils.SecureString.ConvertFrom($Base64String) - ) - ); - $Base64String = $null; - - # If no ':' is within the string, the credential data is not properly formated - if ($PlainAuth.Contains(':') -eq $FALSE) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - 'Received invalid formated credentials as Base64 encoded.' - ); - $PlainAuth = $null; - return $Credentials; - } - - try { - # Build our User Data and Password from the string - [string]$UserData = $PlainAuth.Substring( - 0, - $PlainAuth.IndexOf(':') - ); - $Credentials.Add( - 'password', - $Icinga2.Utils.SecureString.ConvertTo( - $PlainAuth.Substring( - $PlainAuth.IndexOf(':') + 1, - $PlainAuth.Length - $UserData.Length - 1 - ) - ) - ); - - $PlainAuth = $null; - - # Extract a possible domain - if ($UserData.Contains('\')) { - # Split the auth string on the '\' - [array]$AuthData = $UserData.Split('\'); - # First value of the array is the Domain, second is the Username - $Credentials.Add('domain', $AuthData[0]); - $Credentials.Add( - 'user', - $Icinga2.Utils.SecureString.ConvertTo( - $AuthData[1] - ) - ); - $AuthData = $null; - } else { - $Credentials.Add('domain', $null); - $Credentials.Add( - 'user', - $Icinga2.Utils.SecureString.ConvertTo( - $UserData - ) - ); - } - - $UserData = $null; - } catch { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Error, - 'Failed to handle authentication request. An exception occured while processing the request.' - ); - } - - return $Credentials; -} - -$WebHelper | Add-Member -membertype ScriptMethod -name 'ParseUrlCommand' -value { - param([string]$Argument); - - [hashtable]$StructuredCommand = @{}; - # If no = is included, we don't need to handle anything special - if ($Argument.Contains('=') -eq $FALSE) { - $StructuredCommand.Add($Argument, $null); - return $StructuredCommand; - } - - [int]$SeperatorIndex = $Argument.IndexOf('='); - [string]$Command = $Argument.Substring( - 0, - $SeperatorIndex - ); - $Command = $Command.Replace(' ', '').ToLower(); - - [array]$Values = @(); - [string]$Value = $Argument.Substring( - $SeperatorIndex + 1, - $Argument.Length - $SeperatorIndex - 1 - ); - - if ($Value.Contains(',') -eq $TRUE) { - [array]$Entries = $Value.Split(','); - foreach ($entry in $Entries) { - [string]$ParsedValue = $entry; - # Cut spaces before names of inputs - while ($ParsedValue[0] -eq ' ') { - $ParsedValue = $ParsedValue.Substring( - 1, - $ParsedValue.Length - 1 - ); - } - - # Cut spaces after names of inputs - while ($ParsedValue[$ParsedValue.Length - 1] -eq ' ') { - $ParsedValue = $ParsedValue.Substring( - 0, - $ParsedValue.Length - 1 - ); - } - $Values += $ParsedValue.ToLower(); - } - } else { - $Values += $Value.Replace(' ', '').ToLower(); - } - - # Filter out duplicate entries - $Values = $Values | Select-Object -Unique; - $StructuredCommand.Add($Command, $Values); - return $StructuredCommand; -} - -return $WebHelper; \ No newline at end of file diff --git a/core/init.ps1 b/core/init.ps1 deleted file mode 100644 index 99b7756..0000000 --- a/core/init.ps1 +++ /dev/null @@ -1,100 +0,0 @@ -# This script will initialse the entire module configuration for easier usage -param ( - [string]$RootDirectory = '', - [string]$ModuleName = '' -); - -# Create an internal 'namespace' for our environment -Set-Variable -Name Icinga2 -Option Constant -Value @{ - Function = @( - 'Use-Icinga', - 'Import-IcingaLib', - 'Get-IcingaPluginDir', - 'Get-IcingaCustomPluginDir', - 'Get-IcingaCacheDir', - 'Get-IcingaPowerShellConfigDir', - 'Get-Icinga-Lib', - 'Get-Icinga-Object', - 'Get-Icinga-Service', - 'Start-Icinga-Service', - 'Stop-Icinga-Service', - 'Restart-Icinga-Service', - 'Install-Icinga-Service', - 'Uninstall-Icinga-Service', - 'Install-Icinga', - 'Get-Icinga-Setup', - 'Start-Icinga-Daemon', - 'Stop-Icinga-Daemon', - 'Start-Icinga-Checker', - 'Stop-Icinga-Checker', - 'Get-Icinga-Command', - 'New-Icinga-Monitoring', - 'Get-Icinga-Counter', - 'Get-Icinga-Config', - 'Set-Icinga-Config', - 'Remove-Icinga-Config', - 'New-Icinga-Config' - ); -} - -# Define temporary variables to store the main current root and module name -# Note: Never use this variables within the module besides inside '\core\includes\' -$_InternalTempVariables = @{ - RootPath = $RootDirectory; - ModuleName = $ModuleName; -} -# End definition of temporary variables - -# Load all PowerShell scripts within our '\core\include\' directory and add the content with the name -# of the script into our namespace -Get-ChildItem (Join-Path -Path $PSScriptRoot -ChildPath '\include\') -Filter *.ps1 | - Foreach-Object { - $path = $_.FullName; - $name = $_.Name.Replace('.ps1', ''); - - # Add variables to a global namespace. Should only be used within the - # same PowerShell instance - try { - $include = (& $path); - } catch { - Write-Host ( - [string]::Format( - 'Failed to execute core module "{0}". Exception: {1}', - $name, - $_.Exception.Message - ) - ); - } - - if ([bool]($include.PSobject.Properties.Name -eq 'static') -eq $FALSE -Or $include.static -eq $TRUE) { - $Icinga2.Add($name, $include); - } - } - -# Flush the internal temp variable cache -$_InternalTempVariables = $null; - -# Load our System.Web helper class -[Reflection.Assembly]::LoadWithPartialName("System.Web") | Out-Null; - -$Icinga2.Add( - 'Cache', - @{ - # This will allow us to dynamicly initialise Performance Counters during - # startup to speed up actual checks later on. Of course counters will be - # cached anyway once they are executed, but will speed up first check - # executions for CPU Performance Counters for example - PerformanceCounter = @{ }; - # Pre-Load the Server SSL Certificate - Certificates = @{ Server = $Icinga2.Utils.SSL.LoadServerCertificate() }; - # Create a instance for storing TCP Sockets (in case we later want to listen in multi-sockets) - Sockets = @{ }; - # Store our checker configuration we receive from the remote endpoint - Checker = @{ }; - # This cache can be used for storing informations of modules to compare send informations - # as well as required data for a later execution of the same module again - Modules = @{ }; - } -); - -return $Icinga2; \ No newline at end of file diff --git a/core/monitoring.ps1 b/core/monitoring.ps1 deleted file mode 100644 index 3af9c6f..0000000 --- a/core/monitoring.ps1 +++ /dev/null @@ -1,118 +0,0 @@ -param( - [array]$Include = @(), - [array]$Exclude = @(), - [boolean]$ListModules = $FALSE, - $Config = $null, - [string]$AgentRoot = '' -) - -function ClassMonitoring() -{ - param( - [array]$Include = @(), - [array]$Exclude = @(), - [boolean]$ListModules = $FALSE, - $Config = $null, - [string]$AgentRoot = '' - ) - - [string]$ModuleDirectory = Join-Path $AgentRoot -ChildPath 'modules'; - [hashtable]$ModuleList = @{}; - [array]$AvailableModules = @(); - $ResultList = New-Object psobject -prop @{}; - - # Let's do a small fix here: We have defined 'include' within the URL, but - # we haven't specified any values. So lets assume we want to load all - # modules - if ($Include.Count -eq 1 -And [string]::IsNullOrEmpty($Include[0])) { - $Include[0] = '*'; - } - - # In case no includes are specified, lets include everything - if ($Include.Count -eq 0) { - $Include += '*'; - } - - <# - # In case no filter is specified, we asume we want to collect everything. - # Lets fetch all PowerShell Scripts within our module Directory - # Will also be used to return a list of installed modules - #> - if (($Include.Count -eq 1 -And $Include[0] -eq '*') -Or $ListModules) { - Get-ChildItem $ModuleDirectory -Filter *.ps1 | - Foreach-Object { - $path = $_.FullName - $name = $_.Name.Replace('.ps1', '').ToLower(); - - $ModuleList.Add($name, $path); - $AvailableModules += $name; - } - - if ($ListModules) { - return $AvailableModules; - } - } else { - # In case we provided a filter, try to locate these modules - foreach ($module in $Include) { - # Just to ensure we skip this argument in case it is provided - if ($module -eq '*') { - continue; - } - $module = $module.ToLower(); - [string]$file = [string]::Format('{0}.ps1', $module); - [string]$path = Join-Path $ModuleDirectory -ChildPath $file; - - if ($ModuleList.ContainsKey($module) -eq $FALSE) { - $ModuleList.Add($module, $path); - } - } - } - - foreach ($module in $Exclude) { - if ($ModuleList.ContainsKey($module)) { - $ModuleList.Remove($module); - } - } - - [System.Diagnostics.Stopwatch]$ModuleTimer = New-Object System.Diagnostics.Stopwatch; - # Now as we have our module list available, lets execute them to fetch informations - foreach ($module in $ModuleList.Keys) { - $ModuleTimer.Start(); - [string]$path = $ModuleList[$module]; - [hashtable]$ModuleResult = @{}; - $moduleConfig = $null; - - if ($Config -ne $null -AND $Config.$module -ne $null) { - $moduleConfig = $Config.$module; - } - - # First test if the specified module is available - if (Test-Path ($path)) { - try { - # If it is, execute the script and return the output - $ModuleResult.Add('output', (&$path -Config $moduleConfig)); - $ModuleResult.Add('response', 200); - $ModuleResult.Add('error', $null); - } catch { - # In case the script we tried to execute runs into a failure, return the exception message as result - $ModuleResult.Add('output', $null); - $ModuleResult.Add('response', 500); - $ModuleResult.Add('error', [string]::Format('Failed to execute module "{0}". Exeception: {1}', $module, $_.Exception.Message)); - } - } else { - # Include the module to our output with a small notify message - $ModuleResult.Add('output', $null); - $ModuleResult.Add('response', 404); - $ModuleResult.Add('error', 'Module not found'); - } - - $ModuleResult.Add('execution', $ModuleTimer.Elapsed.TotalSeconds); - $ModuleTimer.Stop(); - - $ResultList | Add-Member -Name $module -Type NoteProperty -Value $ModuleResult; - } - - return $ResultList; -} - -return ClassMonitoring -Include $Include -Exclude $Exclude -ListModules $ListModules -Config $Config -AgentRoot $AgentRoot; \ No newline at end of file diff --git a/core/perfcounter.ps1 b/core/perfcounter.ps1 deleted file mode 100644 index 99839be..0000000 --- a/core/perfcounter.ps1 +++ /dev/null @@ -1,577 +0,0 @@ -param( - [string]$Counter = '', - [string]$ListCounter = '', - [array]$CounterArray = @(), - [boolean]$ListCategories = $FALSE, - [boolean]$SkipWait = $FALSE, - # These arguments apply to CreateStructuredPerformanceCounterTable - # This is the category name we want to create a structured output - # Example: 'Network Interface' - [string]$CreateStructuredOutputForCategory = '', - # This is the hashtable of Performance Counters, created by - # PerformanceCounterArray - [hashtable]$StructuredCounterInput = @{}, - # This argument is just a helper to replace certain strings within - # a instance name with simply nothing. - # Example: 'HarddiskVolume1' => '1' - [array]$StructuredCounterInstanceCleanup = @() -); - -# This is our internal cache for Performance Counters already loaded -# In case the Icinga Agent is running as daemon, this hashtable is -# already initialised at the beginning. But if we run the Agent -# from the Powershell directly, we will require to build this cache -# within the environment to work properly and to receive valid data -if ($Icinga2.Cache.PerformanceCounter -eq $null) { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - 'Creating new performance counter cache' - ); - $Icinga2.Cache.PerformanceCounter = @{}; -} - -$Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - [string]::Format( - 'Performance Counter Cache content {0}', - ($Icinga2.Cache.PerformanceCounter | Out-String) - ) -); - -<# - # This function will provide a virtual object, containing an array - # of Performance Counters. The object has the following members: - # Name - # Value - # This will ensure we will not have to worry about looping an array - # of mutltiple instances within a counter handler, because this - # function will deal with everything, returning an hashtable - # containing the parent counter name including the values and - # samples for every single instance - #> -function PerformanceCounterArray() -{ - param( - [string]$FullName = '', - [array]$PerformanceCounters = @() - ); - - $pc_instance = New-Object -TypeName PSObject; - $pc_instance | Add-Member -membertype NoteProperty -name 'FullName' -value $FullName; - $pc_instance | Add-Member -membertype NoteProperty -name 'Counters' -value $PerformanceCounters; - - $pc_instance | Add-Member -membertype ScriptMethod -name 'Name' -value { - return $this.FullName; - } - - $pc_instance | Add-Member -membertype ScriptMethod -name 'Value' -value { - [hashtable]$CounterResults = @{}; - - foreach ($counter in $this.Counters) { - $CounterResults.Add($counter.Name(), $counter.Value()); - } - - return $CounterResults; - } - - return $pc_instance; -} - -<# - # This function will create a custom Performance Counter object with - # already initialised counters, which can be accessed with the - # following members: - # Name - # Value - # Like the PerformanceCounterArray, this will allow to fetch the - # current values of a single counter instance including the name - # of the counter. Within the PerformanceCounterArray function, - # objects created by this function are used. - #> -function PerformanceCounterObject() -{ - param( - [string]$FullName = '', - [string]$Category = '', - [string]$Instance = '', - [string]$Counter = '', - [boolean]$SkipWait = $FALSE - ); - - $pc_instance = New-Object -TypeName PSObject; - $pc_instance | Add-Member -membertype NoteProperty -name 'FullName' -value $FullName; - $pc_instance | Add-Member -membertype NoteProperty -name 'Category' -value $Category; - $pc_instance | Add-Member -membertype NoteProperty -name 'Instance' -value $Instance; - $pc_instance | Add-Member -membertype NoteProperty -name 'Counter' -value $Counter; - $pc_instance | Add-Member -membertype NoteProperty -name 'PerfCounter' -value $Counter; - $pc_instance | Add-Member -membertype NoteProperty -name 'SkipWait' -value $SkipWait; - - $pc_instance | Add-Member -membertype ScriptMethod -name 'Init' -value { - - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Debug, - [string]::Format('Creating new Counter for Category {0} with Instance {1} and Counter {2}. Full Name "{3}"', - $this.Category, - $this.Instance, - $this.Counter, - $this.FullName - ) - ); - - # Create the Performance Counter object we want to access - $this.PerfCounter = New-Object System.Diagnostics.PerformanceCounter; - $this.PerfCounter.CategoryName = $this.Category; - $this.PerfCounter.CounterName = $this.Counter; - - # Only add an instance in case it is defined - if ([string]::IsNullOrEmpty($this.Instance) -eq $FALSE) { - $this.PerfCounter.InstanceName = $this.Instance - } - - # Initialise the counter - try { - $this.PerfCounter.NextValue() | Out-Null; - } catch { - # Nothing to do here, will be handled later - } - - <# - # For some counters we require to wait a small amount of time to receive proper data - # Other counters do not need these informations and we do also not require to wait - # for every counter we use, once the counter is initialised within our environment. - # This will allow us to skip the sleep to speed up loading counters - #> - if ($this.SkipWait -eq $FALSE) { - Start-Sleep -Milliseconds 500; - } - } - - # Return the name of the counter as string - $pc_instance | Add-Member -membertype ScriptMethod -name 'Name' -value { - return $this.FullName; - } - - <# - # Return a hashtable containting the counter value including the - # Sample values for the counter itself. In case we run into an error, - # keep the counter construct but add an error message in addition. - #> - $pc_instance | Add-Member -membertype ScriptMethod -name 'Value' -value { - [hashtable]$CounterData = @{}; - - try { - [string]$CounterType = $this.PerfCounter.CounterType; - $CounterData.Add('value', $this.PerfCounter.NextValue()); - $CounterData.Add('sample', $this.PerfCounter.NextSample()); - $CounterData.Add('help', $this.PerfCounter.CounterHelp); - $CounterData.Add('type', $CounterType); - $CounterData.Add('error', $null); - } catch { - $CounterData = @{}; - $CounterData.Add('value', $null); - $CounterData.Add('sample', $null); - $CounterData.Add('help', $null); - $CounterData.Add('type', $null); - $CounterData.Add('error', $_.Exception.Message); - } - - return $CounterData; - } - - # Initialiste the entire counter and internal handlers - $pc_instance.Init(); - - # Return this custom object - return $pc_instance; -} - -<# - # If some informations are missing, it could happen that - # we are unable to create a Performance Counter. - # In this case we will use this Null Object, containing - # the same member functions but allowing us to maintain - # stability without unwanted exceptions - #> - function PerformanceCounterNullObject() - { - param( - [string]$FullName = '', - [string]$ErrorMessage = '' - ); - - $pc_instance = New-Object -TypeName PSObject; - $pc_instance | Add-Member -membertype NoteProperty -name 'FullName' -value $FullName; - $pc_instance | Add-Member -membertype NoteProperty -name 'ErrorMessage' -value $ErrorMessage; - - $pc_instance | Add-Member -membertype ScriptMethod -name 'Name' -value { - return $this.FullName; - } - - $pc_instance | Add-Member -membertype ScriptMethod -name 'Value' -value { - [hashtable]$ErrorMessage = @{}; - - $ErrorMessage.Add('value', $null); - $ErrorMessage.Add('sample', $null); - $ErrorMessage.Add('help', $null); - $ErrorMessage.Add('type', $null); - $ErrorMessage.Add('error', $this.ErrorMessage); - - return $ErrorMessage; - } - - return $pc_instance; - } - - <# - # This function will make monitoring an entire list of - # Performance counters even more easier. We simply provide - # an array of Performance Counters to this module - # and we will receive a construct-save result of an - # hashtable with all performance counters including - # the corresponding values. In that case the code - # size decreases for larger modules. - # Example: - $counter = Get-Icinga-Counter -CounterArray @( - '\Memory\Available Bytes', - '\Memory\% Committed Bytes In Use' - ); - #> - function CreatePerformanceCounterResult() - { - param( - [array]$CounterArray = @() - ) - - [hashtable]$CounterResult = @{}; - [bool]$RequireSleep = $FALSE; - foreach ($counter in $CounterArray) { - # We want to speed up things with loading, so we will check if a specified - # Counter is already cached within our hashtable. If it is not, we sleep - # at the end of the function the required 500ms and don't have to wait - # NumOfCounters * 500 milliseconds for the first runs. This will speed - # up the general loading of counters and will not require some fancy - # pre-caching / configuration handler - if ($Icinga2.Cache.PerformanceCounter -ne $null) { - if ($Icinga2.Cache.PerformanceCounter.ContainsKey($counter) -eq $FALSE) { - $RequireSleep = $TRUE; - } - } - $obj = CreatePerformanceCounter -Counter $counter -SkipWait $TRUE; - if ($CounterResult.ContainsKey($obj.Name()) -eq $FALSE) { - $CounterResult.Add($obj.Name(), $obj.Value()); - } - } - - # Above we initialse ever single counter and we only require a sleep once - # in case a new, yet unknown counter was added - if ($RequireSleep) { - Start-Sleep -Milliseconds 500; - - # Agreed, this is some sort of code duplication but it wouldn't make - # any sense to create a own function for this. Why are we doing - # this anway? - # Simple: In case we found counters which have yet not been initialised - # we did this above. Now we have waited 500 ms to receive proper - # values from these counters. As the previous generated result - # might have contained counters with 0 results, we will now - # check all counters again to receive the proper values. - # Agreed, might sound like a overhead, but the impact only - # applies to the first call of the module with the counters. - # This 'duplication' however decreased the execution from - # certain modules from 25s to 1s on the first run. Every - # additional run is then beeing executed within 0.x s - # which sounds like a very good performance and solution - $CounterResult = @{}; - foreach ($counter in $CounterArray) { - $obj = CreatePerformanceCounter -Counter $counter -SkipWait $TRUE; - if ($CounterResult.ContainsKey($obj.Name()) -eq $FALSE) { - $CounterResult.Add($obj.Name(), $obj.Value()); - } - } - } - - return $CounterResult; - } - -<# - # This is the main function which is called from this script, constructing our counters - # and loading possible sub-instances from our Performance Counter. - # It will return either an PerformanceCounterObject or PerformanceCounterArray - # which both contain the same members, allowing us to dynamicly use the objects - # without having to worry about exception. - #> -function CreatePerformanceCounter() -{ - param( - [string]$Counter = '', - [boolean]$SkipWait = $FALSE - ); - - # Simply use the counter name, like - # \Paging File(_total)\% Usage - if ([string]::IsNullOrEmpty($Counter) -eq $TRUE) { - return (PerformanceCounterNullObject -FullName $Counter -ErrorMessage 'Failed to initialise counter, as no counter was specified.'); - } - - [array]$CounterArray = $Counter.Split('\'); - [string]$UseCounterCategory = ''; - [string]$UseCounterName = ''; - [string]$UseCounterInstance = ''; - - # If we add the counter as it should be - # \Paging File(_total)\% Usage - # the first array element will be an empty string we can skip - # Otherwise the name was wrong and we should not continue - if (-Not [string]::IsNullOrEmpty($CounterArray[0])) { - return (PerformanceCounterNullObject -FullName $Counter -ErrorMessage ([string]::Format('Failed to deserialize counter "{0}". It seems the leading "\" is missing.', $Counter))); - } - - # In case our Performance Counter is containing instances, we should split - # The content and read the instance and counter category out - if ($CounterArray[1].Contains('(')) { - [array]$TmpCounter = $CounterArray[1].Split('('); - $UseCounterCategory = $TmpCounter[0]; - $UseCounterInstance = $TmpCounter[1].Replace(')', ''); - } else { - # Otherwise we only require the category - $UseCounterCategory = $CounterArray[1]; - } - - # At last get the actual counter containing our values - $UseCounterName = $CounterArray[2]; - - # Now as we know how the counter path is constructed and has been splitted into - # the different values, we need to know how to handle the instances of the counter - - # If we specify a instance with (*) we want the module to automaticly fetch all - # instances for this counter. This will result in an PerformanceCounterArray - # which contains the parent name including counters for all instances that - # have been found - if ($UseCounterInstance -eq '*') { - # In case we already loaded the counters once, return the finished array - if ($Icinga2.Cache.PerformanceCounter.ContainsKey($Counter) -eq $TRUE) { - return (PerformanceCounterArray -FullName $Counter -PerformanceCounters $Icinga2.Cache.PerformanceCounter[$Counter]); - } - - # If we need to build the array, load all instances from the counters and - # create single performance counters and add them to a custom array and - # later to a custom object - try { - [array]$AllCountersIntances = @(); - $CounterInstances = New-Object System.Diagnostics.PerformanceCounterCategory($UseCounterCategory); - foreach ($instance in $CounterInstances.GetInstanceNames()) { - [string]$NewCounterName = $Counter.Replace('*', $instance); - $NewCounter = PerformanceCounterObject -FullName $NewCounterName -Category $UseCounterCategory -Counter $UseCounterName -Instance $instance -SkipWait $SkipWait; - $AllCountersIntances += $NewCounter; - } - } catch { - return (PerformanceCounterNullObject -FullName $Counter -ErrorMessage ([string]::Format('Failed to deserialize instances for counter "{0}". Exception: "{1}".', $Counter, $_.Exception.Message))); - } - - # Add the parent counter including the array of Performance Counters to our - # caching mechanism and return the PerformanceCounterArray object for usage - # within the monitoring modules - $Icinga2.Cache.PerformanceCounter.Add($Counter, $AllCountersIntances); - return (PerformanceCounterArray -FullName $Counter -PerformanceCounters $AllCountersIntances); - } else { - # This part will handle the counters without any instances as well as - # specificly assigned instances, like (_Total) CPU usage. - - # In case we already have the counter within our cache, return the - # cached informations - if ($Icinga2.Cache.PerformanceCounter.ContainsKey($Counter) -eq $TRUE) { - return $Icinga2.Cache.PerformanceCounter[$Counter]; - } - - # If the cache is not present yet, create the Performance Counter object, - # and add it to our cache - $NewCounter = PerformanceCounterObject -FullName $Counter -Category $UseCounterCategory -Counter $UseCounterName -Instance $UseCounterInstance -SkipWait $SkipWait; - $Icinga2.Cache.PerformanceCounter.Add($Counter, $NewCounter); - } - - # This function will always return non-instance counters or - # specificly defined instance counters. Performance Counter Arrays - # are returned within their function. This is just to ensure that the - # function looks finished from developer point of view - return $Icinga2.Cache.PerformanceCounter[$Counter]; -} - -# -# This function will get handy in case we want to fetch Counters -# which have instances which might be helpful to group by their -# instances name. This will apply to Disk and Network Interface -# outputs for example, as it would be helpful to combine all -# counter results for a specific disk / interface in one -# result for easier working with these informations -# -function CreateStructuredPerformanceCounterTable -{ - param( - [string]$CounterCategory = '', - [hashtable]$PerformanceCounterHash = @{}, - [array]$InstanceNameCleanupArray = @() - ) - - # The storage variables we require to store our data - [array]$AvailableInstances = @(); - [hashtable]$StructuredCounterData = @{}; - - # With this little trick we can fetch all instances we have and get their unique name - $CounterInstances = New-Object System.Diagnostics.PerformanceCounterCategory($CounterCategory); - foreach ($instance in $CounterInstances.GetInstanceNames()) { - # For some counters we require to apply a 'cleanup' for the instance name - # Example Disks: Some disks are stored with the name - # 'HarddiskVolume1' - # To be able to map the volume correctly to disks, we require to remove - # 'HarddiskVolume' so only '1' will remain, which allows us to map the - # volume correctly afterwards - [string]$CleanInstanceName = $instance; - foreach ($cleanup in $InstanceNameCleanupArray) { - $CleanInstanceName = $CleanInstanceName.Replace($cleanup, ''); - } - $AvailableInstances += $CleanInstanceName; - } - - # Now let the real magic begin. - - # At first we will loop all instances of our Performance Counters, which means all - # instances we have found above. We build a new hashtable then to list the instances - # by their individual name and all corresponding counters as children - # This allows us a structured output with all data for each instance - foreach ($instance in $AvailableInstances) { - - # First build a hashtable for each instance to add data to later - $StructuredCounterData.Add($instance, @{}); - - # Now we need to loop all return values from our Performance Counters - foreach ($InterfaceCounter in $PerformanceCounterHash.Keys) { - # As we just looped the parent counter (Instance *), we now need to - # loop the actual counters for each instance - foreach ($interface in $PerformanceCounterHash[$InterfaceCounter]) { - # Finally let's loop through all the results which contain the values - # to build our new, structured hashtable - foreach ($entry in $interface.Keys) { - # Match the counters based on our current parent index - # (the instance name we want to add the values as children). - if ($entry.Contains('(' + $instance + ')')) { - # To ensure we don't transmit the entire counter name, - # we only want to include the name of the actual counter. - # There is no need to return - # \Network Interface(Desktopadapter Intel[R] Gigabit CT)\Bytes Received/sec - # the naming - # Bytes Received/sec - # is enough - [array]$TmpOutput = $entry.Split('\'); - [string]$OutputName = $TmpOutput[$TmpOutput.Count - 1]; - - # Now add the actual value to our parent instance with the - # improved value name, including the sample and counter value data - $StructuredCounterData[$instance].Add($OutputName, $interface[$entry]); - } - } - } - } - } - - return $StructuredCounterData; -} - -# -# This function will load all available Categories of Performance Counters -# from the registry and outputs them. This will ensure we can fetch the real -# english names instead of the localiced ones -# -function ListCounterCategories() -{ - $RegistryData = Get-ItemProperty -Path 'HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009' ` - -Name 'counter' | Select-Object -ExpandProperty Counter; - [array]$Counters = @(); - - # Now lets loop our registry data and fetch only for counter categories - # Ignore everything else and drop the information - foreach ($counter in $RegistryData) { - # First filter out the ID's of the performance counter - if (-Not ($counter -match "^[\d\.]+$") -And [string]::IsNullOrEmpty($counter) -eq $FALSE) { - # Now check if the value we got is a counter category - if ([System.Diagnostics.PerformanceCounterCategory]::Exists($counter) -eq $TRUE) { - $Counters += $counter; - } - } - } - - return $Counters; -} - -# -# Provide the name of a category to fetch all available counters and -# if there are any instances assigned to it -# -function ListCountersFromCategory() -{ - param ([string]$CounterCategory); - - [hashtable]$counters = @{}; - try { - # At first create our Performance Counter object for the category we specified - $Category = New-Object System.Diagnostics.PerformanceCounterCategory($CounterCategory); - - # Now loop through all keys to find the name of available counters - foreach ($counter in $Category.ReadCategory().Keys) { - [string]$CounterInstanceAddition = ''; - - # As counters might also have instances (like interfaces, disks, paging file), we should - # try to load them as well - foreach ($instance in $Category.ReadCategory()[$counter].Keys) { - # If we do not match this magic string, we have multiple instances we can access - # to get informations for different disks, volumes and interfaces for example - if ($instance -ne 'systemdiagnosticsperfcounterlibsingleinstance') { - # Re-Write the name we return of the counter to something we can use directly - # within our modules to load data from. A returned counter will look like this - # for example: - # \PhysicalDisk(*)\avg. disk bytes/read - [string]$UsableCounterName = [string]::Format('\{0}(*)\{1}', $CounterCategory, $counter); - if ($counters.ContainsKey($UsableCounterName) -eq $TRUE) { - $counters[$UsableCounterName] += $Category.ReadCategory()[$counter][$instance]; - } else { - $counters.Add($UsableCounterName, @( $Category.ReadCategory()[$counter][$instance] )); - } - } else { - # For counters with no instances, we still require to return a re-build Performance Counter - # output, to make later usage in our modules very easy. This can look like this: - # \System\system up time - [string]$UsableCounterName = [string]::Format('\{0}\{1}', $CounterCategory, $counter); - $counters.Add($UsableCounterName, $null); - } - } - }; - } catch { - # In case we run into an error, return an error message - $counters.Add('error', $_.Exception.Message); - } - - return $counters; -} - -if ([string]::IsNullOrEmpty($CreateStructuredOutputForCategory) -eq $FALSE) { - return (CreateStructuredPerformanceCounterTable ` - -CounterCategory $CreateStructuredOutputForCategory ` - -PerformanceCounterHash $StructuredCounterInput ` - -InstanceNameCleanupArray $StructuredCounterInstanceCleanup - ) -} - -if ($ListCategories -eq $TRUE) { - return ListCounterCategories; -} - -if ([string]::IsNullOrEmpty($ListCounter) -eq $FALSE) { - return ListCountersFromCategory -CounterCategory $ListCounter; -} - -# Make things easier by simply proividing an array of Performance Counter -# Names we wish to monitor -if ($CounterArray.Count -ne 0) { - return (CreatePerformanceCounterResult -CounterArray $CounterArray); -} - -return CreatePerformanceCounter -Counter $Counter -SkipWait $SkipWait; \ No newline at end of file diff --git a/core/setup.ps1 b/core/setup.ps1 deleted file mode 100644 index f857875..0000000 --- a/core/setup.ps1 +++ /dev/null @@ -1,97 +0,0 @@ -param( - [bool]$IsAgentIntalled = $FALSE -) - -function ClassSetup() -{ - param( - [bool]$IsAgentIntalled = $FALSE - ); - - $instance = New-Object -TypeName PSObject; - - $instance | Add-Member -membertype NoteProperty -name 'BaseDirectory' -value (Join-Path $Icinga2.App.RootPath -ChildPath 'agent'); - - $instance | Add-Member -membertype ScriptMethod -name 'Init' -value { - $IsInstalled = Get-Icinga-Config -Key 'setup.installed'; - - if ($IsAgentIntalled) { - if ($IsInstalled -eq $FALSE -Or $IsInstalled -eq $null) { - return 0; - } - } - - $this.CreateDirectories('config'); - $this.CreateDirectories('state'); - - if ($IsInstalled -eq $FALSE -Or $IsInstalled -eq $null) { - $this.InstallEventLog(); - $this.CreateConfig(); - } - - # At this point for this module, we require to return 1 as 'true' - return 1; - } - - $instance | Add-Member -membertype ScriptMethod -name 'CreateDirectories' -value { - param([string]$directory); - - [string]$path = Join-Path $this.BaseDirectory -ChildPath $directory; - if (-Not (Test-Path $path)) { - New-Item $path -ItemType Directory | Out-Null; - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - ([string]::Format('Creating new directory "{0}"', $path)) - ); - } - } - - $instance | Add-Member -membertype ScriptMethod -name 'InstallEventLog' -value { - try { - New-EventLog -LogName Application -Source ($Icinga2.Service.servicedisplayname) -ErrorAction Stop; - $Icinga2.Log.WriteConsole( - $Icinga2.Enums.LogState.Info, - [string]::Format( - 'Successfully installed EventLog "{0}" for this module', - $Icinga2.Service.servicedisplayname - ) - ); - } catch { - $Icinga2.Log.WriteConsole( - $Icinga2.Enums.LogState.Warning, - [string]::Format( - 'EventLog for "{0}" is already installed.', - $Icinga2.Service.servicedisplayname - ) - ); - } - } - - $instance | Add-Member -membertype ScriptMethod -name 'CreateConfig' -value { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Info, - '### Installing default configuration values ###' - ); - - Set-Icinga-Config -Key 'checker.server.host' -Value 'https://localhost/icingaweb2/windows/checkresult' | Out-Null; - Set-Icinga-Config -Key 'checker.ssl.verify' -Value $TRUE | Out-Null; - Set-Icinga-Config -Key 'tcp.socket.host' -Value 'localhost' | Out-Null; - Set-Icinga-Config -Key 'tcp.socket.port' -Value '5891' | Out-Null; - Set-Icinga-Config -Key 'service.name' -Value 'icinga2winservice' | Out-Null; - Set-Icinga-Config -Key 'service.displayname' -Value 'Icinga 2 Windows Service' | Out-Null; - Set-Icinga-Config -Key 'setup.installed' -Value $TRUE | Out-Null; - Set-Icinga-Config -Key 'certstore.name' -Value 'My' | Out-Null; - Set-Icinga-Config -Key 'certstore.location' -Value 'LocalMachine' | Out-Null; - Set-Icinga-Config -Key 'certstore.certificate.name' -Value '' | Out-Null; - Set-Icinga-Config -Key 'certstore.certificate.thumbprint' -Value '' | Out-Null; - Set-Icinga-Config -Key 'logger.directory' -Value '' | Out-Null; - Set-Icinga-Config -Key 'logger.debug' -Value $FALSE | Out-Null; - Set-Icinga-Config -Key 'authentication.enabled' -Value $FALSE | Out-Null; - Set-Icinga-Config -Key 'authentication.user' -Value '' | Out-Null; - Set-Icinga-Config -Key 'authentication.domain' -Value '' | Out-Null; - } - - return $instance.Init(); -} - -return ClassSetup -IsAgentIntalled $IsAgentIntalled; \ No newline at end of file diff --git a/modules/bios.ps1 b/modules/bios.ps1 deleted file mode 100644 index 11e842c..0000000 --- a/modules/bios.ps1 +++ /dev/null @@ -1,21 +0,0 @@ - - -function ClassBIOS -{ - # Lets load some bios informations - $BIOSInformation = Get-CimInstance Win32_BIOS; - [hashtable]$BIOSData = @{}; - - foreach ($bios_properties in $BIOSInformation) { - #$bios_datails = @{}; - foreach($bios in $bios_properties.CimInstanceProperties) { - #$bios_datails.Add($bios.Name, $bios.Value); - $BIOSData.Add($bios.Name, $bios.Value); - } - #$BIOSData.Add($bios_datails.DeviceID, $bios_datails); - } - - return $BIOSData; -} - -return ClassBIOS; \ No newline at end of file diff --git a/modules/certificates.ps1 b/modules/certificates.ps1 deleted file mode 100644 index bf6298d..0000000 --- a/modules/certificates.ps1 +++ /dev/null @@ -1,112 +0,0 @@ -param($Config = $null); - -function ClassCertificates() -{ - param($Config = $null); - - [hashtable]$CertStore = @{}; - [hashtable]$CertLocation = @{}; - [hashtable]$CertCounters = @{}; - - Set-Location 'cert:' | Out-Null; - $certs = Get-ChildItem -Recurse; - - foreach ($cert in $certs) { - if ($cert.LocationName) { - if ($CertStore.ContainsKey($cert.LocationName) -eq $FALSE) { - $CertStore.Add($cert.LocationName, @{}); - } - } - - if ($cert.IssuerName) { - [hashtable]$Certificate = @{}; - $Certificate.Add('Archived', $cert.Archived); - $Certificate.Add('HasPrivateKey', $cert.HasPrivateKey); - $Certificate.Add('IssuerName.Name', $cert.IssuerName.Name); - $Certificate.Add('IssuerName.Oid', $cert.IssuerName.Oid); - $Certificate.Add('NotAfter', $cert.NotAfter); - $Certificate.Add('NotBefore', $cert.NotBefore); - $Certificate.Add('SerialNumber', $cert.SerialNumber); - $Certificate.Add('SubjectName.Name', $cert.SubjectName.Name); - $Certificate.Add('SubjectOid.Oid', $cert.SubjectName.Oid); - $Certificate.Add('SignatureAlgorithm.Value', $cert.SignatureAlgorithm.Value); - $Certificate.Add('SignatureAlgorithm.FriendlyName', $cert.SignatureAlgorithm.FriendlyName); - $Certificate.Add('Thumbprint', $cert.Thumbprint); - $Certificate.Add('Version', $cert.Version); - $Certificate.Add('Issuer', $cert.Issuer); - $Certificate.Add('Subject', $cert.Subject); - $Certificate.Add('PSParentPath', $cert.PSParentPath); - $Certificate.Add('PSChildName', $cert.PSChildName); - $Certificate.Add('DnsNameList', $cert.DnsNameList); - - [string]$cert_store = (GetCertStore -CertPath $cert.PSPath); - [string]$cert_location = (GetCertLocation -CertPath $cert.PSPath); - - $Certificate.Add('CertStore', $cert_store); - $Certificate.Add('CertLocation', $cert_location); - - if ($CertLocation.ContainsKey($cert_location)) { - $CertLocation[$cert_location] += $Certificate; - } else { - $CertLocation.Add($cert_location, @( $Certificate )); - } - } - } - - foreach ($cert_arr in $CertLocation.Keys) { - foreach ($cert in $CertLocation[$cert_arr]) { - [string]$CertFullPathCache = [string]::Format( - '{0}\{1}\{2}', - $cert.CertStore, - $cert.CertLocation, - $cert.Thumbprint - ); - if ($CertCounters.ContainsKey($CertFullPathCache) -eq $FALSE) { - $CertCounters.Add($CertFullPathCache, 1); - } else { - $CertCounters[$CertFullPathCache] += 1; - } - if ($CertStore[$cert.CertStore].ContainsKey($cert.CertLocation)) { - [string]$CertThumbprintKey = $cert.Thumbprint; - if ($CertCounters[$CertFullPathCache] -gt 1) { - $CertThumbprintKey = [string]::Format( - '{0} ({1})', - $CertThumbprintKey, - $CertCounters[$CertFullPathCache] - ); - } - $CertStore[$cert.CertStore][$cert.CertLocation].Add($CertThumbprintKey, $cert); - } else { - $CertStore[$cert.CertStore].Add($cert.CertLocation, @{ $cert.Thumbprint = $cert }); - } - } - } - - return $CertStore -} - -function GetCertStore() -{ - param([string]$CertPath); - - $CertPath = $CertPath.Replace('Microsoft.PowerShell.Security\', ''); - $CertPath = $CertPath.Replace('Certificate::', ''); - - [array]$path = $CertPath.Split('\'); - - return $path[0]; -} - -function GetCertLocation() -{ - param([string]$CertPath); - - $CertPath = $CertPath.Replace('Microsoft.PowerShell.Security\', ''); - $CertPath = $CertPath.Replace('Certificate::', ''); - - [array]$path = $CertPath.Split('\'); - - return $path[1]; -} - -return ClassCertificates -Config $Config; \ No newline at end of file diff --git a/modules/cpu.ps1 b/modules/cpu.ps1 deleted file mode 100644 index 36a0f57..0000000 --- a/modules/cpu.ps1 +++ /dev/null @@ -1,18 +0,0 @@ -param($Config = $null); - -function ClassCPU -{ - param($Config = $null); - - # This will return a hashtable with every single counter - # We specify within the array - $counter = Get-Icinga-Counter -CounterArray @( - '\Processor(*)\% Processor Time', - '\System\Processor Queue Length', - '\System\Threads' - ); - - return $counter; -} - -return ClassCPU -Config $Config; \ No newline at end of file diff --git a/modules/disk.ps1 b/modules/disk.ps1 deleted file mode 100644 index b8097b7..0000000 --- a/modules/disk.ps1 +++ /dev/null @@ -1,96 +0,0 @@ -param($Config = $null); - -function ClassDisk() -{ - param($Config = $null); - # The storage variables we require to store our data - [hashtable]$StructuredDiskData = @{}; - - # This will return a hashtable with every single counter - # we specify within the array. Instead of returning all - # the values in the returned hashtable, we will rebuild - # the result a little to have a improved output which - # is more user friendly and allows us to check for - # certain disks / volumes in details with a simpler - # accessing possibility - $counter = Get-Icinga-Counter -CounterArray @( - '\PhysicalDisk(*)\% Disk Read Time', - '\PhysicalDisk(*)\Current Disk Queue Length', - '\PhysicalDisk(*)\Avg. Disk Bytes/Transfer', - '\PhysicalDisk(*)\Split IO/sec', - '\PhysicalDisk(*)\Disk Reads/sec', - '\PhysicalDisk(*)\Disk Writes/sec', - '\PhysicalDisk(*)\Disk Bytes/sec', - '\PhysicalDisk(*)\Avg. Disk Read Queue Length', - '\PhysicalDisk(*)\Avg. Disk sec/Write', - '\PhysicalDisk(*)\% Disk Time', - '\PhysicalDisk(*)\Avg. Disk sec/Transfer', - '\PhysicalDisk(*)\Avg. Disk Bytes/Write', - '\PhysicalDisk(*)\% Disk Write Time', - '\PhysicalDisk(*)\Avg. Disk Queue Length', - '\PhysicalDisk(*)\Disk Write Bytes/sec', - '\PhysicalDisk(*)\Avg. Disk sec/Read', - '\PhysicalDisk(*)\Disk Read Bytes/sec', - '\PhysicalDisk(*)\Disk Transfers/sec', - '\PhysicalDisk(*)\% Idle Time', - '\PhysicalDisk(*)\Avg. Disk Write Queue Length', - '\PhysicalDisk(*)\Avg. Disk Bytes/Read' - ); - - $logicalCounter = Get-Icinga-Counter -CounterArray @( - '\LogicalDisk(*)\Free Megabytes', - '\LogicalDisk(*)\% Free Space' - ); - - # This function will help us to build a structured output based on - # volumes / disks found within the instances. We will use our - # LogicalDisk as 'index' to assign our performance Counters to. - # In addition we then provide the hashtable of counters we fetched - # above. Last but not least we cleanup the instances name to replace - # 'HarddiskVolume1' for '1' for example, to ensure the mapping of disk - # informations is working as intended - [hashtable]$DiskData = Get-Icinga-Counter ` - -CreateStructuredOutputForCategory 'PhysicalDisk' ` - -StructuredCounterInput $counter; - - foreach ($counters in $logicalCounter.Keys) { - foreach ($counter in $logicalCounter[$counters].Keys) { - [string]$instance = $counter; - if ($instance.Contains('(') -And $instance.Contains(')')) { - [int]$bracketStart = $instance.IndexOf('(') + 1; - [int]$bracketEnd = $instance.IndexOf(')'); - $instance = $instance.Substring($bracketStart, $bracketEnd - $bracketStart); - $instanceArray = $counter.Split('\'); - $counterName = $instanceArray[$instanceArray.Length - 1]; - foreach ($disk in $DiskData.Keys) { - if ($disk.Contains($instance)) { - $DiskData[$disk].Add( - $counterName, - $logicalCounter[$counters][$counter] - ); - } - } - } - } - } - - # Rewrite our output a little to make it more user friendly - # This is unique for disks, as we want to remove the ':' from - # Drive Letters and add back the HarddiskVolume label to volumes - # to prevent having only a numeric table keys. Example: - # '1' => 'HarddiskVolume1' - foreach ($disk in $DiskData.Keys) { - $NewKey = $disk.Replace(':', ''); - if ($NewKey -match "^[\d\.]+$") { - $NewKey = [string]::Format('HarddiskVolume{0}', $NewKey); - } - if ($NewKey[0] -match "^[\d\.]+$") { - $NewKey = $NewKey.Substring(2, $NewKey.Length - 2); - } - $StructuredDiskData.Add($NewKey, $DiskData[$disk]); - } - - return $StructuredDiskData; -} - -return ClassDisk -Config $Config; \ No newline at end of file diff --git a/modules/hardware.ps1 b/modules/hardware.ps1 deleted file mode 100644 index ea47044..0000000 --- a/modules/hardware.ps1 +++ /dev/null @@ -1,6 +0,0 @@ -param($Config = $null); - -return $Icinga2.Utils.Modules.LoadIncludes( - $MyInvocation.MyCommand.Name, - $Config -); \ No newline at end of file diff --git a/modules/include/hardware/cpu.ps1 b/modules/include/hardware/cpu.ps1 deleted file mode 100644 index d813c1b..0000000 --- a/modules/include/hardware/cpu.ps1 +++ /dev/null @@ -1,19 +0,0 @@ -param($Config = $null); -# -# Fetch the CPU Hardware informations -# - -# Lets load some additional CPU informations, besides current performance counters -# It might be useful to get more details about the hardware itself -$CPUInformations = Get-CimInstance Win32_Processor; -[hashtable]$PhysicalCPUData = @{}; - -foreach ($cpu_properties in $CPUInformations) { - $cpu_datails = @{}; - foreach($cpu_core in $cpu_properties.CimInstanceProperties) { - $cpu_datails.Add($cpu_core.Name, $cpu_core.Value); - } - $PhysicalCPUData.Add($cpu_datails.DeviceID, $cpu_datails); -} - -return $PhysicalCPUData; \ No newline at end of file diff --git a/modules/include/hardware/disks.ps1 b/modules/include/hardware/disks.ps1 deleted file mode 100644 index fa0c6c0..0000000 --- a/modules/include/hardware/disks.ps1 +++ /dev/null @@ -1,70 +0,0 @@ -param($Config = $null); -# -# Fetch the Disk Hardware informations -# - -# Lets load some additional disk informations, besides current data -# It might be useful to get more details about the hardware itself -$DisksInformations = Get-CimInstance Win32_DiskDrive; - -[hashtable]$PhysicalDiskData = @{}; - -foreach ($disk_properties in $DisksInformations) { - $disk_datails = @{}; - foreach($disk in $disk_properties.CimInstanceProperties) { - $disk_datails.Add($disk.Name, $disk.Value); - } - $disk_datails.Add('DriveReference', @()); - $PhysicalDiskData.Add($disk_datails.DeviceID, $disk_datails); -} - -$DiskPartitionInfo = Get-WmiObject Win32_DiskDriveToDiskPartition; - -[hashtable]$MapDiskPartitionToLogicalDisk = @{}; - -foreach ($item in $DiskPartitionInfo) { - [string]$diskPartition = $item.Dependent.SubString( - $item.Dependent.LastIndexOf('=') + 1, - $item.Dependent.Length - $item.Dependent.LastIndexOf('=') - 1 - ); - $diskPartition = $diskPartition.Replace('"', ''); - - [string]$physicalDrive = $item.Antecedent.SubString( - $item.Antecedent.LastIndexOf('\') + 1, - $item.Antecedent.Length - $item.Antecedent.LastIndexOf('\') - 1 - ) - $physicalDrive = $physicalDrive.Replace('"', ''); - - $MapDiskPartitionToLogicalDisk.Add($diskPartition, $physicalDrive); -} - -$LogicalDiskInfo = Get-WmiObject Win32_LogicalDiskToPartition; - -foreach ($item in $LogicalDiskInfo) { - [string]$driveLetter = $item.Dependent.SubString( - $item.Dependent.LastIndexOf('=') + 1, - $item.Dependent.Length - $item.Dependent.LastIndexOf('=') - 1 - ); - $driveLetter = $driveLetter.Replace('"', ''); - - [string]$diskPartition = $item.Antecedent.SubString( - $item.Antecedent.LastIndexOf('=') + 1, - $item.Antecedent.Length - $item.Antecedent.LastIndexOf('=') - 1 - ) - $diskPartition = $diskPartition.Replace('"', ''); - - if ($MapDiskPartitionToLogicalDisk.ContainsKey($diskPartition)) { - foreach ($disk in $PhysicalDiskData.Keys) { - [string]$DiskId = $disk.SubString( - $disk.LastIndexOf('\') + 1, - $disk.Length - $disk.LastIndexOf('\') - 1 - ); - - if ($DiskId.ToLower() -eq $MapDiskPartitionToLogicalDisk[$diskPartition].ToLower()) { - $PhysicalDiskData[$disk]['DriveReference'] += $driveLetter; - } - } - } -} - -return $PhysicalDiskData; \ No newline at end of file diff --git a/modules/include/hardware/memory.ps1 b/modules/include/hardware/memory.ps1 deleted file mode 100644 index a47825e..0000000 --- a/modules/include/hardware/memory.ps1 +++ /dev/null @@ -1,59 +0,0 @@ -param($Config = $null); -# -# Fetch the Memory Hardware informations -# - -# Lets load some additional memory informations, besides current performance counters -# It might be useful to get more details about the hardware itself -$MemoryInformations = Get-CimInstance Win32_PhysicalMemory; -$capacity = $MemoryInformations | Measure-Object -Property capacity -Sum; - -# Lets load the details from our RAM modules -[hashtable]$PhysicalMemoryData = @{}; - -$PhysicalMemoryData.Add('Modules', $capacity.Count); - -foreach($memory_object in $MemoryInformations) { - $memory_datails = @{}; - $memory_datails.Add('caption', $memory_object.Caption); - $memory_datails.Add('desc', $memory_object.Description); - $memory_datails.Add('name', $memory_object.Name); - $memory_datails.Add('install_date', $memory_object.InstallDate); - $memory_datails.Add('status', $memory_object.Status); - $memory_datails.Add('creation_class_name', $memory_object.CreationClassName); - $memory_datails.Add('manufacturer', $memory_object.Manufacturer); - $memory_datails.Add('model', $memory_object.Model); - $memory_datails.Add('other_identifiying_info', $memory_object.OtherIdentifyingInfo); - $memory_datails.Add('part_number', $memory_object.PartNumber); - $memory_datails.Add('powered_on', $memory_object.PoweredOn); - $memory_datails.Add('serial_number', $memory_object.SerialNumber); - $memory_datails.Add('sku', $memory_object.SKU); - $memory_datails.Add('tag', $memory_object.Tag); - $memory_datails.Add('version', $memory_object.Version); - $memory_datails.Add('hot_swappable', $memory_object.HotSwappable); - $memory_datails.Add('removable', $memory_object.Removable); - $memory_datails.Add('replaceable', $memory_object.Replaceable); - $memory_datails.Add('form_factor', $memory_object.FormFactor); - $memory_datails.Add('bank_label', $memory_object.BankLabel); - $memory_datails.Add('capacity', $memory_object.Capacity); - $memory_datails.Add('data_width', $memory_object.DataWidth); - $memory_datails.Add('interleave_position', $memory_object.InterleavePosition); - $memory_datails.Add('memory_type', $memory_object.MemoryType); - $memory_datails.Add('position_in_row', $memory_object.PositionInRow); - $memory_datails.Add('speed', $memory_object.Speed); - $memory_datails.Add('total_width', $memory_object.TotalWidth); - $memory_datails.Add('attributes', $memory_object.Attributes); - $memory_datails.Add('configured_clock_speed', $memory_object.ConfiguredClockSpeed); - $memory_datails.Add('configured_voltage', $memory_object.ConfiguredVoltage); - $memory_datails.Add('device_locator', $memory_object.DeviceLocator); - $memory_datails.Add('interleave_data_depth', $memory_object.InterleaveDataDepth); - $memory_datails.Add('max_voltage', $memory_object.MaxVoltage); - $memory_datails.Add('min_voltage', $memory_object.MinVoltage); - $memory_datails.Add('smbios_memory_type', $memory_object.SMBIOSMemoryType); - $memory_datails.Add('type_detail', $memory_object.TypeDetail); - $memory_datails.Add('ps_computer_name', $memory_object.PSComputerName); - - $PhysicalMemoryData.Add($memory_object.Tag, $memory_datails); -} - -return $PhysicalMemoryData; \ No newline at end of file diff --git a/modules/include/updates/hotfixes.ps1 b/modules/include/updates/hotfixes.ps1 deleted file mode 100644 index 7dba95a..0000000 --- a/modules/include/updates/hotfixes.ps1 +++ /dev/null @@ -1,27 +0,0 @@ -param($Config = $null); - -[hashtable]$HotfixInfo = @{}; -[hashtable]$HotfixNameCache = @{}; - -# First fetch all of our hotfixes -$Hotfixes = Get-Hotfix; - -foreach ($property in $Hotfixes) { - [hashtable]$HotfixData = @{}; - foreach ($hotfix in $property.Properties) { - $HotfixData.Add($hotfix.Name, $hotfix.Value); - } - - [string]$name = [string]::Format('{0} [{1}]', $HotfixData.HotFixID, $HotfixData.InstalledOn); - - if ($HotfixNameCache.ContainsKey($name) -eq $FALSE) { - $HotfixNameCache.Add($name, 1); - } else { - $HotfixNameCache[$name] += 1; - $name = [string]::Format('{0} ({1})', $name, $HotfixNameCache[$name]); - } - - $HotfixInfo.Add($name, $HotfixData); -} - -return $HotfixInfo; \ No newline at end of file diff --git a/modules/include/updates/pending.ps1 b/modules/include/updates/pending.ps1 deleted file mode 100644 index e0726fd..0000000 --- a/modules/include/updates/pending.ps1 +++ /dev/null @@ -1,76 +0,0 @@ -param($Config = $null); - -[hashtable]$PendingUpdates = @{}; -[hashtable]$PendingUpdateNameCache = @{}; -# Fetch all informations about installed updates and add them -$WindowsUpdates = New-Object -ComObject "Microsoft.Update.Session"; -$SearchIndex = $WindowsUpdates.CreateUpdateSearcher(); - -try { - # Get a list of current pending updates which are not yet installed on the system - $Pending = $SearchIndex.Search("IsInstalled=0"); - $PendingUpdates.Add('count', $Pending.Updates.Count); - - foreach ($update in $Pending.Updates) { - [hashtable]$PendingUpdateDetails = @{}; - $PendingUpdateDetails.Add('Title', $update.Title); - $PendingUpdateDetails.Add('Deadline', $update.Deadline); - $PendingUpdateDetails.Add('Description', $update.Description); - $PendingUpdateDetails.Add('IsBeta', $update.IsBeta); - $PendingUpdateDetails.Add('IsDownloaded', $update.IsDownloaded); - $PendingUpdateDetails.Add('IsHidden', $update.IsHidden); - $PendingUpdateDetails.Add('IsInstalled', $update.IsInstalled); - $PendingUpdateDetails.Add('IsMandatory', $update.IsMandatory); - $PendingUpdateDetails.Add('IsUninstallable', $update.IsUninstallable); - $PendingUpdateDetails.Add('Languages', $update.Languages); - $PendingUpdateDetails.Add('LastDeploymentChangeTime', $update.LastDeploymentChangeTime); - $PendingUpdateDetails.Add('MaxDownloadSize', $update.MaxDownloadSize); - $PendingUpdateDetails.Add('MinDownloadSize', $update.MinDownloadSize); - $PendingUpdateDetails.Add('MoreInfoUrls', $update.MoreInfoUrls); - $PendingUpdateDetails.Add('MsrcSeverity', $update.MsrcSeverity); - $PendingUpdateDetails.Add('RecommendedCpuSpeed', $update.RecommendedCpuSpeed); - $PendingUpdateDetails.Add('RecommendedHardDiskSpace', $update.RecommendedHardDiskSpace); - $PendingUpdateDetails.Add('RecommendedMemory', $update.RecommendedMemory); - $PendingUpdateDetails.Add('ReleaseNotes', $update.ReleaseNotes); - $PendingUpdateDetails.Add('SecurityBulletinIDs', $update.SecurityBulletinIDs); - $PendingUpdateDetails.Add('SupersededUpdateIDs', $update.SupersededUpdateIDs); - $PendingUpdateDetails.Add('SupportUrl', $update.SupportUrl); - $PendingUpdateDetails.Add('Type', $update.Type); - $PendingUpdateDetails.Add('UninstallationNotes', $update.UninstallationNotes); - $PendingUpdateDetails.Add('UninstallationBehavior', $update.UninstallationBehavior); - $PendingUpdateDetails.Add('UninstallationSteps', $update.UninstallationSteps); - $PendingUpdateDetails.Add('KBArticleIDs', $update.KBArticleIDs); - $PendingUpdateDetails.Add('DeploymentAction', $update.DeploymentAction); - $PendingUpdateDetails.Add('DownloadPriority', $update.DownloadPriority); - $PendingUpdateDetails.Add('RebootRequired', $update.RebootRequired); - $PendingUpdateDetails.Add('IsPresent', $update.IsPresent); - $PendingUpdateDetails.Add('CveIDs', $update.CveIDs); - $PendingUpdateDetails.Add('BrowseOnly', $update.BrowseOnly); - $PendingUpdateDetails.Add('PerUser', $update.PerUser); - $PendingUpdateDetails.Add('AutoSelection', $update.AutoSelection); - $PendingUpdateDetails.Add('AutoDownload', $update.AutoDownload); - - [string]$name = [string]::Format('{0} [{1}]', $update.Title, $update.LastDeploymentChangeTime); - - if ($PendingUpdateNameCache.ContainsKey($name) -eq $FALSE) { - $PendingUpdateNameCache.Add($name, 1); - } else { - $PendingUpdateNameCache[$name] += 1; - $name = [string]::Format('{0} ({1})', $name, $PendingUpdateNameCache[$name]); - } - - $PendingUpdates.Add($name, $PendingUpdateDetails); - } -} catch { - if ($PendingUpdates.ContainsKey('Count') -eq $FALSE) { - $PendingUpdates.Add('count', 0); - } else { - $PendingUpdates['count'] = 0; - } - $PendingUpdates.Add('error', [string]::Format( - 'Failed to query Windows Update server: {0}', - $_.Exception.Message - )); -} - -return $PendingUpdates; \ No newline at end of file diff --git a/modules/include/updates/updates.ps1 b/modules/include/updates/updates.ps1 deleted file mode 100644 index 4432fbf..0000000 --- a/modules/include/updates/updates.ps1 +++ /dev/null @@ -1,72 +0,0 @@ -param($Config = $null); - -# Fetch all informations about installed updates and add them -$WindowsUpdates = New-Object -ComObject "Microsoft.Update.Session"; -$SearchIndex = $WindowsUpdates.CreateUpdateSearcher(); -[hashtable]$UpdateList = @{}; -[hashtable]$UpdateInstalled = @{}; -[hashtable]$UpdateUninstalled = @{}; -[hashtable]$UpdateOther = @{}; - -# Operation ID's -# 1: Installed -# 2: Uninstalled -# 3: Other - -# At first get a list of our Windows Update history -$Updates = $SearchIndex.QueryHistory(0, $SearchIndex.GetTotalHistoryCount()) | - Select-Object Operation, ResultCode, HResult, Date, Title, Description, ServiceID, SupportUrl; - -foreach ($update in $Updates) { - [string]$UpdateKey = [string]::Format('{0} [{1}|{2}]', $update.Title, $update.Date, $update.HResult); - switch ($update.Operation) { - 1 { - if ($UpdateInstalled.ContainsKey($UpdateKey) -eq $FALSE) { - $UpdateInstalled.Add($UpdateKey, $update); - } else { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - [string]::Format( - 'Unable to add update "{0}" to update list. The key with content "{1}" is already present', - $UpdateKey, - $update - ) - ); - } - }; - 2 { - if ($UpdateUninstalled.ContainsKey($UpdateKey) -eq $FALSE) { - $UpdateUninstalled.Add($UpdateKey, $update); - } else { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - [string]::Format( - 'Unable to add update "{0}" to update list. The key with content "{1}" is already present', - $UpdateKey, - $update - ) - ); - } - }; - default { - if ($UpdateOther.ContainsKey($UpdateKey) -eq $FALSE) { - $UpdateOther.Add($UpdateKey, $update); - } else { - $Icinga2.Log.Write( - $Icinga2.Enums.LogState.Warning, - [string]::Format( - 'Unable to add update "{0}" to update list. The key with content "{1}" is already present', - $UpdateKey, - $update - ) - ); - } - }; - } -} - -$UpdateList.Add('installed', $UpdateInstalled); -$UpdateList.Add('uninstalled', $UpdateUninstalled); -$UpdateList.Add('other', $UpdateOther); - -return $UpdateList; \ No newline at end of file diff --git a/modules/memory.ps1 b/modules/memory.ps1 deleted file mode 100644 index 95dca6d..0000000 --- a/modules/memory.ps1 +++ /dev/null @@ -1,32 +0,0 @@ - - -param($Config = $null); - -function ClassMemory -{ - param($Config = $null); - # This will return a hashtable with every single counter - # We specify within the array - $counter = Get-Icinga-Counter -CounterArray @( - '\Memory\Available Bytes', - '\Memory\% Committed Bytes In Use', - '\Memory\Committed Bytes', - '\Memory\Cache Bytes', - '\Memory\Pool Nonpaged Bytes', - '\Memory\Pages/sec', - '\Memory\Page Reads/sec', - '\Memory\Page Writes/sec', - '\Memory\Pages Input/sec', - '\Memory\Pages Output/sec', - '\Paging File(*)\% Usage', - '\Paging File(*)\% Usage Peak' - ); - - # Lets load some additional memory informations, besides current performance counters - $ComputerInformation = Get-CimInstance Win32_ComputerSystem; - $counter.Add('\Memory\Physical Memory Total Bytes', @{ 'value' = $ComputerInformation.TotalPhysicalMemory; 'sample' = @{ }; }); - - return $counter; -} - -return ClassMemory -Config $Config; \ No newline at end of file diff --git a/modules/network.ps1 b/modules/network.ps1 deleted file mode 100644 index b22a470..0000000 --- a/modules/network.ps1 +++ /dev/null @@ -1,154 +0,0 @@ -param($Config = $null); - -function ClassNetwork -{ - param($Config = $null); - # The storage variables we require to store our data - [hashtable]$NetworkData = @{}; - [hashtable]$StructuredInterfaceData = @{}; - - $CachedNetwork = $Icinga2.Utils.Modules.GetCacheElement( - $MyInvocation.MyCommand.Name, - 'NetworkData' - ); - - # This will return a hashtable with every single counter - # we specify within the array. Instead of returning all - # the values in the returned hashtable, we will rebuild - # the result a little to have a improved output which - # is more user friendly and allows us to check for - # certain interfaces in detail with a simpler - # accessing possibility - $counter = Get-Icinga-Counter -CounterArray @( - '\Network Interface(*)\Bytes Received/sec', - '\Network Interface(*)\Bytes Sent/sec', - '\Network Interface(*)\Packets Received Unicast/sec', - '\Network Interface(*)\Packets Sent Unicast/sec', - '\Network Interface(*)\Packets Received Non-Unicast/sec', - '\Network Interface(*)\Packets Sent Non-Unicast/sec', - '\Network Interface(*)\Packets Outbound Errors', - '\Network Interface(*)\Packets Sent/sec', - '\Network Interface(*)\TCP RSC Exceptions/sec', - '\Network Interface(*)\Packets Outbound Discarded', - '\Network Interface(*)\TCP RSC Coalesced Packets/sec', - '\Network Interface(*)\Bytes Total/sec', - '\Network Interface(*)\Current Bandwidth', - '\Network Interface(*)\Packets Received Unknown', - '\Network Interface(*)\TCP Active RSC Connections', - '\Network Interface(*)\Offloaded Connections', - '\Network Interface(*)\Packets/sec', - '\Network Interface(*)\Packets Received Errors', - '\Network Interface(*)\Packets Received/sec', - '\Network Interface(*)\Packets Received Discarded', - '\Network Interface(*)\Output Queue Length', - '\Network Interface(*)\TCP RSC Average Packet Size' - ); - - # This function will help us to build a structured output based on - # interfaces found within the instances. We will use our - # Network Interface as 'index' to assign our performance Counters to. - # In addition we then provide the hashtable of counters we fetched - # above. - $StructuredInterfaceData = Get-Icinga-Counter ` - -CreateStructuredOutputForCategory 'Network Interface' ` - -StructuredCounterInput $counter; - - $NetworkData.Add('interfaces', $StructuredInterfaceData); - - # Add additional details to our interfaces, like MAC Address, Interface Index and current connection status - $NetworkAdapter = Get-WMIObject Win32_NetworkAdapter; - - [hashtable]$DuplicateIDCache = @{}; - - foreach ($adapter in $NetworkAdapter) { - # The Performance Counter return values in brackets with [], while WMI returns () - # In addition, WMI uses / within Interface names, while Perf Counter uses _ - # We need to take care about this here - [string]$AdapterName = $adapter.Name.Replace('(', '[').Replace(')', ']'); - [string]$AdapterName = $AdapterName.Replace('/', '_'); - [string]$AdapterName = $AdapterName.Replace('#', '_'); - - # To ensure duplicate interface names will not cause this module - # to crash, we will have to build up a cache and add numeric - # additions. - if ($DuplicateIDCache.ContainsKey($AdapterName) -eq $FALSE) { - $DuplicateIDCache.Add($AdapterName, 0); - } - - # In case we add adapters we have no performance counters for, - # create a new hashtable object for the name - if ($StructuredInterfaceData.ContainsKey($AdapterName) -eq $FALSE) { - $StructuredInterfaceData.Add($AdapterName, @{}); - } else { - # In case the interface does already exist, check if we require - # to rename the interface with a index ID in addition. As we - # have to ensure Performance Counters are added to Physical Adapters - # only, we will focus in these indexes. All other instances will - # receive a follow-up ID. - [int]$ID = $DuplicateIDCache[$AdapterName] + 1; - if ($adapter.PhysicalAdapter -eq $FALSE) { - $ID += 1; - $DuplicateIDCache[$AdapterName] = $ID; - } else { - # Physical Adapters always have unique names, therefor we should - # always use index 1 for these to ensure Performance Counter data - # is added to the correct interfaces - $ID = 1; - } - - # Only add index ID's to interfaces in case we are not equal 1 - if ($ID -ne 1) { - $AdapterName = [string]::Format('{0} ({1})', - $AdapterName, - $ID - ); - $StructuredInterfaceData.Add($AdapterName, @{}); - } - } - - # Add the WMI informations to this interface - $StructuredInterfaceData[$AdapterName].Add('NetConnectionID', $adapter.NetConnectionID); - $StructuredInterfaceData[$AdapterName].Add('InterfaceIndex', $adapter.InterfaceIndex); - $StructuredInterfaceData[$AdapterName].Add('NetConnectionStatus', $adapter.NetConnectionStatus); - $StructuredInterfaceData[$AdapterName].Add('DeviceID', $adapter.DeviceID); - $StructuredInterfaceData[$AdapterName].Add('MACAddress', $adapter.MACAddress); - $StructuredInterfaceData[$AdapterName].Add('ServiceName', $adapter.ServiceName); - $StructuredInterfaceData[$AdapterName].Add('Speed', $adapter.Speed); - $StructuredInterfaceData[$AdapterName].Add('AdapterType', $adapter.AdapterType); - $StructuredInterfaceData[$AdapterName].Add('NetworkAddresses', $adapter.NetworkAddresses); - $StructuredInterfaceData[$AdapterName].Add('Manufacturer', $adapter.Manufacturer); - $StructuredInterfaceData[$AdapterName].Add('PNPDeviceID', $adapter.PNPDeviceID); - $StructuredInterfaceData[$AdapterName].Add('PhysicalAdapter', $adapter.PhysicalAdapter); - } - - # In addition to our general network interface data, it might also - # be helpful to have a look on the configured routing table - $RoutingTable = Get-CimInstance -ClassName Win32_IP4RouteTable - [array]$RoutingData = @(); - - foreach ($tables in $RoutingTable) { - $routes = @{}; - foreach($route in $tables.CimInstanceProperties) { - $routes.Add($route.Name, $route.Value); - } - $RoutingData += $routes; - } - - $NetworkData.Add('routes', $RoutingData); - - $Icinga2.Utils.Modules.AddCacheElement( - $MyInvocation.MyCommand.Name, - 'NetworkData', - $NetworkData - ); - - return $Icinga2.Utils.Modules.GetHashtableDiff( - $NetworkData.Clone(), - $CachedNetwork.Clone() - ); - - # At the end simply return the entire hashtable - return $NetworkData; -} - -return ClassNetwork -Config $Config; \ No newline at end of file diff --git a/modules/ntp.ps1 b/modules/ntp.ps1 deleted file mode 100644 index 211773a..0000000 --- a/modules/ntp.ps1 +++ /dev/null @@ -1,34 +0,0 @@ -param($Config = $null); - -function ClassNTP -{ - param($Config = $null); - [hashtable]$NTPInformations = @{}; - # This will return a hashtable with every single counter - # we specify within the array - $counter = Get-Icinga-Counter -CounterArray @( - '\Windows Time service\clock frequency adjustment', - '\Windows Time service\ntp client time source count', - '\Windows Time service\ntp server outgoing responses', - '\Windows Time service\computed time offset', - '\Windows Time service\ntp roundtrip delay', - '\Windows Time service\ntp server incoming requests' - ); - $NTPInformations.Add('counter', $counter); - - # Load the source from which we receive our NTP config - $NTPInformations.Add('source', (&W32tm /query /source)); - - # Load the NTP config and parse it properly - $NTPInformations.Add( - 'config', - $Icinga2.Utils.IniParser.LoadFromArray( - (&W32tm /query /configuration), - $TRUE - ) - ); - - return $NTPInformations; -} - -return ClassNTP -Config $Config; \ No newline at end of file diff --git a/modules/process.ps1 b/modules/process.ps1 deleted file mode 100644 index 15cc71b..0000000 --- a/modules/process.ps1 +++ /dev/null @@ -1,113 +0,0 @@ -param($Config = $null); - -$CachedProcessList = $Icinga2.Utils.Modules.GetCacheElement( - $MyInvocation.MyCommand.Name, - 'ProcessList' -); - -$ProcessList = Get-WmiObject Win32_Process; -$ProcessPerfList = Get-WmiObject Win32_PerfFormattedData_PerfProc_Process; - -$NumberOfCPUThreads = $Icinga2.System.NumberOfCPUThreads; - -[hashtable]$ProcessReference = @{}; -[hashtable]$Processes = @{}; -[hashtable]$ProcessValues = @{ - FullList = @{ }; - Removed = @( ); - Added = $null; - Modified = @{ }; -} - -foreach ($process in $ProcessList) { - [string]$ProcessKey = [string]::Format( - '{0} [{1}]', - $process.ProcessName, - $process.ProcessId - ); - - [hashtable]$ProcessInfo = @{}; - - $ProcessInfo.Add('Name', $process.Name); - $ProcessInfo.Add('ProcessId', $process.ProcessId); - $ProcessInfo.Add('Priority', $process.Priority); - $ProcessInfo.Add('PageFileUsage', $process.PageFileUsage); - $ProcessInfo.Add('ThreadCount', $process.ThreadCount); - $ProcessInfo.Add('KernelModeTime', $process.KernelModeTime); - $ProcessInfo.Add('UserModeTime', $process.UserModeTime); - $ProcessInfo.Add('WorkingSetSize', $process.WorkingSetSize); - $ProcessInfo.Add('CommandLine', $process.CommandLine); -<# - # These are not required by now - $ProcessInfo.Add('Caption', $process.Caption); - $ProcessInfo.Add('CreationClassName', $process.CreationClassName); - $ProcessInfo.Add('CreationDate', $process.CreationDate); - $ProcessInfo.Add('CSCreationClassName', $process.CSCreationClassName); - $ProcessInfo.Add('CSName', $process.CSName); - $ProcessInfo.Add('Description', $process.Description); - $ProcessInfo.Add('ExecutablePath', $process.ExecutablePath); - $ProcessInfo.Add('ExecutionState', $process.ExecutionState); - $ProcessInfo.Add('Handle', $process.Handle); - $ProcessInfo.Add('HandleCount', $process.HandleCount); - $ProcessInfo.Add('InstallDate', $process.InstallDate); - $ProcessInfo.Add('MaximumWorkingSetSize', $process.MaximumWorkingSetSize); - $ProcessInfo.Add('MinimumWorkingSetSize', $process.MinimumWorkingSetSize); - $ProcessInfo.Add('OSCreationClassName', $process.OSCreationClassName); - $ProcessInfo.Add('OSName', $process.OSName); - $ProcessInfo.Add('OtherOperationCount', $process.OtherOperationCount); - $ProcessInfo.Add('OtherTransferCount', $process.OtherTransferCount); - $ProcessInfo.Add('PageFaults', $process.PageFaults); - $ProcessInfo.Add('ParentProcessId', $process.ParentProcessId); - $ProcessInfo.Add('PeakPageFileUsage', $process.PeakPageFileUsage); - $ProcessInfo.Add('PeakVirtualSize', $process.PeakVirtualSize); - $ProcessInfo.Add('PeakWorkingSetSize', $process.PeakWorkingSetSize); - $ProcessInfo.Add('PrivatePageCount', $process.PrivatePageCount); - $ProcessInfo.Add('QuotaNonPagedPoolUsage', $process.QuotaNonPagedPoolUsage); - $ProcessInfo.Add('QuotaPagedPoolUsage', $process.QuotaPagedPoolUsage); - $ProcessInfo.Add('QuotaPeakNonPagedPoolUsage', $process.QuotaPeakNonPagedPoolUsage); - $ProcessInfo.Add('QuotaPeakPagedPoolUsage', $process.QuotaPeakPagedPoolUsage); - $ProcessInfo.Add('ReadOperationCount', $process.ReadOperationCount); - $ProcessInfo.Add('ReadTransferCount', $process.ReadTransferCount); - $ProcessInfo.Add('SessionId', $process.SessionId); - $ProcessInfo.Add('Status', $process.Status); - $ProcessInfo.Add('TerminationDate', $process.TerminationDate); - $ProcessInfo.Add('VirtualSize', $process.VirtualSize); - $ProcessInfo.Add('WindowsVersion', $process.WindowsVersion); - $ProcessInfo.Add('WriteOperationCount', $process.WriteOperationCount); - $ProcessInfo.Add('WriteTransferCount', $process.WriteTransferCount); -#> - $ProcessReference.Add($process.ProcessId, $ProcessKey); - $Processes.Add($ProcessKey, $ProcessInfo); -} - -foreach ($perfdata in $ProcessPerfList) { - if ($perfdata.Name -eq '_Total') { - continue; - } - if ($ProcessReference.ContainsKey($perfdata.IDProcess)) { - $Processes[$ProcessReference[$perfdata.IDProcess]].Add( - 'WorkingSetPrivate', - $perfdata.WorkingSetPrivate - ); - # Note: In order to get the correct CPU time in % we have to divide the - # Processor Time with the amount of threads installed on our CPU - $Processes[$ProcessReference[$perfdata.IDProcess]].Add( - 'PercentProcessorTime', - [math]::Round(($perfdata.PercentProcessorTime / $NumberOfCPUThreads), 2) - ); - } -} - -$Processes.Add('count', $Processes.count); - -$Icinga2.Utils.Modules.AddCacheElement( - $MyInvocation.MyCommand.Name, - 'ProcessList', - $Processes -); - -return $Icinga2.Utils.Modules.GetHashtableDiff( - $Processes.Clone(), - $CachedProcessList.Clone(), - @('ProcessId') -); \ No newline at end of file diff --git a/modules/services.ps1 b/modules/services.ps1 deleted file mode 100644 index 02ea528..0000000 --- a/modules/services.ps1 +++ /dev/null @@ -1,62 +0,0 @@ -param($Config = $null); - -function ClassService() -{ - param($Config = $null); - $services = Get-Service; - - [hashtable]$ServiceData = @{}; - - $CachedServiceData = $Icinga2.Utils.Modules.GetCacheElement( - $MyInvocation.MyCommand.Name, - 'ServiceData' - ); - - foreach ($service in $services) { - [hashtable]$ServiceInfo = @{}; - - $ServiceInfo.Add('display_name', $service.DisplayName); - $ServiceInfo.Add('service_name', $service.ServiceName); - $ServiceInfo.Add('can_pause_and_continue', $service.CanPauseAndContinue); - $ServiceInfo.Add('can_shutdown', $service.CanShutdown); - $ServiceInfo.Add('can_stop', $service.CanStop); - $ServiceInfo.Add('service_handle', $service.ServiceHandle); - $ServiceInfo.Add('status', $service.Status); - $ServiceInfo.Add('service_type', $service.ServiceType); - $ServiceInfo.Add('start_type', $service.StartType); - $ServiceInfo.Add('site', $service.Site); - $ServiceInfo.Add('container', $service.Container); - - [array]$DependentServices = $null; - foreach ($dependency in $service.DependentServices) { - if ($DependentServices -eq $null) { $DependentServices = @(); } - $DependentServices += $dependency.Name; - } - $ServiceInfo.Add('dependent_services', $DependentServices); - - [array]$DependentServices = $null; - foreach ($dependency in $service.ServicesDependedOn) { - if ($DependentServices -eq $null) { $DependentServices = @(); } - $DependentServices += $dependency.Name; - } - $ServiceInfo.Add('depends_on', $DependentServices); - - $ServiceData.Add($service.Name, $ServiceInfo); - } - - $Icinga2.Utils.Modules.AddCacheElement( - $MyInvocation.MyCommand.Name, - 'ServiceData', - $ServiceData - ); - - return $Icinga2.Utils.Modules.GetHashtableDiff( - $ServiceData.Clone(), - $CachedServiceData.Clone(), - @('service_name') - ); - - return $ServiceData; -} - -return ClassService -Config $Config; \ No newline at end of file diff --git a/modules/updates.ps1 b/modules/updates.ps1 deleted file mode 100644 index ea47044..0000000 --- a/modules/updates.ps1 +++ /dev/null @@ -1,6 +0,0 @@ -param($Config = $null); - -return $Icinga2.Utils.Modules.LoadIncludes( - $MyInvocation.MyCommand.Name, - $Config -); \ No newline at end of file diff --git a/modules/windows.ps1 b/modules/windows.ps1 deleted file mode 100644 index 057defe..0000000 --- a/modules/windows.ps1 +++ /dev/null @@ -1,16 +0,0 @@ -param($Config = $null); - -function ClassWindows -{ - param($Config = $null); - $WindowsInformations = Get-CimInstance Win32_OperatingSystem; - - $windows_datails = @{}; - foreach($cpu_core in $WindowsInformations.CimInstanceProperties) { - $windows_datails.Add($cpu_core.Name, $cpu_core.Value); - } - - return $windows_datails; -} - -return ClassWindows -Config $Config; \ No newline at end of file From ac5d80175058cfb9c30f66e7c9eb5b605df5cabc Mon Sep 17 00:00:00 2001 From: Lord Hepipud Date: Sun, 3 Nov 2019 22:55:21 +0100 Subject: [PATCH 258/259] Add delay between service stop and framework upgrade --- lib/core/framework/Install-IcingaFrameworkUpdate.psm1 | 1 + 1 file changed, 1 insertion(+) diff --git a/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 b/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 index e84b8b0..cb29538 100644 --- a/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 +++ b/lib/core/framework/Install-IcingaFrameworkUpdate.psm1 @@ -61,6 +61,7 @@ function Install-IcingaFrameworkUpdate() if ($ServiceStatus -eq 'Running') { Stop-IcingaService 'icingapowershell'; + Start-Sleep -Seconds 1; } $NewDirectory = (Join-Path -Path $ModuleDirectory -ChildPath 'icinga-powershell-framework'); From f42ec96e55bc27efdb4814f9254c218d3e3fe4f2 Mon Sep 17 00:00:00 2001 From: Alexander Stoll Date: Mon, 4 Nov 2019 08:20:17 +0100 Subject: [PATCH 259/259] Fix documentation --- README.md | 6 +++--- doc/01-Introduction.md | 2 +- doc/03-WebIntegration.md | 2 +- doc/developerguide/01-NewIcingaCheck.md | 4 ++-- doc/installation/02-ManualInstallation.md | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/README.md b/README.md index bde1421..353280d 100644 --- a/README.md +++ b/README.md @@ -4,12 +4,12 @@ Icinga Module for Windows The Icinga PowerShell Framework provides a wide range of configuration and check possibilities to ensure an easy integration and full monitoring of Windows environments. Each single chapter of this documentation will describe parts of the module and the possibilities. -Before you continue, please take a look on the [installation guide](doc/02-Installation.md) +Before you continue, please take a look at the [installation guide](doc/02-Installation.md) Documentation ------------- -Please take a look on the following content to get to know the possibilities of the module including examples on how to use it. +Please take a look at the following content to get to know the possibilities of the module including examples on how to use it. * [Introduction](doc/01-Introduction.md) * [Installation Guide](doc/02-Installation.md) @@ -18,7 +18,7 @@ Please take a look on the following content to get to know the possibilities of Developer Guide ------------ -If you wish to extend the Framework by yourself or write custom plugins for your environment, please have a look on the [Developer Guide](doc/04-DeveloperGuide.md) for detailed explanations of functions and code examples. +If you wish to extend the Framework by yourself or write custom plugins for your environment, please have a look at the [Developer Guide](doc/04-DeveloperGuide.md) for detailed explanations of functions and code examples. Contributing ------------ diff --git a/doc/01-Introduction.md b/doc/01-Introduction.md index 805eead..d51c013 100644 --- a/doc/01-Introduction.md +++ b/doc/01-Introduction.md @@ -10,4 +10,4 @@ The following requirements have to be fullfilled: * Windows 7 / Windows 2008 R2 or later * PowerShell Version 4.x or higher -If you are ready to get started, take a look on the [installation guide](02-Installation.md). +If you are ready to get started, take a look at the [installation guide](02-Installation.md). diff --git a/doc/03-WebIntegration.md b/doc/03-WebIntegration.md index 6fa4549..e0286e2 100644 --- a/doc/03-WebIntegration.md +++ b/doc/03-WebIntegration.md @@ -33,7 +33,7 @@ Of course if you wish to actively send data to Icinga Web 2 for example, you can Start-Icinga-Checker ``` -For additional setup possibilities, please take a look on the following pages: +For additional setup possibilities, please take a look at the following pages: * [Use the module as Icinga Plugin Framework](12-Icinga2AgentExample.md) * [Install the module as Windows Service](10-InstallService.md) diff --git a/doc/developerguide/01-NewIcingaCheck.md b/doc/developerguide/01-NewIcingaCheck.md index 649c06d..27e47fd 100644 --- a/doc/developerguide/01-NewIcingaCheck.md +++ b/doc/developerguide/01-NewIcingaCheck.md @@ -8,7 +8,7 @@ Below you will find a list of functions and detailed descriptions including use The `IcingaCheck` is the basic start point for determining on how a certain value is performing. Checks will provide a bunch of internal commands within the PowerShell Object to analyse a value and get the Icinga result `Ok`, `Warning`, `Critical` including performance metrics. -Checks are always used wihtin Check Plugins to have a standardised method for properly handling the input. +Checks are always used within Check Plugins to have a standardised method for properly handling the input. It will be used like in this example: @@ -16,7 +16,7 @@ It will be used like in this example: $IcingaCheck = New-IcingaCheck -Name 'My Check' -Value 25 -Unit '%'; ``` -You will have to provide a `Name` for each check which **must** be unique within each Check Plugin. This will make it easier to differentiate between checks for results. The `Value` is mandatory as this will be the base for each single check to fetch the actual status. +You will have to provide a `Name` for each check which **must** be unique within each Check Plugin. This will make it easier to differentiate between checks for results. The `Value` is mandatory as this will be the basis for each single check to fetch the actual status. For performance metrics you can provide a `Unit` to ensure your graphing is displaying values as the should be diff --git a/doc/installation/02-ManualInstallation.md b/doc/installation/02-ManualInstallation.md index d87b865..858b141 100644 --- a/doc/installation/02-ManualInstallation.md +++ b/doc/installation/02-ManualInstallation.md @@ -41,4 +41,4 @@ The prefered way is to simply unblock the script files, allowing them to be exec Get-ChildItem -Path 'C:\Program Files\WindowsPowershell\Modules\icinga-powershell-framework' -Recurse | Unblock-File ``` -Once done, please try again if you are now able to run the module on your host. If you are still not able to run the module and/or its scripts, please have a look on the Microsoft documentation for the [Set-Execution-Policy](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-6) Cmdlet to modify the Execution Policy for running PowerShell modules on your host, matching your internal guidelines. +Once done, please try again if you are now able to run the module on your host. If you are still not able to run the module and/or its scripts, please have a look at the Microsoft documentation for the [Set-Execution-Policy](https://docs.microsoft.com/en-us/powershell/module/microsoft.powershell.security/set-executionpolicy?view=powershell-6) Cmdlet to modify the Execution Policy for running PowerShell modules on your host, matching your internal guidelines.