This commit is contained in:
Lord Hepipud 2019-09-13 17:04:09 +02:00
commit 782897be93
2 changed files with 560 additions and 2 deletions

View file

@ -0,0 +1,500 @@
<#
.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' = @{
'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.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' = 'Specifies if the plugin will return performance data output or not';
'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' = 'Specifies if the plugin will return performance data output or not';
'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' = $parameter.Description.Text;
'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' = 'Increase the plugin output for more information on the received result.';
'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' = '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'
}
}
);
}
}
}
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;
}

View file

@ -2,13 +2,69 @@ 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(
[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 +72,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);
}