2018-11-06 11:14:49 -05:00
<#
. Synopsis
2022-01-14 16:18:59 -05:00
Icinga PowerShell Module - Powerful PowerShell Framework for monitoring Windows Systems
2018-11-06 11:14:49 -05:00
. DESCRIPTION
2019-10-31 12:24:30 -04:00
More Information on https : / / github . com / Icinga / icinga-powershell -framework
2018-11-06 11:14:49 -05:00
. EXAMPLE
2018-12-06 12:21:55 -05:00
Install-Icinga
2018-11-06 11:14:49 -05:00
. NOTES
#>
2019-07-22 06:41:07 -04:00
function Use-Icinga ( )
{
2021-04-23 06:55:05 -04:00
param (
2020-03-24 09:04:41 -04:00
[ switch ] $LibOnly = $FALSE ,
[ switch ] $Daemon = $FALSE ,
2021-02-16 10:10:00 -05:00
[ switch ] $DebugMode = $FALSE ,
[ switch ] $Minimal = $FALSE
2019-10-05 15:54:24 -04:00
) ;
2021-08-06 09:44:31 -04:00
if ( $null -ne $Global:Icinga -And $Global:Icinga . ContainsKey ( 'RebuildCache' ) -And $Global:Icinga . RebuildCache ) {
2021-08-17 03:41:04 -04:00
# On some systems, this call will re-build the cache
Import-Module ( Join-Path -Path ( Get-IcingaForWindowsRootPath ) -ChildPath 'icinga-powershell-framework' ) -Global -Force ;
# The second run would then actually import the new module. Only happens on some systems, but with this we fix
# possible exceptions
2021-08-17 03:22:05 -04:00
Import-Module ( Join-Path -Path ( Get-IcingaForWindowsRootPath ) -ChildPath 'icinga-powershell-framework' ) -Global -Force ;
2021-08-06 09:44:31 -04:00
}
2022-01-14 13:57:43 -05:00
# Only apply migrations if we directly call "Use-Icinga" without any other argument
if ( $LibOnly -eq $FALSE -And $Daemon -eq $FALSE -and $Minimal -eq $FALSE ) {
Invoke-IcingaForWindowsMigration ;
}
2021-02-16 10:10:00 -05:00
Disable-IcingaProgressPreference ;
2021-12-09 11:42:06 -05:00
New-IcingaEnvironmentVariable ;
2021-02-16 10:10:00 -05:00
if ( $Minimal ) {
2021-12-09 11:42:06 -05:00
$Global:Icinga . Protected . Minimal = $TRUE ;
2021-02-16 10:10:00 -05:00
}
2019-11-03 05:59:08 -05:00
# Ensure we autoload the Icinga Plugin collection, provided by the external
# module 'icinga-powershell-plugins'
if ( Get-Command 'Use-IcingaPlugins' -ErrorAction SilentlyContinue ) {
Use-IcingaPlugins ;
}
2021-12-09 11:42:06 -05:00
if ( $Daemon ) {
$Global:Icinga . Protected . RunAsDaemon = $TRUE ;
}
if ( $DebugMode ) {
$Global:Icinga . Protected . DebugMode = $TRUE ;
2019-10-05 15:54:24 -04:00
}
2020-03-27 11:39:47 -04:00
# Enable DebugMode in case it is enabled in our config
if ( Get-IcingaFrameworkDebugMode ) {
Enable-IcingaFrameworkDebugMode ;
}
$EventLogMessages = Invoke-IcingaNamespaceCmdlets -Command 'Register-IcingaEventLogMessages*' ;
foreach ( $entry in $EventLogMessages . Values ) {
foreach ( $event in $entry . Keys ) {
2021-12-09 11:42:06 -05:00
if ( $LibOnly -eq $FALSE -And $Daemon -eq $FALSE ) {
2022-01-14 13:57:43 -05:00
Register-IcingaEventLog -LogName $event ;
}
2020-03-27 11:39:47 -04:00
Add-IcingaHashtableItem -Hashtable $global:IcingaEventLogEnums `
2020-08-04 06:39:25 -04:00
-Key $event `
-Value $entry [ $event ] | Out-Null ;
2020-03-27 11:39:47 -04:00
}
}
2020-08-06 13:06:59 -04:00
2021-12-09 11:42:06 -05:00
if ( $LibOnly -eq $FALSE -And $Daemon -eq $FALSE ) {
2020-08-06 13:06:59 -04:00
Register-IcingaEventLog ;
}
2019-07-22 06:41:07 -04:00
}
2020-11-04 03:20:19 -05:00
function Get-IcingaFrameworkCodeCacheFile ( )
{
return ( Join-Path -Path ( Get-IcingaCacheDir ) -ChildPath 'framework_cache.psm1' ) ;
}
2019-07-18 11:52:21 -04:00
function Import-IcingaLib ( )
{
2021-08-07 05:04:05 -04:00
# Do nothing, just leave it here as compatibility layer until we
# cleaned every other repository
2019-07-18 11:52:21 -04:00
}
2021-08-07 05:04:05 -04:00
function Write-IcingaFrameworkCodeCache ( )
2018-11-06 11:14:49 -05:00
{
2021-08-07 05:04:05 -04:00
[ string ] $CacheFile = Get-IcingaFrameworkCodeCacheFile ;
[ string ] $directory = Join-Path -Path $PSScriptRoot -ChildPath 'lib\' ;
[ string ] $CacheContent = '' ;
2018-11-06 11:14:49 -05:00
2021-08-07 05:04:05 -04:00
# Load modules from directory
Get-ChildItem -Path $directory -Recurse -Filter '*.psm1' |
ForEach-Object {
$CacheContent + = ( Get-Content -Path $_ . FullName -Raw ) ;
$CacheContent + = " `r `n " ;
2019-10-28 12:03:19 -04:00
}
2018-11-06 11:14:49 -05:00
2021-08-21 06:28:42 -04:00
$CacheContent + = " Export-ModuleMember -Function @( '*' ) -Alias @( '*' ) -Variable @( '*' ) " ;
2021-08-07 05:04:05 -04:00
Set-Content -Path $CacheFile -Value $CacheContent ;
2021-08-06 12:12:27 -04:00
Remove-IcingaFrameworkDependencyFile ;
2018-11-06 11:14:49 -05:00
}
2022-01-14 16:18:59 -05:00
function Publish-IcingaEventLogDocumentation ( )
2020-03-28 13:58:14 -04:00
{
param (
[ string ] $Namespace ,
[ string ] $OutFile
) ;
[ string ] $DocContent = [ string ] :: Format (
2022-01-14 16:18:59 -05:00
'# {0} EventLog Documentation' ,
2020-03-28 13:58:14 -04:00
$Namespace
) ;
$DocContent + = New-IcingaNewLine ;
$DocContent + = New-IcingaNewLine ;
2022-01-14 16:18:59 -05:00
$DocContent + = " Below you will find a list of EventId's which are exported by this module. The short and detailed message are both written directly into the EventLog. This documentation shall simply provide a summary of available EventId's " ;
2020-03-28 13:58:14 -04:00
$SortedArray = $IcingaEventLogEnums [ $Namespace ] . Keys . GetEnumerator ( ) | Sort-Object ;
foreach ( $entry in $SortedArray ) {
$entry = $IcingaEventLogEnums [ $Namespace ] [ $entry ] ;
$DocContent = [ string ] :: Format (
'{0}{2}{2}## Event Id {1}{2}{2}| Category | Short Message | Detailed Message |{2}| --- | --- | --- |{2}| {3} | {4} | {5} |' ,
$DocContent ,
$entry . EventId ,
( New-IcingaNewLine ) ,
$entry . EntryType ,
$entry . Message ,
$entry . Details
) ;
}
if ( [ string ] :: IsNullOrEmpty ( $OutFile ) ) {
2020-08-04 06:39:25 -04:00
Write-Output $DocContent ;
2020-03-28 13:58:14 -04:00
} else {
2021-08-21 06:28:42 -04:00
Write-IcingaFileSecure -File $OutFile -Value $DocContent ;
2020-03-28 13:58:14 -04:00
}
}
2019-10-28 12:03:19 -04:00
function Get-IcingaPluginDir ( )
2018-11-06 11:14:49 -05:00
{
2019-10-28 12:03:19 -04:00
return ( Join-Path -Path $PSScriptRoot -ChildPath 'lib\plugins\' ) ;
2018-11-06 11:14:49 -05:00
}
2019-10-28 12:03:19 -04:00
function Get-IcingaCustomPluginDir ( )
2018-11-06 11:14:49 -05:00
{
2019-10-28 12:03:19 -04:00
return ( Join-Path -Path $PSScriptRoot -ChildPath 'custom\plugins\' ) ;
2018-11-06 11:14:49 -05:00
}
2019-10-28 12:03:19 -04:00
function Get-IcingaCacheDir ( )
2018-11-06 11:14:49 -05:00
{
2019-10-28 12:03:19 -04:00
return ( Join-Path -Path $PSScriptRoot -ChildPath 'cache' ) ;
2018-11-06 11:14:49 -05:00
}
2019-10-28 12:03:19 -04:00
function Get-IcingaPowerShellConfigDir ( )
2018-11-06 11:14:49 -05:00
{
2019-10-28 12:03:19 -04:00
return ( Join-Path -Path $PSScriptRoot -ChildPath 'config' ) ;
2018-11-06 11:14:49 -05:00
}
2019-10-31 08:43:20 -04:00
2019-11-02 07:12:26 -04:00
function Get-IcingaFrameworkRootPath ( )
{
[ string ] $Path = $PSScriptRoot ;
2021-05-31 11:02:46 -04:00
return $PSScriptRoot ;
}
function Get-IcingaForWindowsRootPath ( )
{
[ string ] $Path = $PSScriptRoot ;
[ int ] $Index = $Path . LastIndexOf ( 'icinga-powershell-framework' ) ;
2019-11-02 07:12:26 -04:00
$Path = $Path . Substring ( 0 , $Index ) ;
2021-05-31 11:02:46 -04:00
2019-11-02 07:12:26 -04:00
return $Path ;
}
2019-10-31 08:43:20 -04:00
function Get-IcingaPowerShellModuleFile ( )
{
2021-08-20 12:13:25 -04:00
return ( Join-Path -Path $PSScriptRoot -ChildPath 'icinga-powershell-framework.psd1' ) ;
2019-10-31 08:43:20 -04:00
}
2020-08-03 05:15:15 -04:00
function Invoke-IcingaCommand ( )
{
[ CmdletBinding ( ) ]
param (
2020-08-03 05:46:56 -04:00
$ScriptBlock ,
2021-08-07 08:30:01 -04:00
[ switch ] $SkipHeader = $FALSE ,
[ switch ] $Manage = $FALSE ,
[ switch ] $RebuildCache = $FALSE ,
[ array ] $ArgumentList = @ ( )
2020-08-03 05:15:15 -04:00
) ;
2020-08-03 06:29:28 -04:00
Import-LocalizedData `
2021-05-31 11:02:46 -04:00
-BaseDirectory ( Get-IcingaFrameworkRootPath ) `
2020-08-03 06:29:28 -04:00
-FileName 'icinga-powershell-framework.psd1' `
-BindingVariable IcingaFrameworkData ;
# Print a header informing our user that loaded the Icinga Framework with a specific
# version. We can also skip the header by using $SKipHeader
2021-02-19 04:09:42 -05:00
if ( [ string ] :: IsNullOrEmpty ( $ScriptBlock ) -And $SkipHeader -eq $FALSE -And $Manage -eq $FALSE ) {
[ array ] $Headers = @ (
'Icinga for Windows $FrameworkVersion' ,
'Copyright $Copyright' ,
'User environment $UserDomain\$Username'
) ;
2021-08-06 09:44:31 -04:00
if ( $null -eq ( Get-Command -Name 'Write-IcingaConsoleHeader' -ErrorAction SilentlyContinue ) ) {
Use-Icinga ;
2020-11-04 03:20:19 -05:00
}
2021-02-19 04:09:42 -05:00
Write-IcingaConsoleHeader -HeaderLines $Headers ;
2020-08-03 06:29:28 -04:00
}
2021-08-07 08:30:01 -04:00
if ( $RebuildCache ) {
Write-IcingaFrameworkCodeCache ;
}
2022-01-20 12:15:08 -05:00
if ( $Manage -And $null -ne $psISE ) {
Use-Icinga ;
Write-IcingaConsoleError -Message 'Icinga for Windows was loaded, but the Icinga Management Console is not available within the PowerShell ISE context. Please start a regular PowerShell to use it.' ;
return ;
}
if ( $null -ne $psISE ) {
Write-IcingaConsoleWarning -Message 'Icinga for Windows was successfully loaded, but the current PowerShell ISE environment is not fully supported. For advanced and production tasks, please use Icinga for Windows inside a regular PowerShell environment.' ;
return ;
}
2020-08-03 05:15:15 -04:00
powershell . exe -NoExit -Command {
2020-11-19 07:41:23 -05:00
$Script = $args [ 0 ] ;
$RootPath = $args [ 1 ] ;
$Version = $args [ 2 ] ;
2021-02-19 04:09:42 -05:00
$Manage = $args [ 3 ] ;
$IcingaShellArgs = $args [ 4 ] ;
2020-08-03 05:46:56 -04:00
# Load our Icinga Framework
2020-08-03 05:15:15 -04:00
Use-Icinga ;
2020-08-28 09:24:48 -04:00
$Host . UI . RawUI . WindowTitle = ( [ string ] :: Format ( 'Icinga for Windows {0}' , $Version ) ) ;
2020-08-03 05:46:56 -04:00
# Set the location to the Icinga Framework module folder
Set-Location $RootPath ;
2021-02-19 04:09:42 -05:00
if ( $Manage ) {
Install-Icinga ;
exit $LASTEXITCODE ;
}
2020-08-03 05:46:56 -04:00
# If we added a block to execute, do it right here and exit the shell
# with the last exit code of the command
2020-08-03 05:15:15 -04:00
if ( [ string ] :: IsNullOrEmpty ( $Script ) -eq $FALSE ) {
Invoke-Command -ScriptBlock ( [ Scriptblock ] :: Create ( $Script ) ) ;
exit $LASTEXITCODE ;
}
2020-08-03 05:46:56 -04:00
2020-08-03 05:15:15 -04:00
# Set our "path" to something different so we know that we loaded the Framework
function prompt {
Write-Host -Object " icinga " -NoNewline ;
return " > "
}
2021-02-19 04:09:42 -05:00
} -Args $ScriptBlock , $PSScriptRoot , $IcingaFrameworkData . PrivateData . Version , ( [ bool ] $Manage ) , $ArgumentList ;
2020-08-03 05:15:15 -04:00
}
2020-10-30 10:06:26 -04:00
function Start-IcingaShellAsUser ( )
{
param (
[ string ] $User = ''
) ;
Start-Process `
-WorkingDirectory $PSHOME `
-FilePath 'powershell.exe' `
-Verb RunAs `
-ArgumentList (
[ string ] :: Format (
" -Command `" Start-Process -FilePath `" powershell.exe `" -WorkingDirectory `" {0} `" -Credential (Get-Credential -UserName '{1}' -Message 'Please enter your credentials to open an Icinga Shell with') -ArgumentList icinga `" " ,
$PSHOME ,
$User
)
) ;
}
2020-08-03 05:15:15 -04:00
Set-Alias icinga Invoke-IcingaCommand -Description " Execute Icinga Framework commands in a new PowerShell instance for testing or quick access to data " ;
2021-08-20 06:37:34 -04:00
Export-ModuleMember -Alias * -Function * -Variable * ;