2019-07-22 07:17:07 -04:00
<#
2020-08-20 08:16:16 -04:00
. SYNOPSIS
Creates counter objects and sub-instances from a given Performance Counter
Will return either a New-IcingaPerformanceCounterObject or New-IcingaPerformanceCounterResult
2022-01-14 16:18:59 -05:00
which both contain the same members , allowing for dynamically use of objects
2020-08-20 08:16:16 -04:00
. DESCRIPTION
Creates counter objects and sub-instances from a given Performance Counter
Will return either a New-IcingaPerformanceCounterObject or New-IcingaPerformanceCounterResult
2022-01-14 16:18:59 -05:00
which both contain the same members , allowing for dynamically use of objects
2020-08-20 08:16:16 -04:00
. FUNCTIONALITY
Creates counter objects and sub-instances from a given Performance Counter
Will return either a New-IcingaPerformanceCounterObject or New-IcingaPerformanceCounterResult
2022-01-14 16:18:59 -05:00
which both contain the same members , allowing for dynamically use of objects
2020-08-20 08:16:16 -04:00
. EXAMPLE
PS > New-IcingaPerformanceCounter -Counter '\Processor(*)\% processor time' ;
FullName Counters
- - - - - - - - - - - - - - - -
\ Processor ( * ) \ % processor time { @ { FullName = \ Processor ( 2 ) \ % processor time ; Category = Processor ; Instance = 2 ; Counter = % . . .
. EXAMPLE
PS > New-IcingaPerformanceCounter -Counter '\Processor(*)\% processor time' -SkipWait ;
. PARAMETER Counter
The path to the Performance Counter to fetch data for
. PARAMETER SkipWait
Set this if no sleep is intended for initialising the counter . This can be useful
if multiple counters are fetched during one call with this function if the sleep
is done afterwards manually . A sleep is set to 500ms to ensure counter data is
valid and contains an offset from previous / current values
. INPUTS
System . String
. LINK
https : / / github . com / Icinga / icinga-powershell -framework
#>
2020-08-04 08:48:32 -04:00
function New-IcingaPerformanceCounter ( )
{
param (
[ string ] $Counter = '' ,
[ boolean ] $SkipWait = $FALSE
) ;
# Simply use the counter name, like
# \Paging File(_total)\% Usage
if ( [ string ] :: IsNullOrEmpty ( $Counter ) -eq $TRUE ) {
return ( New-IcingaPerformanceCounterNullObject -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 ( New-IcingaPerformanceCounterNullObject -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 ] ;
2022-01-14 16:18:59 -05:00
# Now as we know how the counter path is constructed and has been split into
2020-08-04 08:48:32 -04:00
# the different values, we need to know how to handle the instances of the counter
2022-01-14 16:18:59 -05:00
# If we specify a instance with (*) we want the module to automatically fetch all
2020-08-04 08:48:32 -04:00
# instances for this counter. This will result in an New-IcingaPerformanceCounterResult
# 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
2020-08-07 09:17:19 -04:00
$CachedCounter = Get-IcingaPerformanceCounterCacheItem -Counter $Counter ;
if ( $null -ne $CachedCounter ) {
return ( New-IcingaPerformanceCounterResult -FullName $Counter -PerformanceCounters $CachedCounter ) ;
}
2020-08-04 08:48:32 -04:00
# 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 {
2022-01-14 16:18:59 -05:00
[ array ] $AllCountersInstances = @ ( ) ;
2020-08-04 08:48:32 -04:00
$CounterInstances = New-Object System . Diagnostics . PerformanceCounterCategory ( $UseCounterCategory ) ;
foreach ( $instance in $CounterInstances . GetInstanceNames ( ) ) {
[ string ] $NewCounterName = $Counter . Replace ( '*' , $instance ) ;
$NewCounter = New-IcingaPerformanceCounterObject -FullName $NewCounterName -Category $UseCounterCategory -Counter $UseCounterName -Instance $instance -SkipWait $TRUE ;
2022-01-14 16:18:59 -05:00
$AllCountersInstances + = $NewCounter ;
2020-08-04 08:48:32 -04:00
}
} catch {
2019-09-14 10:12:24 -04:00
# 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 ) ) ) ;
2020-08-04 08:48:32 -04:00
}
2019-07-22 08:35:35 -04:00
2020-08-04 08:48:32 -04:00
# If we load multiple instances, we should add a global wait here instead of a wait for each single instance
2022-01-14 16:18:59 -05:00
# This will speed up CPU loading for example with plenty of cores available
2020-08-04 08:48:32 -04:00
if ( $SkipWait -eq $FALSE ) {
2019-07-22 08:35:35 -04:00
Start-Sleep -Milliseconds 500 ;
2020-08-04 08:48:32 -04:00
}
# Add the parent counter including the array of Performance Counters to our
# caching mechanism and return the New-IcingaPerformanceCounterResult object for usage
# within the monitoring modules
2022-01-14 16:18:59 -05:00
Add-IcingaPerformanceCounterCache -Counter $Counter -Instances $AllCountersInstances ;
return ( New-IcingaPerformanceCounterResult -FullName $Counter -PerformanceCounters $AllCountersInstances ) ;
2020-08-04 08:48:32 -04:00
} else {
# This part will handle the counters without any instances as well as
2022-01-14 16:18:59 -05:00
# specifically assigned instances, like (_Total) CPU usage.
2020-08-04 08:48:32 -04:00
# In case we already have the counter within our cache, return the
# cached informations
2020-08-07 09:17:19 -04:00
$CachedCounter = Get-IcingaPerformanceCounterCacheItem -Counter $Counter ;
if ( $null -ne $CachedCounter ) {
return $CachedCounter ;
}
2020-08-04 08:48:32 -04:00
# If the cache is not present yet, create the Performance Counter object,
# and add it to our cache
$NewCounter = New-IcingaPerformanceCounterObject -FullName $Counter -Category $UseCounterCategory -Counter $UseCounterName -Instance $UseCounterInstance -SkipWait $SkipWait ;
2020-08-07 09:17:19 -04:00
Add-IcingaPerformanceCounterCache -Counter $Counter -Instances $NewCounter ;
2020-08-04 08:48:32 -04:00
}
# This function will always return non-instance counters or
2022-01-14 16:18:59 -05:00
# specifically defined instance counters. Performance Counter Arrays
2020-08-04 08:48:32 -04:00
# are returned within their function. This is just to ensure that the
# function looks finished from developer point of view
2020-08-07 09:17:19 -04:00
return ( Get-IcingaPerformanceCounterCacheItem -Counter $Counter ) ;
2020-08-04 08:48:32 -04:00
}