enh wsus by using json data format

This commit is contained in:
Colin Gagnaire 2019-03-21 18:16:22 +01:00
parent 90a2427c13
commit 63789d362a
9 changed files with 246 additions and 83 deletions

View File

@ -24,6 +24,7 @@ use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use JSON::XS;
use centreon::common::powershell::wsus::computersstatus;
sub set_counters {
@ -143,16 +144,16 @@ sub manage_selection {
$self->{output}->exit();
}
#[ComputerTargetsNeedingUpdatesCount = 0][ComputerTargetsWithUpdateErrorsCount = 0][ComputersUpToDateCount = 0][ComputersNotContactedSinceCount = 0][UnassignedComputersCount = 0]
if ($stdout =~ /^\[ComputerTargetsNeedingUpdatesCount\s*=\s*(\d+)\s*\]\[ComputerTargetsWithUpdateErrorsCount\s*=\s*(\d+)\s*\]\[ComputersUpToDateCount\s*=\s*(\d+)\s*\]\[ComputersNotContactedSinceCount\s*=\s*(\d+)\s*\]\[UnassignedComputersCount\s*=\s*(\d+)\s*\]/i) {
$self->{global} = {
ComputerTargetsNeedingUpdatesCount => $1,
ComputerTargetsWithUpdateErrorsCount => $2,
ComputersUpToDateCount => $3,
ComputersNotContactedSinceCount => $4,
UnassignedComputersCount => $5,
};
my $decoded;
eval {
$decoded = JSON::XS->new->utf8->decode($stdout);
};
if ($@) {
$self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@");
$self->{output}->option_exit();
}
$self->{global} = { %$decoded };
}
1;

View File

@ -24,6 +24,7 @@ use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use JSON::XS;
use centreon::common::powershell::wsus::serverstatistics;
sub set_counters {
@ -162,19 +163,16 @@ sub manage_selection {
$self->{output}->exit();
}
#[ComputerTargetCount = 0 ][CustomComputerTargetGroupCount = 1 ][UpdateCount = 109 ][ApprovedUpdateCount = 0 ][DeclinedUpdateCount = 0 ][NotApprovedUpdateCount = 109 ][UpdatesWithStaleUpdateApprovalsCount = 0 ][ExpiredUpdateCount = 0 ]
if ($stdout =~ /^\[ComputerTargetCount\s*=\s*(\d+)\s*\]\[CustomComputerTargetGroupCount\s*=\s*(\d+)\s*\]\[UpdateCount\s*=\s*(\d+)\s*\]\[ApprovedUpdateCount\s*=\s*(\d+)\s*\]\[DeclinedUpdateCount\s*=\s*(\d+)\s*\]\[NotApprovedUpdateCount\s*=\s*(\d+)\s*\]\[UpdatesWithStaleUpdateApprovalsCount\s*=\s*(\d+)\s*\]\[ExpiredUpdateCount\s*=\s*(\d+)\s*\]/i) {
$self->{global} = {
ComputerTargetCount => $1,
CustomComputerTargetGroupCount => $2,
UpdateCount => $3,
ApprovedUpdateCount => $4,
DeclinedUpdateCount => $5,
NotApprovedUpdateCount => $6,
UpdatesWithStaleUpdateApprovalsCount => $7,
ExpiredUpdateCount => $8,
};
my $decoded;
eval {
$decoded = JSON::XS->new->utf8->decode($stdout);
};
if ($@) {
$self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@");
$self->{output}->option_exit();
}
$self->{global} = { %$decoded };
}
1;

View File

@ -24,6 +24,7 @@ use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use JSON::XS;
use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold);
use centreon::common::powershell::wsus::synchronisationstatus;
use DateTime;
@ -130,11 +131,12 @@ sub custom_duration_calc {
my $start_time = $options{new_datas}->{$self->{instance} . '_LastSynchronizationStartTime'};
my $end_time = $options{new_datas}->{$self->{instance} . '_LastSynchronizationEndTime'};
# 2019-03-21T13:00:13
my $tz = centreon::plugins::misc::set_timezone(name => $self->{option_results}->{timezone});
$start_time =~ /^(\d+)\/(\d+)\/(\d+)\s+(\d+)[:\/](\d+)[:\/](\d+).*$/;
my $start_time_dt = DateTime->new(year => $3, month => $1, day => $2, hour => $4, minute => $5, second => $6, %$tz);
$end_time =~ /^(\d+)\/(\d+)\/(\d+)\s+(\d+)[:\/](\d+)[:\/](\d+).*$/;
my $end_time_dt = DateTime->new(year => $3, month => $1, day => $2, hour => $4, minute => $5, second => $6, %$tz);
$start_time =~ /^(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)$/;
my $start_time_dt = DateTime->new(year => $1, month => $2, day => $3, hour => $4, minute => $5, second => $6, %$tz);
$end_time =~ /^(\d+)-(\d+)-(\d+)T(\d+):(\d+):(\d+)$/;
my $end_time_dt = DateTime->new(year => $1, month => $2, day => $3, hour => $4, minute => $5, second => $6, %$tz);
$self->{result_values}->{duration} = $end_time_dt->epoch - $start_time_dt->epoch;
return 0;
@ -258,19 +260,25 @@ sub manage_selection {
$self->{output}->exit();
}
#[SynchronizationStatus = NotProcessing][TotalItems = 0 ][ProcessedItems = 0 ][LastSynchronizationResult = Succeeded ][LastSynchronizationStartTime = 3/21/2019 8:48:50 AM ][LastSynchronizationEndTime = 3/21/2019 10:21:23 AM ]
if ($stdout =~ /^\[SynchronizationStatus\s*=\s*(\w+)\s*\]\[TotalItems\s*=\s*(\d+)\s*\]\[ProcessedItems\s*=\s*(\d+)\s*\]\[LastSynchronizationResult\s*=\s*(\w+)\s*\]\[LastSynchronizationStartTime\s*=\s*(.*)\s*\]\[LastSynchronizationEndTime\s*=\s*(.*)\s*\]/i) {
$self->{current} = {
SynchronizationStatus => $1,
TotalItems => $2,
ProcessedItems => $3,
};
$self->{last} = {
LastSynchronizationResult => $4,
LastSynchronizationStartTime => $5,
LastSynchronizationEndTime => $6,
};
my $decoded;
eval {
$decoded = JSON::XS->new->utf8->decode($stdout);
};
if ($@) {
$self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@");
$self->{output}->option_exit();
}
$self->{current} = {
SynchronizationStatus => $decoded->{SynchronizationStatus},
TotalItems => $decoded->{TotalItems},
ProcessedItems => $decoded->{ProcessedItems},
};
$self->{last} = {
LastSynchronizationResult => $decoded->{LastSynchronizationResult},
LastSynchronizationStartTime => $decoded->{LastSynchronizationStartTime},
LastSynchronizationEndTime => $decoded->{LastSynchronizationEndTime},
};
}
1;

View File

@ -24,6 +24,7 @@ use base qw(centreon::plugins::templates::counter);
use strict;
use warnings;
use JSON::XS;
use centreon::common::powershell::wsus::updatesstatus;
sub set_counters {
@ -141,16 +142,16 @@ sub manage_selection {
$self->{output}->exit();
}
#[UpdatesWithClientErrorsCount = 0 ][UpdatesWithServerErrorsCount = 0 ][UpdatesNeedingFilesCount = 0 ][UpdatesNeededByComputersCount = 0 ][UpdatesUpToDateCount = 0 ]
if ($stdout =~ /^\[UpdatesWithClientErrorsCount\s*=\s*(\d+)\s*\]\[UpdatesWithServerErrorsCount\s*=\s*(\d+)\s*\]\[UpdatesNeedingFilesCount\s*=\s*(\d+)\s*\]\[UpdatesNeededByComputersCount\s*=\s*(\d+)\s*\]\[UpdatesUpToDateCount\s*=\s*(\d+)\s*\]/i) {
$self->{global} = {
UpdatesWithClientErrorsCount => $1,
UpdatesWithServerErrorsCount => $2,
UpdatesNeedingFilesCount => $3,
UpdatesNeededByComputersCount => $4,
UpdatesUpToDateCount => $5,
};
my $decoded;
eval {
$decoded = JSON::XS->new->utf8->decode($stdout);
};
if ($@) {
$self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@");
$self->{output}->option_exit();
}
$self->{global} = { %$decoded };
}
1;

View File

@ -0,0 +1,123 @@
#
# Copyright 2019 Centreon (http://www.centreon.com/)
#
# Centreon is a full-fledged industry-strength solution that meets
# the needs in IT infrastructure and application monitoring for
# service performance.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
package centreon::common::powershell::functions;
use strict;
use warnings;
use centreon::plugins::misc;
sub escape_jsonstring {
my (%options) = @_;
my $ps = q{
function Escape-JSONString($str) {
if ($str -eq $null) {return ""}
$str = $str.ToString().Replace('"','\"').Replace('\','\\').Replace("`n",'\n').Replace("`r",'\r').Replace("`t",'\t')
return $str;
}
};
return $ps;
}
sub convert_to_json {
my (%options) = @_;
my $ps = q{
function ConvertTo-JSON-20($maxDepth = 4,$forceArray = $false) {
begin {
$data = @()
}
process{
$data += $_
}
end{
if ($data.length -eq 1 -and $forceArray -eq $false) {
$value = $data[0]
} else {
$value = $data
}
if ($value -eq $null) {
return "null"
}
$dataType = $value.GetType().Name
switch -regex ($dataType) {
'String' {
return "`"{0}`"" -f (Escape-JSONString $value )
}
'(System\.)?DateTime' {return "`"{0:yyyy-MM-dd}T{0:HH:mm:ss}`"" -f $value}
'Int32|Double' {return "$value"}
'Boolean' {return "$value".ToLower()}
'(System\.)?Object\[\]' { # array
if ($maxDepth -le 0){return "`"$value`""}
$jsonResult = ''
foreach($elem in $value){
#if ($elem -eq $null) {continue}
if ($jsonResult.Length -gt 0) {$jsonResult +=', '}
$jsonResult += ($elem | ConvertTo-JSON-20 -maxDepth ($maxDepth -1))
}
return "[" + $jsonResult + "]"
}
'(System\.)?Hashtable' { # hashtable
$jsonResult = ''
foreach($key in $value.Keys){
if ($jsonResult.Length -gt 0) {$jsonResult +=', '}
$jsonResult +=
@"
"{0}": {1}
"@ -f $key , ($value[$key] | ConvertTo-JSON-20 -maxDepth ($maxDepth -1) )
}
return "{" + $jsonResult + "}"
}
default { #object
if ($maxDepth -le 0){return "`"{0}`"" -f (Escape-JSONString $value)}
return "{" +
(($value | Get-Member -MemberType *property | % {
@"
"{0}": {1}
"@ -f $_.Name , ($value.($_.Name) | ConvertTo-JSON-20 -maxDepth ($maxDepth -1) )
}) -join ', ') + "}"
}
}
}
}
};
return $ps;
}
1;
__END__
=head1 DESCRIPTION
Powershell common functions.
=cut

View File

@ -22,6 +22,7 @@ package centreon::common::powershell::wsus::computersstatus;
use strict;
use warnings;
use centreon::common::powershell::functions;
sub get_powershell {
my (%options) = @_;
@ -32,9 +33,14 @@ sub get_powershell {
my $ps = '
$culture = new-object "System.Globalization.CultureInfo" "en-us"
[System.Threading.Thread]::CurrentThread.CurrentUICulture = $culture
';
$ps .= centreon::common::powershell::functions::escape_jsonstring(%options);
$ps .= centreon::common::powershell::functions::convert_to_json(%options);
$ps .= '
$wsusServer = "' . $options{wsus_server} . '"
$useSsl = ' . $options{secure_connection} . '
$useSsl = ' . $options{use_ssl} . '
$wsusPort = ' . $options{wsus_port} . '
$notUpdatedSince = ' . $options{not_updated_since} . '
@ -52,18 +58,22 @@ Try {
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($wsusServer, $useSsl, $wsusPort)
$wsusStatus = $wsusObject.GetStatus()
$notUpdatedSinceTimespan = new-object TimeSpan($notUpdatedSince, 0, 0, 0)
$computersNotContactedSinceCount = $wsus.GetComputersNotContactedSinceCount([DateTime]::UtcNow.Subtract($notUpdatedSinceTimespan))
$computersNotContactedSinceCount = $wsusObject.GetComputersNotContactedSinceCount([DateTime]::UtcNow.Subtract($notUpdatedSinceTimespan))
$computerTargetScope = new-object Microsoft.UpdateServices.Administration.ComputerTargetScope
$unassignedComputersCount = $wsus.GetComputerTargetGroup([Microsoft.UpdateServices.Administration.ComputerTargetGroupId]::UnassignedComputers).GetComputerTargets().Count
$status = $wsus.GetStatus()
Write-Host "[ComputerTargetsNeedingUpdatesCount = "$status.ComputerTargetsNeedingUpdatesCount"]" -NoNewline
Write-Host "[ComputerTargetsWithUpdateErrorsCount = "$status.ComputerTargetsWithUpdateErrorsCount"]" -NoNewline
Write-Host "[ComputersUpToDateCount = "$status.ComputersUpToDateCount"]" -NoNewline
Write-Host "[ComputersNotContactedSinceCount = "$computersNotContactedSinceCount"]" -NoNewline
Write-Host "[UnassignedComputersCount = "$unassignedComputersCount"]"
$unassignedComputersCount = $wsusObject.GetComputerTargetGroup([Microsoft.UpdateServices.Administration.ComputerTargetGroupId]::UnassignedComputers).GetComputerTargets().Count
$returnObject = New-Object -TypeName PSObject
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "ComputerTargetsNeedingUpdatesCount" -Value $wsusStatus.ComputerTargetsNeedingUpdatesCount
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "ComputerTargetsWithUpdateErrorsCount" -Value $wsusStatus.ComputerTargetsWithUpdateErrorsCount
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "ComputersUpToDateCount" -Value $wsusStatus.ComputersUpToDateCount
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "ComputersNotContactedSinceCount" -Value $computersNotContactedSinceCount
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "UnassignedComputersCount" -Value $unassignedComputersCount
$returnObject | ConvertTo-JSON-20
} Catch {
Write-Host $Error[0].Exception
exit 1

View File

@ -51,15 +51,19 @@ Try {
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($wsusServer, $useSsl, $wsusPort)
$status = $wsus.GetStatus()
Write-Host "[ComputerTargetCount = "$status.ComputerTargetCount"]" -NoNewline
Write-Host "[CustomComputerTargetGroupCount = "$status.CustomComputerTargetGroupCount"]" -NoNewline
Write-Host "[UpdateCount = "$status.UpdateCount"]" -NoNewline
Write-Host "[ApprovedUpdateCount = "$status.ApprovedUpdateCount"]" -NoNewline
Write-Host "[DeclinedUpdateCount = "$status.DeclinedUpdateCount"]" -NoNewline
Write-Host "[NotApprovedUpdateCount = "$status.NotApprovedUpdateCount"]" -NoNewline
Write-Host "[UpdatesWithStaleUpdateApprovalsCount = "$status.UpdatesWithStaleUpdateApprovalsCount"]" -NoNewline
Write-Host "[ExpiredUpdateCount = "$status.ExpiredUpdateCount"]"
$wsusStatus = $wsusObject.GetStatus()
$returnObject = New-Object -TypeName PSObject
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "ComputerTargetCount" -Value $wsusStatus.ComputerTargetCount
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "CustomComputerTargetGroupCount" -Value $wsusStatus.CustomComputerTargetGroupCount
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "UpdateCount" -Value $wsusStatus.UpdateCount
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "ApprovedUpdateCount" -Value $wsusStatus.ApprovedUpdateCount
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "DeclinedUpdateCount" -Value $wsusStatus.DeclinedUpdateCount
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "NotApprovedUpdateCount" -Value $wsusStatus.NotApprovedUpdateCount
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "UpdatesWithStaleUpdateApprovalsCount" -Value $wsusStatus.UpdatesWithStaleUpdateApprovalsCount
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "ExpiredUpdateCount" -Value $wsusStatus.ExpiredUpdateCount
$returnObject | ConvertTo-JSON-20
} Catch {
Write-Host $Error[0].Exception
exit 1

View File

@ -32,7 +32,12 @@ sub get_powershell {
my $ps = '
$culture = new-object "System.Globalization.CultureInfo" "en-us"
[System.Threading.Thread]::CurrentThread.CurrentUICulture = $culture
';
$ps .= centreon::common::powershell::functions::escape_jsonstring(%options);
$ps .= centreon::common::powershell::functions::convert_to_json(%options);
$ps .= '
$wsusServer = "' . $options{wsus_server} . '"
$useSsl = ' . $options{secure_connection} . '
$wsusPort = ' . $options{wsus_port} . '
@ -49,18 +54,21 @@ $ProgressPreference = "SilentlyContinue"
Try {
$ErrorActionPreference = "Stop"
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($wsusServer, $useSsl, $wsusPort)
$wsusObject = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($wsusServer, $useSsl, $wsusPort)
$sync_status = $wsus.GetSubscription().GetSynchronizationStatus()
$sync_progress = $wsus.GetSubscription().GetSynchronizationProgress()
$last_sync = $wsus.GetSubscription().GetLastSynchronizationInfo()
Write-Host "[SynchronizationStatus = "$sync_status"]" -NoNewline
Write-Host "[TotalItems = "$sync_progress.TotalItems"]" -NoNewline
Write-Host "[ProcessedItems = "$sync_progress.ProcessedItems"]" -NoNewline
Write-Host "[LastSynchronizationResult = "$last_sync.Result"]" -NoNewline
Write-Host "[LastSynchronizationStartTime = "$last_sync.StartTime"]" -NoNewline
Write-Host "[LastSynchronizationEndTime = "$last_sync.EndTime"]"
$syncStatus = $wsusObject.GetSubscription().GetSynchronizationStatus()
$syncProgress = $wsusObject.GetSubscription().GetSynchronizationProgress()
$lastSync = $wsusObject.GetSubscription().GetLastSynchronizationInfo()
$returnObject = New-Object -TypeName PSObject
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "SynchronizationStatus" -Value $syncStatus.ToString()
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "TotalItems" -Value $syncProgress.TotalItems
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "ProcessedItems" -Value $syncProgress.ProcessedItems
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "LastSynchronizationResult" -Value $lastSync.Result.ToString()
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "LastSynchronizationStartTime" -Value $lastSync.StartTime
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "LastSynchronizationEndTime" -Value $lastSync.EndTime
$returnObject | ConvertTo-JSON-20
} Catch {
Write-Host $Error[0].Exception
exit 1

View File

@ -22,6 +22,7 @@ package centreon::common::powershell::wsus::updatesstatus;
use strict;
use warnings;
use centreon::common::powershell::functions;
sub get_powershell {
my (%options) = @_;
@ -32,7 +33,12 @@ sub get_powershell {
my $ps = '
$culture = new-object "System.Globalization.CultureInfo" "en-us"
[System.Threading.Thread]::CurrentThread.CurrentUICulture = $culture
';
$ps .= centreon::common::powershell::functions::escape_jsonstring(%options);
$ps .= centreon::common::powershell::functions::convert_to_json(%options);
$ps .= '
$wsusServer = "' . $options{wsus_server} . '"
$useSsl = ' . $options{secure_connection} . '
$wsusPort = ' . $options{wsus_port} . '
@ -49,14 +55,18 @@ $ProgressPreference = "SilentlyContinue"
Try {
$ErrorActionPreference = "Stop"
$wsus = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($wsusServer, $useSsl, $wsusPort)
$wsusObject = [Microsoft.UpdateServices.Administration.AdminProxy]::getUpdateServer($wsusServer, $useSsl, $wsusPort)
$status = $wsus.GetStatus()
Write-Host "[UpdatesWithClientErrorsCount = "$status.UpdatesWithClientErrorsCount"]" -NoNewline
Write-Host "[UpdatesWithServerErrorsCount = "$status.UpdatesWithServerErrorsCount"]" -NoNewline
Write-Host "[UpdatesNeedingFilesCount = "$status.UpdatesNeedingFilesCount"]" -NoNewline
Write-Host "[UpdatesNeededByComputersCount = "$status.UpdatesNeededByComputersCount"]" -NoNewline
Write-Host "[UpdatesUpToDateCount = "$status.UpdatesUpToDateCount"]"
$wsusStatus = $wsusObject.GetStatus()
$returnObject = New-Object -TypeName PSObject
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "UpdatesWithClientErrorsCount" -Value $wsusStatus.UpdatesWithClientErrorsCount
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "UpdatesWithServerErrorsCount" -Value $wsusStatus.UpdatesWithServerErrorsCount
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "UpdatesNeedingFilesCount" -Value $wsusStatus.UpdatesNeedingFilesCount
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "UpdatesNeededByComputersCount" -Value $wsusStatus.UpdatesNeededByComputersCount
Add-Member -InputObject $returnObject -MemberType NoteProperty -Name "UpdatesUpToDateCount" -Value $wsusStatus.UpdatesUpToDateCount
$returnObject | ConvertTo-JSON-20
} Catch {
Write-Host $Error[0].Exception
exit 1