2019-09-13 05:44:37 -04:00
<#
. 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 .
2019-10-31 12:24:30 -04:00
More Information on https : / / github . com / Icinga / icinga-powershell -framework
2019-09-13 05:44:37 -04:00
. 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
2019-10-30 13:19:08 -04:00
Get-IcingaCheckCommandConfig -OutDirectory 'C:\Users\icinga\config-exports'
2019-09-13 05:44:37 -04:00
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
2019-10-30 13:19:08 -04:00
Get-IcingaCheckCommandConfig Invoke-IcingaCheckBiosSerial , Invoke-IcingaCheckCPU -OutDirectory 'C:\Users\icinga\config-exports'
2019-09-13 05:44:37 -04:00
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 ','
2019-09-13 10:24:30 -04:00
. INPUTS
2019-09-13 05:44:37 -04:00
System . Array
2019-09-13 10:24:30 -04:00
. OUTPUTS
2019-09-13 05:44:37 -04:00
System . String
2019-09-13 10:24:30 -04:00
. LINK
2019-10-31 12:24:30 -04:00
https : / / github . com / Icinga / icinga-powershell -framework
2019-09-13 05:44:37 -04:00
2019-09-13 10:24:30 -04:00
. NOTES
2019-09-13 05:44:37 -04:00
#>
function Get-IcingaCheckCommandConfig ( )
{
param (
[ array ] $CheckName ,
2019-10-30 13:19:08 -04:00
[ string ] $OutDirectory
2019-09-13 05:44:37 -04:00
) ;
# Check whether all Checks will be exported or just the ones specified
if ( [ string ] :: IsNullOrEmpty ( $CheckName ) -eq $true ) {
$CheckName = ( Get-Command Invoke-IcingaCheck * ) . Name
}
2020-08-04 08:48:32 -04:00
[ int ] $FieldID = 2 ; # Starts at '2', because '0' and '1' are reserved for 'Verbose' and 'NoPerfData'
2019-09-13 05:44:37 -04:00
[ hashtable ] $Basket = @ { } ;
# Define basic hashtable structure by adding fields: "Datafield", "DataList", "Command"
$Basket . Add ( 'Datafield' , @ { } ) ;
$Basket . Add ( 'DataList' , @ { } ) ;
$Basket . Add ( 'Command' , @ { } ) ;
2019-09-25 13:56:05 -04:00
# 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 ;
}
) ;
2019-09-13 05:44:37 -04:00
# Loop through ${CheckName}, to get information on every command specified/all commands.
foreach ( $check in $CheckName ) {
2020-08-04 08:48:32 -04:00
2019-09-13 05:44:37 -04:00
# Get necessary syntax-information and more through cmdlet "Get-Help"
2019-10-30 13:19:08 -04:00
$Data = ( Get-Help $check ) ;
$ParameterList = ( Get-Command -Name $check ) . Parameters ;
$PluginNameSpace = $Data . Name . Replace ( 'Invoke-' , '' ) ;
2019-09-13 05:44:37 -04:00
# Add command Structure
$Basket . Command . Add (
2019-09-16 09:33:57 -04:00
$Data . Name , @ {
2019-09-25 13:56:05 -04:00
'arguments' = @ {
# Set the Command handling for every check command
2019-09-13 05:44:37 -04:00
'-C' = @ {
2020-08-06 11:46:29 -04:00
'value' = [ string ] :: Format ( 'try {{ Use-Icinga; }} catch {{ Write-Output {1}The Icinga PowerShell Framework is either not installed on the system or not configured properly. Please check https://icinga.com/docs/windows for further details{1}; exit 3; }}; Exit-IcingaPluginNotInstalled {1}{0}{1}; exit {0}' , $Data . Name , " ' " ) ;
2019-09-13 05:44:37 -04:00
'order' = '0' ;
}
}
2019-09-25 13:56:05 -04:00
'fields' = @ ( ) ;
'imports' = @ ( 'PowerShell Base' ) ;
2019-09-16 09:33:57 -04:00
'object_name' = $Data . Name ;
2019-09-13 05:44:37 -04:00
'object_type' = 'object' ;
2019-09-25 13:56:05 -04:00
'vars' = @ { } ;
2019-09-13 05:44:37 -04:00
}
) ;
# Loop through parameters of a given command
2019-09-16 09:33:57 -04:00
foreach ( $parameter in $Data . parameters . parameter ) {
2019-09-13 05:44:37 -04:00
2019-11-04 05:36:41 -05:00
$IsDataList = $FALSE ;
2019-10-29 04:08:44 -04:00
# 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
}
2019-09-13 05:44:37 -04:00
2019-10-30 13:19:08 -04:00
$IcingaCustomVariable = [ string ] :: Format ( '${0}_{1}_{2}$' , $PluginNameSpace , ( Get-Culture ) . TextInfo . ToTitleCase ( $parameter . type . name ) , $parameter . Name ) ;
2019-09-13 05:44:37 -04:00
2019-10-29 04:08:44 -04:00
# Todo: Should we improve this? Actually the handling would be identical, we just need to assign
# the proper field for this
2019-10-30 13:19:08 -04:00
if ( $IcingaCustomVariable -like '*_Int32_Verbose$' -Or $IcingaCustomVariable -like '*_Int_Verbose$' -Or $IcingaCustomVariable -like '*_Object_Verbose$' ) {
$IcingaCustomVariable = [ string ] :: Format ( '${0}_Int_Verbose$' , $PluginNameSpace ) ;
2019-10-29 04:08:44 -04:00
}
2019-09-16 10:31:15 -04:00
2019-10-29 04:08:44 -04:00
# Add arguments to a given command
2020-02-03 11:28:31 -05:00
if ( $parameter . type . name -eq 'SwitchParameter' ) {
2019-10-29 04:08:44 -04:00
$Basket . Command [ $Data . Name ] . arguments . Add (
[ string ] :: Format ( '-{0}' , $parameter . Name ) , @ {
2020-08-04 09:13:04 -04:00
'set_if' = $IcingaCustomVariable ;
2019-10-29 04:08:44 -04:00
'set_if_format' = 'string' ;
2020-08-04 09:13:04 -04:00
'order' = $Order ;
2019-10-29 04:08:44 -04:00
}
) ;
2019-09-16 09:33:57 -04:00
2019-10-29 04:08:44 -04:00
$Basket . Command [ $Data . Name ] . vars . Add ( $parameter . Name , $FALSE ) ;
2020-02-03 11:28:31 -05:00
} elseif ( $parameter . type . name -eq 'Array' ) {
2020-08-04 08:48:32 -04:00
# Conditional whether type of parameter is array
2019-10-29 04:08:44 -04:00
$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 " ,
'{' ,
'}'
) ;
2019-09-13 05:44:37 -04:00
}
2019-10-29 04:08:44 -04:00
'order' = $Order ;
2019-09-13 05:44:37 -04:00
}
2019-10-29 04:08:44 -04:00
) ;
} else {
# Default to Object
$Basket . Command [ $Data . Name ] . arguments . Add (
[ string ] :: Format ( '-{0}' , $parameter . Name ) , @ {
'value' = $IcingaCustomVariable ;
'order' = $Order ;
}
) ;
}
2019-09-13 05:44:37 -04:00
2019-10-29 04:08:44 -04:00
# Determine wether a parameter is required based on given syntax-information
if ( $parameter . required -eq $TRUE ) {
$Required = 'y' ;
} else {
$Required = 'n' ;
}
2019-09-13 05:44:37 -04:00
2019-10-30 13:19:08 -04:00
$IcingaCustomVariable = [ string ] :: Format ( '{0}_{1}_{2}' , $PluginNameSpace , ( Get-Culture ) . TextInfo . ToTitleCase ( $parameter . type . name ) , $parameter . Name ) ;
2019-10-29 04:08:44 -04:00
# Todo: Should we improve this? Actually the handling would be identical, we just need to assign
# the proper field for this
2019-10-30 13:19:08 -04:00
if ( $IcingaCustomVariable -like '*_Int32_Verbose' -Or $IcingaCustomVariable -like '*_Int_Verbose' -Or $IcingaCustomVariable -like '*_Object_Verbose' ) {
$IcingaCustomVariable = [ string ] :: Format ( '{0}_Int_Verbose' , $PluginNameSpace ) ;
2019-10-29 04:08:44 -04:00
}
2019-09-16 10:31:15 -04:00
2019-10-29 04:08:44 -04:00
[ bool ] $ArgumentKnown = $FALSE ;
2019-09-16 10:31:15 -04:00
2019-10-29 04:08:44 -04:00
foreach ( $argument in $Basket . Datafield . Keys ) {
if ( $Basket . Datafield [ $argument ] . varname -eq $IcingaCustomVariable ) {
$ArgumentKnown = $TRUE ;
break ;
2019-09-16 10:31:15 -04:00
}
2019-10-29 04:08:44 -04:00
}
2019-09-16 10:31:15 -04:00
2019-10-29 04:08:44 -04:00
if ( $ArgumentKnown ) {
continue ;
}
2019-10-30 13:19:08 -04:00
$DataListName = [ string ] :: Format ( '{0} {1}' , $PluginNameSpace , $parameter . Name ) ;
2019-10-29 04:08:44 -04:00
2019-10-30 13:19:08 -04:00
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' ;
2019-10-29 04:08:44 -04:00
} elseif ( $parameter . type . name -eq 'Object' ) {
2019-10-30 13:19:08 -04:00
$IcingaDataType = 'String' ;
2019-10-29 04:08:44 -04:00
} elseif ( $parameter . type . name -eq 'Array' ) {
2019-10-30 13:19:08 -04:00
$IcingaDataType = 'Array' ;
} elseif ( $parameter . type . name -eq 'Int' -Or $parameter . type . name -eq 'Int32' ) {
$IcingaDataType = 'Number' ;
2019-10-29 04:08:44 -04:00
} else {
2019-10-30 13:19:08 -04:00
$IcingaDataType = 'String' ;
2019-10-29 04:08:44 -04:00
}
2019-09-13 05:44:37 -04:00
2019-10-29 04:08:44 -04:00
$IcingaDataType = [ string ] :: Format ( 'Icinga\Module\Director\DataType\DataType{0}' , $IcingaDataType )
2019-10-30 13:19:08 -04:00
2019-10-29 04:08:44 -04:00
if ( $Basket . Datafield . Values . varname -ne $IcingaCustomVariable ) {
$Basket . Datafield . Add (
[ string ] $FieldID , @ {
2020-08-04 09:13:04 -04:00
'varname' = $IcingaCustomVariable ;
'caption' = $parameter . Name ;
2019-10-29 04:08:44 -04:00
'description' = $parameter . Description . Text ;
2020-08-04 09:13:04 -04:00
'datatype' = $IcingaDataType ;
'format' = $NULL ;
'originalId' = [ string ] $FieldID ;
2019-10-29 04:08:44 -04:00
}
) ;
2019-09-13 05:44:37 -04:00
2019-10-30 13:19:08 -04:00
if ( $IsDataList ) {
2019-10-29 04:08:44 -04:00
$Basket . Datafield [ [string ] $FieldID ] . Add (
'settings' , @ {
2020-08-04 09:13:04 -04:00
'datalist' = $DataListName ;
2020-02-13 08:16:42 -05:00
'data_type' = 'string' ;
2020-08-04 09:13:04 -04:00
'behavior' = 'strict' ;
2019-09-13 05:44:37 -04:00
}
) ;
2019-10-29 04:08:44 -04:00
} else {
$Basket . Datafield [ [string ] $FieldID ] . Add (
'settings' , @ {
'visbility' = 'visible' ;
2019-09-13 05:44:37 -04:00
}
) ;
}
2019-10-29 04:08:44 -04:00
# Increment FieldID, so unique datafields are added.
[ int ] $FieldID = [ int ] $FieldID + 1 ;
2019-09-13 05:44:37 -04:00
}
2019-09-16 09:33:57 -04:00
# Increment FieldNumeration, so unique fields for a given command are added.
2019-09-13 05:44:37 -04:00
[ int ] $FieldNumeration = [ int ] $FieldNumeration + 1 ;
}
}
foreach ( $check in $CheckName ) {
[ int ] $FieldNumeration = 0 ;
2019-10-30 13:19:08 -04:00
$Data = ( Get-Help $check )
$PluginNameSpace = $Data . Name . Replace ( 'Invoke-' , '' ) ;
2019-09-16 09:33:57 -04:00
2019-09-25 13:30:02 -04:00
foreach ( $parameter in $Data . parameters . parameter ) {
2019-10-30 13:19:08 -04:00
$IcingaCustomVariable = [ string ] :: Format ( '{0}_{1}_{2}' , $PluginNameSpace , ( Get-Culture ) . TextInfo . ToTitleCase ( $parameter . type . name ) , $parameter . Name ) ;
2019-09-13 05:44:37 -04:00
2019-09-16 09:33:57 -04:00
# Todo: Should we improve this? Actually the handling would be identical, we just need to assign
# the proper field for this
2019-10-30 13:19:08 -04:00
if ( $IcingaCustomVariable -like '*_Int32_Verbose' -Or $IcingaCustomVariable -like '*_Int_Verbose' -Or $IcingaCustomVariable -like '*_Object_Verbose' ) {
$IcingaCustomVariable = [ string ] :: Format ( '{0}_Int_Verbose' , $PluginNameSpace ) ;
2019-09-16 09:33:57 -04:00
}
2019-09-13 05:44:37 -04:00
2019-09-16 09:33:57 -04:00
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 ;
} ;
2019-09-13 05:44:37 -04:00
}
}
}
}
# 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 ;
2019-10-30 13:19:08 -04:00
# 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 ) {
2020-08-03 11:50:19 -04:00
New-Item -Path $OutDirectory -ItemType File -Force | Out-Null ;
2019-09-13 05:44:37 -04:00
}
2019-10-30 13:19:08 -04:00
if ( ( Test-Path ( $OutDirectory ) ) -eq $false ) {
2019-09-13 05:44:37 -04:00
throw 'Failed to create specified directory. Please try again or use a different target location.' ;
}
2020-08-04 08:48:32 -04:00
2019-10-30 13:19:08 -04:00
Set-Content -Path $OutDirectory -Value $output ;
2019-09-13 05:44:37 -04:00
# Output-Text
2020-05-13 10:53:15 -04:00
Write-IcingaConsoleNotice " The following commands have been exported: "
2019-09-13 05:44:37 -04:00
foreach ( $check in $CheckName ) {
2020-05-13 10:53:15 -04:00
Write-IcingaConsoleNotice " - ' $check ' " ;
2019-09-13 05:44:37 -04:00
}
2020-05-13 10:53:15 -04:00
Write-IcingaConsoleNotice " JSON export created in ' ${OutDirectory} ' "
2020-08-06 12:40:38 -04:00
Write-IcingaConsoleWarning 'By using this generated check command configuration you will require the Icinga PowerShell Framework 1.2.0 or later to be installed on ALL monitored machines!' ;
2019-09-13 05:44:37 -04:00
return ;
}
2020-05-13 10:53:15 -04:00
Write-IcingaConsoleNotice " Check Command JSON for the following commands: "
2019-09-13 05:44:37 -04:00
foreach ( $check in $CheckName ) {
2020-05-13 10:53:15 -04:00
Write-IcingaConsoleNotice " - ' $check ' "
2019-09-13 05:44:37 -04:00
}
2020-08-06 12:40:38 -04:00
Write-IcingaConsoleWarning 'By using this generated check command configuration you will require the Icinga PowerShell Framework 1.2.0 or later to be installed on ALL monitored machines!' ;
2020-05-13 10:53:15 -04:00
Write-IcingaConsoleNotice '############################################################' ;
2019-09-13 05:44:37 -04:00
return $output ;
}
2019-10-30 13:19:08 -04:00
function Add-PowerShellDataList ( )
{
param (
$Name ,
$Basket ,
$Arguments
) ;
$Basket . DataList . Add (
$Name , @ {
'list_name' = $Name ;
'owner' = $env:username ;
'originalId' = '2' ;
'entries' = @ ( ) ;
}
) ;
foreach ( $entry in $Arguments ) {
2020-08-12 04:38:07 -04:00
if ( [ string ] :: IsNullOrEmpty ( $entry ) ) {
Write-IcingaConsoleWarning `
-Message 'The plugin argument "{0}" contains the illegal ValidateSet $null which will not be rendered. Please remove it from the arguments list of "{1}"' `
-Objects $Name , $Arguments ;
continue ;
}
2019-10-30 13:19:08 -04:00
$Basket . DataList [ $Name ] [ 'entries' ] + = @ {
'entry_name' = $entry ;
'entry_value' = $entry ;
'format' = 'string' ;
'allowed_roles' = $NULL ;
} ;
}
}