diff --git a/centreon-plugins/apps/backup/veeam/local/mode/jobstatus.pm b/centreon-plugins/apps/backup/veeam/local/mode/jobstatus.pm index 22e6492bb..ebe85eb28 100644 --- a/centreon-plugins/apps/backup/veeam/local/mode/jobstatus.pm +++ b/centreon-plugins/apps/backup/veeam/local/mode/jobstatus.pm @@ -25,8 +25,9 @@ use base qw(centreon::plugins::templates::counter); use strict; use warnings; use centreon::common::powershell::veeam::jobstatus; -use centreon::plugins::misc; use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold); +use centreon::plugins::misc; +use JSON::XS; sub custom_status_threshold { my ($self, %options) = @_; @@ -36,7 +37,7 @@ sub custom_status_threshold { eval { local $SIG{__WARN__} = sub { $message = $_[0]; }; local $SIG{__DIE__} = sub { $message = $_[0]; }; - + # To exclude some OK if (defined($self->{instance_mode}->{option_results}->{ok_status}) && $self->{instance_mode}->{option_results}->{ok_status} ne '' && eval "$self->{instance_mode}->{option_results}->{ok_status}") { @@ -203,54 +204,60 @@ sub manage_selection { $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); $self->{output}->exit(); } - - #[name = xxxx ][type = Backup ][isrunning = False ][result = Success ][creationTimeUTC = 1512875246.2 ][endTimeUTC = 1512883615.377 ] - #[name = xxxx ][type = Backup ][isrunning = False ][result = ][creationTimeUTC = ][endTimeUTC = ] - #[name = xxxx ][type = BackupSync ][isrunning = True ][result = None ][creationTimeUTC = 1513060425.027 ][endTimeUTC = -2208992400 ] - #is_running = 2 (never running) + 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(); + } + + #[ + # { name: 'xxxx', type: 'Backup', isRunning: False, result: 'Success', creationTimeUTC: 1512875246.2, endTimeUTC: 1512883615.377 }, + # { name: 'xxxx', type: 'Backup', isRunning: False, result: '', creationTimeUTC: '', endTimeUTC: '' }, + # { name: 'xxxx', type: 'BackupSync', isRunning: True, result: 'None', creationTimeUTC: 1513060425.027, endTimeUTC: -2208992400 } + #] + $self->{global} = { total => 0 }; $self->{job} = {}; my $current_time = time(); - foreach my $line (split /\n/, $stdout) { - next if ($line !~ /^\[name\s*=(.*?)\]\[type\s*=(.*?)\]\[isrunning\s*=(.*?)\]\[result\s*=(.*?)\]\[creationTimeUTC\s*=(.*?)\]\[endTimeUTC\s*=(.*?)\]/i); - - my ($name, $type, $is_running, $result, $start_time, $end_time) = ( - centreon::plugins::misc::trim($1), centreon::plugins::misc::trim($2), centreon::plugins::misc::trim($3), - centreon::plugins::misc::trim($4), centreon::plugins::misc::trim($5), centreon::plugins::misc::trim($6) - ); - $start_time =~ s/,/\./; - $end_time =~ s/,/\./; + foreach my $job (@$decoded) { + $job->{creationTimeUTC} =~ s/,/\./; + $job->{endTimeUTC} =~ s/,/\./; if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && - $name !~ /$self->{option_results}->{filter_name}/) { - $self->{output}->output_add(long_msg => "skipping job '" . $name . "': no matching filter.", debug => 1); + $job->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping job '" . $job->{name} . "': no matching filter.", debug => 1); next; } if (defined($self->{option_results}->{filter_type}) && $self->{option_results}->{filter_type} ne '' && - $type !~ /$self->{option_results}->{filter_type}/) { - $self->{output}->output_add(long_msg => "skipping job '" . $name . "': no matching filter type.", debug => 1); + $job->{type} !~ /$self->{option_results}->{filter_type}/) { + $self->{output}->output_add(long_msg => "skipping job '" . $job->{name} . "': no matching filter type.", debug => 1); next; } if (defined($self->{option_results}->{filter_end_time}) && $self->{option_results}->{filter_end_time} =~ /[0-9]+/ && - defined($end_time) && $end_time =~ /[0-9]+/ && $end_time < $current_time - $self->{option_results}->{filter_end_time}) { - $self->{output}->output_add(long_msg => "skipping job '" . $name . "': end time too old.", debug => 1); + $job->{endTimeUTC} =~ /[0-9]+/ && $job->{endTimeUTC} < $current_time - $self->{option_results}->{filter_end_time}) { + $self->{output}->output_add(long_msg => "skipping job '" . $job->{name} . "': end time too old.", debug => 1); next; } if (defined($self->{option_results}->{filter_start_time}) && $self->{option_results}->{filter_start_time} =~ /[0-9]+/ && - defined($start_time) && $start_time =~ /[0-9]+/ && $start_time < $current_time - $self->{option_results}->{filter_start_time}) { - $self->{output}->output_add(long_msg => "skipping job '" . $name . "': start time too old.", debug => 1); + $job->{creationTimeUTC} =~ /[0-9]+/ && $job->{creationTimeUTC} < $current_time - $self->{option_results}->{filter_start_time}) { + $self->{output}->output_add(long_msg => "skipping job '" . $job->{name} . "': start time too old.", debug => 1); next; } - + my $elapsed_time; - $elapsed_time = $current_time - $start_time if ($start_time =~ /[0-9]/); - $self->{job}->{$name} = { - display => $name, + $elapsed_time = $current_time - $job->{creationTimeUTC} if ($job->{creationTimeUTC} =~ /[0-9]/); + + #is_running = 2 (never running) + $self->{job}->{ $job->{name} } = { + display => $job->{name}, elapsed => $elapsed_time, - type => $type, - is_running => ($is_running =~ /True/) ? 1 : ($start_time !~ /[0-9]/ ? 2 : 0), - status => $result ne '' ? $result : '-', + type => $job->{type}, + is_running => $job->{isRunning} =~ /True|1/ ? 1 : ($job->{creationTimeUTC} !~ /[0-9]/ ? 2 : 0), + status => $job->{result} ne '' ? $job->{result} : '-' }; $self->{global}->{total}++; } diff --git a/centreon-plugins/apps/backup/veeam/local/mode/listjobs.pm b/centreon-plugins/apps/backup/veeam/local/mode/listjobs.pm index 26678e6d4..f8064c166 100644 --- a/centreon-plugins/apps/backup/veeam/local/mode/listjobs.pm +++ b/centreon-plugins/apps/backup/veeam/local/mode/listjobs.pm @@ -117,20 +117,25 @@ sub manage_selection { $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); $self->{output}->exit(); } - + + 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->{jobs} = {}; - my @lines = split /\n/, $stdout; - foreach my $line (@lines) { - next if ($line !~ /^\[name\s*=(.*?)\]\[type\s*=(.*?)\]/i); - my ($name, $type) = (centreon::plugins::misc::trim($1), centreon::plugins::misc::trim($2)); - + foreach my $job (@$decoded) { if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && - $name !~ /$self->{option_results}->{filter_name}/i) { - $self->{output}->output_add(long_msg => "skipping job '" . $name . "': no type or no matching filter type", debug => 1); + $job->{name} !~ /$self->{option_results}->{filter_name}/i) { + $self->{output}->output_add(long_msg => "skipping job '" . $job->{name} . "': no type or no matching filter type", debug => 1); next; } - $self->{jobs}->{$name} = { type => $type }; + $self->{jobs}->{ $job->{name} } = { type => $job->{type} }; } } diff --git a/centreon-plugins/apps/backup/veeam/local/mode/tapejobs.pm b/centreon-plugins/apps/backup/veeam/local/mode/tapejobs.pm new file mode 100644 index 000000000..8ed32bc73 --- /dev/null +++ b/centreon-plugins/apps/backup/veeam/local/mode/tapejobs.pm @@ -0,0 +1,258 @@ +# +# Copyright 2020 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 apps::backup::veeam::local::mode::tapejobs; + +use base qw(centreon::plugins::templates::counter); + +use strict; +use warnings; +use centreon::common::powershell::veeam::tapejobs; +use centreon::plugins::templates::catalog_functions qw(catalog_status_threshold catalog_status_calc); +use centreon::plugins::misc; +use JSON::XS; + +sub custom_status_output { + my ($self, %options) = @_; + + return sprintf( + "last result: '%s' [type: '%s'][last state: '%s']", + $self->{result_values}->{last_result}, + $self->{result_values}->{type}, + $self->{result_values}->{last_state}, + ); +} + +sub set_counters { + my ($self, %options) = @_; + + $self->{maps_counters_type} = [ + { name => 'global', type => 0 }, + { name => 'job', type => 1, cb_prefix_output => 'prefix_job_output', message_multiple => 'All jobs are ok', skipped_code => { -10 => 1 } }, + ]; + + $self->{maps_counters}->{global} = [ + { label => 'total', nlabel => 'tapejobs.total.count', set => { + key_values => [ { name => 'total' } ], + output_template => 'total jobs: %s', + perfdatas => [ + { value => 'total_absolute', template => '%s', min => 0 }, + ], + } + }, + ]; + + $self->{maps_counters}->{job} = [ + { label => 'status', threshold => 0, set => { + key_values => [ + { name => 'display' }, { name => 'enabled' }, + { name => 'type' }, { name => 'last_result' }, + { name => 'last_state' } + ], + closure_custom_calc => \&catalog_status_calc, + closure_custom_output => $self->can('custom_status_output'), + closure_custom_perfdata => sub { return 0; }, + closure_custom_threshold_check => \&catalog_status_threshold, + } + } + ]; +} + +sub new { + my ($class, %options) = @_; + my $self = $class->SUPER::new(package => __PACKAGE__, %options, force_new_perfdata => 1); + bless $self, $class; + + $options{options}->add_options(arguments => { + 'timeout:s' => { name => 'timeout', default => 50 }, + 'command:s' => { name => 'command', default => 'powershell.exe' }, + 'command-path:s' => { name => 'command_path' }, + 'command-options:s' => { name => 'command_options', default => '-InputFormat none -NoLogo -EncodedCommand' }, + 'no-ps' => { name => 'no_ps' }, + 'ps-exec-only' => { name => 'ps_exec_only' }, + 'ps-display' => { name => 'ps_display' }, + 'filter-name:s' => { name => 'filter_name' }, + 'filter-type:s' => { name => 'filter_type' }, + 'unknown-status:s' => { name => 'unknown_status', default => '' }, + 'warning-status:s' => { name => 'warning_status', default => '' }, + 'critical-status:s' => { name => 'critical_status', default => '%{enabled} == 1 and not %{last_result} =~ /Success|None/i' } + }); + + return $self; +} + +sub check_options { + my ($self, %options) = @_; + $self->SUPER::check_options(%options); + + $self->change_macros(macros => ['unknown_status', 'warning_status', 'critical_status']); +} + +sub prefix_job_output { + my ($self, %options) = @_; + + return "Tape job '" . $options{instance_value}->{display} . "' "; +} + +sub manage_selection { + my ($self, %options) = @_; + + if (!defined($self->{option_results}->{no_ps})) { + my $ps = centreon::common::powershell::veeam::tapejobs::get_powershell(); + if (defined($self->{option_results}->{ps_display})) { + $self->{output}->output_add( + severity => 'OK', + short_msg => $ps + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); + } + + $self->{option_results}->{command_options} .= " " . centreon::plugins::misc::powershell_encoded($ps); + } + + my ($stdout) = centreon::plugins::misc::execute( + output => $self->{output}, + options => $self->{option_results}, + command => $self->{option_results}->{command}, + command_path => $self->{option_results}->{command_path}, + command_options => $self->{option_results}->{command_options} + ); + if (defined($self->{option_results}->{ps_exec_only})) { + $self->{output}->output_add( + severity => 'OK', + short_msg => $stdout + ); + $self->{output}->display(nolabel => 1, force_ignore_perfdata => 1, force_long_output => 1); + $self->{output}->exit(); + } + + 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(); + } + + #[ + # { name: 'xxxx', type: 'BackupToTape', Enabled: True, lastResult: 'Success', lastState: 'Stopped' }, + # { name: 'xxxx', type: 'FileToTape', Enabled: True, lastResult: 'None', lastState: 'Working' } + #] + + $self->{global} = { total => 0 }; + $self->{job} = {}; + foreach my $job (@$decoded) { + if (defined($self->{option_results}->{filter_name}) && $self->{option_results}->{filter_name} ne '' && + $job->{name} !~ /$self->{option_results}->{filter_name}/) { + $self->{output}->output_add(long_msg => "skipping job '" . $job->{name} . "': no matching filter.", debug => 1); + next; + } + if (defined($self->{option_results}->{filter_type}) && $self->{option_results}->{filter_type} ne '' && + $job->{type} !~ /$self->{option_results}->{filter_type}/) { + $self->{output}->output_add(long_msg => "skipping job '" . $job->{name} . "': no matching filter type.", debug => 1); + next; + } + + $self->{job}->{ $job->{name} } = { + display => $job->{name}, + type => $job->{type}, + enabled => $job->{enabled} =~ /True|1/ ? 1 : 0, + last_result => $job->{lastResult}, + last_state => $job->{lastState} + }; + $self->{global}->{total}++; + } +} + +1; + +__END__ + +=head1 MODE + +Check tape jobs status. + +=over 8 + +=item B<--timeout> + +Set timeout time for command execution (Default: 50 sec) + +=item B<--no-ps> + +Don't encode powershell. To be used with --command and 'type' command. + +=item B<--command> + +Command to get information (Default: 'powershell.exe'). +Can be changed if you have output in a file. To be used with --no-ps option!!! + +=item B<--command-path> + +Command path (Default: none). + +=item B<--command-options> + +Command options (Default: '-InputFormat none -NoLogo -EncodedCommand'). + +=item B<--ps-display> + +Display powershell script. + +=item B<--ps-exec-only> + +Print powershell output. + +=item B<--filter-name> + +Filter job name (can be a regexp). + +=item B<--filter-type> + +Filter job type (can be a regexp). + +=item B<--unknown-status> + +Set unknown threshold for status (Default: '') +Can used special variables like: %{display}, %{enabled}, %{type}, %{last_result}, %{last_state}. + +=item B<--warning-status> + +Set warning threshold for status (Default: '') +Can used special variables like: %{display}, %{enabled}, %{type}, %{last_result}, %{last_state}. + +=item B<--critical-status> + +Set critical threshold for status (Default: '%{enabled} == 1 and not %{last_result} =~ /Success|None/i'). +Can used special variables like: %{display}, %{enabled}, %{type}, %{last_result}, %{last_state}. + +=item B<--warning-total> + +Set warning threshold for total jobs. + +=item B<--critical-total> + +Set critical threshold for total jobs. + +=back + +=cut diff --git a/centreon-plugins/apps/backup/veeam/local/plugin.pm b/centreon-plugins/apps/backup/veeam/local/plugin.pm index 845ebb30f..3be6e97a1 100644 --- a/centreon-plugins/apps/backup/veeam/local/plugin.pm +++ b/centreon-plugins/apps/backup/veeam/local/plugin.pm @@ -31,8 +31,9 @@ sub new { $self->{version} = '0.1'; %{$self->{modes}} = ( - 'job-status' => 'apps::backup::veeam::local::mode::jobstatus', - 'list-jobs' => 'apps::backup::veeam::local::mode::listjobs', + 'job-status' => 'apps::backup::veeam::local::mode::jobstatus', + 'list-jobs' => 'apps::backup::veeam::local::mode::listjobs', + 'tape-jobs' => 'apps::backup::veeam::local::mode::tapejobs', ); return $self; diff --git a/centreon-plugins/apps/wsus/local/mode/computersstatus.pm b/centreon-plugins/apps/wsus/local/mode/computersstatus.pm index 8ddcc0cbf..52d88f9ad 100644 --- a/centreon-plugins/apps/wsus/local/mode/computersstatus.pm +++ b/centreon-plugins/apps/wsus/local/mode/computersstatus.pm @@ -161,7 +161,7 @@ sub manage_selection { my $decoded; eval { - $decoded = JSON::XS->new->utf8->decode(centreon::plugins::misc::powershell_json_sanitizer(string => $stdout, output => $self->{output})); + $decoded = JSON::XS->new->utf8->decode($stdout); }; if ($@) { $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); diff --git a/centreon-plugins/apps/wsus/local/mode/serverstatistics.pm b/centreon-plugins/apps/wsus/local/mode/serverstatistics.pm index d83b6132e..927930f58 100644 --- a/centreon-plugins/apps/wsus/local/mode/serverstatistics.pm +++ b/centreon-plugins/apps/wsus/local/mode/serverstatistics.pm @@ -179,7 +179,7 @@ sub manage_selection { my $decoded; eval { - $decoded = JSON::XS->new->utf8->decode(centreon::plugins::misc::powershell_json_sanitizer(string => $stdout, output => $self->{output})); + $decoded = JSON::XS->new->utf8->decode($stdout); }; if ($@) { $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); diff --git a/centreon-plugins/apps/wsus/local/mode/synchronisationstatus.pm b/centreon-plugins/apps/wsus/local/mode/synchronisationstatus.pm index bd466c052..7ced9a5a8 100644 --- a/centreon-plugins/apps/wsus/local/mode/synchronisationstatus.pm +++ b/centreon-plugins/apps/wsus/local/mode/synchronisationstatus.pm @@ -282,7 +282,7 @@ sub manage_selection { my $decoded; eval { - $decoded = JSON::XS->new->utf8->decode(centreon::plugins::misc::powershell_json_sanitizer(string => $stdout, output => $self->{output})); + $decoded = JSON::XS->new->utf8->decode($stdout); }; if ($@) { $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); diff --git a/centreon-plugins/apps/wsus/local/mode/updatesstatus.pm b/centreon-plugins/apps/wsus/local/mode/updatesstatus.pm index dee5932c2..390a16170 100644 --- a/centreon-plugins/apps/wsus/local/mode/updatesstatus.pm +++ b/centreon-plugins/apps/wsus/local/mode/updatesstatus.pm @@ -158,7 +158,7 @@ sub manage_selection { my $decoded; eval { - $decoded = JSON::XS->new->utf8->decode(centreon::plugins::misc::powershell_json_sanitizer(string => $stdout, output => $self->{output})); + $decoded = JSON::XS->new->utf8->decode($stdout); }; if ($@) { $self->{output}->add_option_msg(short_msg => "Cannot decode json response: $@"); diff --git a/centreon-plugins/centreon/common/powershell/veeam/jobstatus.pm b/centreon-plugins/centreon/common/powershell/veeam/jobstatus.pm index efaeb0b51..2bffbb7e9 100644 --- a/centreon-plugins/centreon/common/powershell/veeam/jobstatus.pm +++ b/centreon-plugins/centreon/common/powershell/veeam/jobstatus.pm @@ -22,6 +22,7 @@ package centreon::common::powershell::veeam::jobstatus; use strict; use warnings; +use centreon::common::powershell::functions; sub get_powershell { my (%options) = @_; @@ -29,7 +30,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 .= ' If (@(Get-PSSnapin -Registered | Where-Object {$_.Name -Match "VeeamPSSnapin"} ).count -gt 0) { If (@(Get-PSSnapin | Where-Object {$_.Name -Match "VeeamPSSnapin"} ).count -eq 0) { Try { @@ -49,20 +55,30 @@ $ProgressPreference = "SilentlyContinue" Try { $ErrorActionPreference = "Stop" + $items = New-Object System.Collections.Generic.List[Hashtable]; + $jobs = Get-VBRJob foreach ($job in $jobs) { - Write-Host "[name = " $job.Name "]" -NoNewline - Write-Host "[type = " $job.JobType "]" -NoNewline - Write-Host "[isrunning = " $job.isRunning "]" -NoNewline + $item = @{} + $item.name = $job.Name + $item.type = $job.JobType + $item.isRunning = $job.isRunning + $item.result = "" + $item.creationTimeUTC = "" + $item.endTimeUTC = "" + $lastsession = $job.findlastsession() if ($lastsession) { - Write-Host "[result = " $lastsession.Result "]" -NoNewline - Write-Host "[creationTimeUTC = " (get-date -date $lastsession.creationTime.ToUniversalTime() -Uformat ' . "'%s'" . ') "]" -NoNewline - Write-Host "[endTimeUTC = " (get-date -date $lastsession.EndTime.ToUniversalTime() -Uformat ' . "'%s'" . ') "]" - } else { - Write-Host "[result = ][creationTimeUTC = ][endTimeUTC = ]" + $item.result = $lastsession.Result + $item.creationTimeUTC = (get-date -date $lastsession.creationTime.ToUniversalTime() -Uformat ' . "'%s'" . ') + $item.endTimeUTC = (get-date -date $lastsession.EndTime.ToUniversalTime() -Uformat ' . "'%s'" . ') } + + $items.Add($item) } + + $jsonString = $items | ConvertTo-JSON-20 -forceArray 1 + Write-Host $jsonString } Catch { Write-Host $Error[0].Exception exit 1 diff --git a/centreon-plugins/centreon/common/powershell/veeam/listjobs.pm b/centreon-plugins/centreon/common/powershell/veeam/listjobs.pm index 7d6859267..40c20da1f 100644 --- a/centreon-plugins/centreon/common/powershell/veeam/listjobs.pm +++ b/centreon-plugins/centreon/common/powershell/veeam/listjobs.pm @@ -22,6 +22,7 @@ package centreon::common::powershell::veeam::listjobs; use strict; use warnings; +use centreon::common::powershell::functions; sub get_powershell { my (%options) = @_; @@ -29,7 +30,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 .= ' If (@(Get-PSSnapin -Registered | Where-Object {$_.Name -Match "VeeamPSSnapin"} ).count -gt 0) { If (@(Get-PSSnapin | Where-Object {$_.Name -Match "VeeamPSSnapin"} ).count -eq 0) { Try { @@ -49,11 +55,20 @@ $ProgressPreference = "SilentlyContinue" Try { $ErrorActionPreference = "Stop" + $items = New-Object System.Collections.Generic.List[Hashtable]; + $jobs = Get-VBRJob foreach ($job in $jobs) { - Write-Host "[name = " $job.Name "]" -NoNewline - Write-Host "[type = " $job.JobType "]" + $item = @{ + name = $job.Name; + type = $job.JobType + } + + $items.Add($item) } + + $jsonString = $items | ConvertTo-JSON-20 -forceArray 1 + Write-Host $jsonString } Catch { Write-Host $Error[0].Exception exit 1 diff --git a/centreon-plugins/centreon/common/powershell/veeam/tapejobs.pm b/centreon-plugins/centreon/common/powershell/veeam/tapejobs.pm new file mode 100644 index 000000000..52b2803e0 --- /dev/null +++ b/centreon-plugins/centreon/common/powershell/veeam/tapejobs.pm @@ -0,0 +1,94 @@ +# +# Copyright 2020 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::veeam::tapejobs; + +use strict; +use warnings; +use centreon::common::powershell::functions; + +sub get_powershell { + my (%options) = @_; + + 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 .= ' +If (@(Get-PSSnapin -Registered | Where-Object {$_.Name -Match "VeeamPSSnapin"} ).count -gt 0) { + If (@(Get-PSSnapin | Where-Object {$_.Name -Match "VeeamPSSnapin"} ).count -eq 0) { + Try { + Get-PSSnapin -Registered | Where-Object {$_.Name -Match "VeeamPSSnapin"} | Add-PSSnapin -ErrorAction STOP + } Catch { + Write-Host $Error[0].Exception + exit 1 + } + } +} else { + Write-Host "Snap-In Veeam no present or not registered" + exit 1 +} + +$ProgressPreference = "SilentlyContinue" + +Try { + $ErrorActionPreference = "Stop" + + $items = New-Object System.Collections.Generic.List[Hashtable]; + + $jobs = Get-VBRtapeJob + foreach ($job in $jobs) { + $item = @{ + name = $job.Name; + enabled = $job.Enabled; + type = $job.Type; + lastResult = $job.LastResult; + lastState = $job.LastState + } + + $items.Add($item) + } + + $jsonString = $items | ConvertTo-JSON-20 -forceArray 1 + Write-Host $jsonString +} Catch { + Write-Host $Error[0].Exception + exit 1 +} + +exit 0 +'; + + return $ps; +} + +1; + +__END__ + +=head1 DESCRIPTION + +Method to get veeam tape job status informations. + +=cut diff --git a/centreon-plugins/centreon/common/powershell/wsus/computersstatus.pm b/centreon-plugins/centreon/common/powershell/wsus/computersstatus.pm index 30940205b..f28f338e1 100644 --- a/centreon-plugins/centreon/common/powershell/wsus/computersstatus.pm +++ b/centreon-plugins/centreon/common/powershell/wsus/computersstatus.pm @@ -62,15 +62,16 @@ Try { $computerTargetScope = new-object Microsoft.UpdateServices.Administration.ComputerTargetScope $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 - - $jsonString = $returnObject | ConvertTo-JSON-20 + + $item = @{ + ComputerTargetsNeedingUpdatesCount = $wsusStatus.ComputerTargetsNeedingUpdatesCount; + ComputerTargetsWithUpdateErrorsCount = $wsusStatus.ComputerTargetsWithUpdateErrorsCount; + ComputersUpToDateCount = $wsusStatus.ComputersUpToDateCount; + ComputersNotContactedSinceCount = $computersNotContactedSinceCount; + UnassignedComputersCount = $unassignedComputersCount + } + + $jsonString = $item | ConvertTo-JSON-20 Write-Host $jsonString } Catch { Write-Host $Error[0].Exception diff --git a/centreon-plugins/centreon/common/powershell/wsus/serverstatistics.pm b/centreon-plugins/centreon/common/powershell/wsus/serverstatistics.pm index 6d08ba700..ddf7f8531 100644 --- a/centreon-plugins/centreon/common/powershell/wsus/serverstatistics.pm +++ b/centreon-plugins/centreon/common/powershell/wsus/serverstatistics.pm @@ -56,17 +56,18 @@ Try { $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 + $item = @{ + ComputerTargetCount = $wsusStatus.ComputerTargetCount; + CustomComputerTargetGroupCount = $wsusStatus.CustomComputerTargetGroupCount; + UpdateCount = $wsusStatus.UpdateCount; + ApprovedUpdateCount = $wsusStatus.ApprovedUpdateCount; + DeclinedUpdateCount = $wsusStatus.DeclinedUpdateCount; + NotApprovedUpdateCount = $wsusStatus.NotApprovedUpdateCount; + UpdatesWithStaleUpdateApprovalsCount = $wsusStatus.UpdatesWithStaleUpdateApprovalsCount; + ExpiredUpdateCount = $wsusStatus.ExpiredUpdateCount + } - $jsonString = $returnObject | ConvertTo-JSON-20 + $jsonString = $item | ConvertTo-JSON-20 Write-Host $jsonString } Catch { Write-Host $Error[0].Exception diff --git a/centreon-plugins/centreon/common/powershell/wsus/synchronisationstatus.pm b/centreon-plugins/centreon/common/powershell/wsus/synchronisationstatus.pm index 0b4c317f7..2bde9cf2b 100644 --- a/centreon-plugins/centreon/common/powershell/wsus/synchronisationstatus.pm +++ b/centreon-plugins/centreon/common/powershell/wsus/synchronisationstatus.pm @@ -58,15 +58,16 @@ Try { $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 + $item = @{ + SynchronizationStatus = $syncStatus.ToString(); + TotalItems = $syncProgress.TotalItems; + ProcessedItems = $syncProgress.ProcessedItems; + LastSynchronizationResult = $lastSync.Result.ToString(); + LastSynchronizationStartTime = $lastSync.StartTime; + LastSynchronizationEndTime = $lastSync.EndTime + } - $jsonString = $returnObject | ConvertTo-JSON-20 + $jsonString = $item | ConvertTo-JSON-20 Write-Host $jsonString } Catch { Write-Host $Error[0].Exception diff --git a/centreon-plugins/centreon/common/powershell/wsus/updatesstatus.pm b/centreon-plugins/centreon/common/powershell/wsus/updatesstatus.pm index 317dbf41b..1443088f5 100644 --- a/centreon-plugins/centreon/common/powershell/wsus/updatesstatus.pm +++ b/centreon-plugins/centreon/common/powershell/wsus/updatesstatus.pm @@ -56,14 +56,15 @@ Try { $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 + $item = @{ + UpdatesWithClientErrorsCount = $wsusStatus.UpdatesWithClientErrorsCount; + UpdatesWithServerErrorsCount = $wsusStatus.UpdatesWithServerErrorsCount; + UpdatesNeedingFilesCount = $wsusStatus.UpdatesNeedingFilesCount; + UpdatesNeededByComputersCount = $wsusStatus.UpdatesNeededByComputersCount; + UpdatesUpToDateCount = $wsusStatus.UpdatesUpToDateCount + } - $jsonString = $returnObject | ConvertTo-JSON-20 + $jsonString = $item | ConvertTo-JSON-20 Write-Host $jsonString } Catch { Write-Host $Error[0].Exception diff --git a/centreon-plugins/centreon/plugins/misc.pm b/centreon-plugins/centreon/plugins/misc.pm index 7c96f1b88..d4334ff58 100644 --- a/centreon-plugins/centreon/plugins/misc.pm +++ b/centreon-plugins/centreon/plugins/misc.pm @@ -336,20 +336,6 @@ sub powershell_escape { return $value; } -sub powershell_json_sanitizer { - my (%options) = @_; - - centreon::plugins::misc::mymodule_load( - output => $options{output}, module => 'JSON::XS', - error_msg => "Cannot load module 'JSON::XS'." - ); - foreach my $line (split /\n/, $options{string}) { - eval { JSON::XS->new->utf8->decode($line) }; - return $line if (!$@); - } - return -1; -} - sub minimal_version { my ($version_src, $version_dst) = @_;