NOTE: Let niet op de comments achter de code. Dat is nog vanuit een eerdere versie 
Zie onderstaand script. Het gaat om het stukje waar hij in de function monitor-CLI moet checken of de dag van gister (dus bijv Saturday) in de schedule voorkomt, waarna hij wel of niet de backup history checkt op fouten e.d.
Ik gebruik hiervoor -match om met regex te checken of het woord er in voorkomt. Echter is het zo dat sommige van de klanten van mijn werkgever de calendar region settings op dutch hebben staan (terwijl de overal language gewoon engels is). De schedule vanuit Backup Exec wordt daardoor in het Nederlands weergegeven. Ik snap dat het het makkelijkst is om de calendar region op UK te zetten, maar dat is nogal veel werk gezien het nogal wat klanten beteft bij mijn werkgever.
Hiervoor maak ik (onderaan in het script) een array met de get-date welke hij daaraan toevoegd, en (even als test) als het 'Saturday" betreft dan wordt er "Zaterdag" toegevoegd aan het array. Hiermee los ik het taal probleem heel smerig op (als er mooiere oplossingen zijn, let me know).
Mijn vraag: Waarom werkt de "If ($schedule.schedule -match $yesterday) {" niet? als in de $schedule Zaterdag of Saturday voorkomt en in $yesterday ook, dan moetie toch daarop doorgaan?
Zie onderstaand script. Het gaat om het stukje waar hij in de function monitor-CLI moet checken of de dag van gister (dus bijv Saturday) in de schedule voorkomt, waarna hij wel of niet de backup history checkt op fouten e.d.
Ik gebruik hiervoor -match om met regex te checken of het woord er in voorkomt. Echter is het zo dat sommige van de klanten van mijn werkgever de calendar region settings op dutch hebben staan (terwijl de overal language gewoon engels is). De schedule vanuit Backup Exec wordt daardoor in het Nederlands weergegeven. Ik snap dat het het makkelijkst is om de calendar region op UK te zetten, maar dat is nogal veel werk gezien het nogal wat klanten beteft bij mijn werkgever.
Hiervoor maak ik (onderaan in het script) een array met de get-date welke hij daaraan toevoegd, en (even als test) als het 'Saturday" betreft dan wordt er "Zaterdag" toegevoegd aan het array. Hiermee los ik het taal probleem heel smerig op (als er mooiere oplossingen zijn, let me know).
Mijn vraag: Waarom werkt de "If ($schedule.schedule -match $yesterday) {" niet? als in de $schedule Zaterdag of Saturday voorkomt en in $yesterday ook, dan moetie toch daarop doorgaan?
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
| function Write-Alert { # Function for the alert message output to AEM, with logging on screen param([string]$Alert) Write-Host "<-Start Result->" Write-Host "CSMon_Result="$Alert Write-Host "<-End Result->" exit 1 } Function Job_Report { # Function to add the job-objects from the jobreports $jobs = @() $jobObject = New-Object -TypeName PSObject $jobObject | Add-Member -MemberType NoteProperty -Name Id -Value $j.JobTypeID $jobObject | Add-Member -MemberType NoteProperty -Name Name -Value $j.JobName $jobObject | Add-Member -MemberType NoteProperty -Name StartTime -Value $j.ActualStartTime $jobObject | Add-Member -MemberType NoteProperty -Name Status -Value $j.FinalJobStatus $jobObject | Add-Member -MemberType NoteProperty -Name EndTime -Value ($j.ActualStartTime -as [datetime]).AddSeconds($j.ElapsedTimeSeconds) $jobs += $jobObject; Write-Host $jobs return $jobs } function Monitor-CMD { # Monitor for version 2010. For version 2010 R2 and later, using the BEM-CMD Write-Host "Monitor versie 2010" $installedPath = (Get-ItemProperty 'HKLM:\SOFTWARE\*\Backup Exec For Windows\Backup Exec\*\install' -Name Path).Path # Get the installation path $alertMessages = @() # Array for alert messages $ServiceArray = 'BackupExecRPCService', 'BackupExecJobEngine', 'BackupExecManagementService' # Array for backup exec services $jobs = @() # Array for jobs $report = [System.IO.Path]::GetTempFileName() # Attribute to create a temporary 'file' $schedule = Invoke-Expression "& '$installedPath\bemcmd.exe' -o506 -j -d3" # Get the schedule of the job(s) Get-Service -Name $serviceArray | Sort-Object Status,Displayname | ForEach-Object { If($_.Status -ne "Running") { $alertMessages += "Service Not Running" # Find The services named in the $serviceArray. Check if these are running or not } } if ( $schedule -match 'Saturday' -or $schedule -match 'Zaterdag' ) { # Check if the schedule of the job(s) is/are contain(s)(ing) the day Saturday (+ Dutch translation) If ((get-date).DayOfWeek -eq "Monday" -Or ((get-date).Hour -le '13' -and (get-date).DayOfWeek -eq 'Tuesday')) { # If it does, exit the script on Monday and Tuesday (until 14:00) exit 0 } } if ( $schedule -notmatch 'Saturday' -or $schedule -notmatch 'Zaterdag' ) { # Check if the schedule of the job(s) is/are NOT contain(s)(ing) the day Saturday (+ Dutch translation) If ((get-date).DayOfWeek -eq "Sunday" -Or (get-date).DayOfWeek -eq "Monday" -Or ((get-date).Hour -le '13' -and (get-date).DayOfWeek -eq 'Tuesday')) { # If it does not, exit the script on Sunday, Monday and Tuesday (until 14:00) exit 0 } } Try { # This try is because the next command does not work on all Backup Exec 2010 R2+ products $cmd = Invoke-Expression "& '$installedPath\bemcmd.exe' -o402 -r13 -ft:2 -ps:'@Hours=180' -f:'$report'" # Get all job values and put them in the $report variable and the return in $cmd if ($cmd -match 'RETURN VALUE: -1') { # If the value of $cmd is equal to 'value -1' it means there is no data, exit script write-host 'VALUE -1' # Write 'value -1' to the host as debug check exit 0 } else { [xml]$content = Get-Content $report # Read the XML content of the $report variable foreach ($j in $content.DataSet.ReportDailyJobs) { # For each field in the XML file -> Job_Report $content # Run the Function 'Job_Report' for the $content variable, which contains XML data } } } Finally { # This try is because the 'Try code' does not work on all Backup Exec 2010 R2+ products $cmd = Invoke-Expression "& '$installedPath\bemcmd.exe' -o402 -r14 -ft:2 -ps:'@Hours=180' -f:'$report'" # Get all job values and put them in the $report variable and the return in $cmd if ($cmd -match 'RETURN VALUE: -1') { # If the value of $cmd is equal to 'value -1' it means there is no data, exit script write-host 'VALUE -1' # Write 'value -1' to the host exit 0 } Else { [xml]$content = Get-Content $report # Read the XML content of the $report variable foreach ($j in $content.DataSet.ReportDailyJobs) { # For each field in the XML file -> $jobs += Job_Report $content # Run the Function 'Job_Report' for the $content variable, which contains XML data } } Remove-Item -Force $report # Remove the $report variable/file } if ($jobs) { # If $jobs is not empty, the content of this variable is split in succeeded jobs and failed jobs. After that, combined into 2 seperates arrays # 19 - JOB_STATE_SUCCESS # 2 - JOB_STATE_COMPLETED # 3 - JOB_STATE_SUCCESS_WITH_EXCEPTIONS $succeededStatuses = @(19, 2, 3) # Only these statuscodes are filtered $succeededJob = $jobs | ? { $succeededStatuses -contains $_.Status } | ? {$_.Name -notmatch 'Inventory Drive' } | ? {$_.Name -notmatch 'Eject Drive' } | Sort-Object EndTime -descending | Select-Object -First 1 # Filter all jobs with the statuscodes stated above, not matching with a name matching 'Inventory Drive' or 'Eject Drive'. Sorting them on endtime as descending and selecting the first one. Put them into the variable $succeededJob Write-Host "Succeeded Jobs:" $succeededJob # Write the succeeded job array to the host as debug check # 1 - JOB_STATE_CANCELED # 6 - JOB_STATE_ERROR # 7 - JOB_STATE_INVALID_SCHEDULE # 10 - JOB_STATE_NOT_IN_WINDOW # 21 - JOB_STATE_NOT_IN_WINDOW $failedStatuses = @(1, 6, 7, 10, 21) # Only these statuscodes are filtered $failedJob = $jobs | ? { $failedStatuses -contains $_.Status } | ? {$_.Name -notmatch 'Inventory Drive' } | ? {$_.Name -notmatch 'Eject Drive' } | Sort-Object EndTime -descending | Select-Object -First 1 # Filter all jobs with the statuscodes stated above, not matching with a name matching 'Inventory Drive' or 'Eject Drive'. Sorting them on endtime as descending and selecting the first one. Put them into the variable $failedJob Write-Host "Failed Jobs:" $failedJob # Write the succeeded job array to the host as debug check if ([Environment]::GetEnvironmentVariable("backupHours", "Process")) { # Check if the backup hours are defined in AEM via the environment variable $backupHours = [Environment]::GetEnvironmentVariable("backupHours", "Process") # Put these hours into a variable } if (-not $succeededJob -or $succeededJob.EndTime.AddHours($backupHours) -le [DateTime]::Now) { # Check for backup jobs in the past 24 hours (or X hours as defined in AEM) $alertMessages += "No backup was done in $backupHours hours" # Add an alert message if there has not been a backup job in the past 24h } if ($failedJob.EndTime -ge $succeededJob.EndTime) { # Compare the latest failed job endtime with the latest succeeded job endtime. $alertMessages += "Last backup has errors" # Alert if failed endtime is greater than or equal to the succeed endtime } if ($failedJob.EndTime.ToShortDateString -eq $succeededJob.EndTime.ToShortDateString -or $failedJob.EndTime.ToShortDateString -eq $succeededJob.EndTime.ToShortDateString) { # Comparison to check if there has been any error in the last backups $alertMessages += "One of the backup jobs has errors" # Alert if there are any errors } return $alertMessages # Return the array of alertmessages to the main script } } Function Monitor-CLI { # Monitor for version 2012 and later, using de BEM-CLI Write-Host "Monitor versie 2012, 14, 15, 16, etc" $installedPath = (Get-ItemProperty 'HKLM:\SOFTWARE\*\Backup Exec For Windows\Backup Exec\*\install' -Name Path).Path # Check the installation path of Backup Exec via the register of Windows Import-module "$installedPath\Modules\BEMCLI\bemcli" # Import the Backup Exec Managment (BEM) Console Line Interface (CLI) (PowerShell plugin) $alertMessages = @() # Array for alert messages $services = Get-BEService | ? { $_.Status -ne "Running" } # Get Backup Exec services which is/are NOT running if (($services | measure).Count -ne 0) { # Count the total services of Backup Exec in the $services variable $alertMessages += "Service Not Running" # When there are more than 0 services NOT running, add an alert message } $jobs = get-bejob -JobType Backup | ?{$_.Status -eq "Scheduled" -or $_.Status -eq "Active"} | sort Name | Get-Unique -asstring | Select name Foreach ($job in $jobs){ Write-host "==============================================================" write-host $job.name $schedule = get-BEJob | ?{$_.Name -eq $job.name} | ?{$_.Status -eq "Scheduled" -or $_.Status -eq "Active"} | Select -Property "Schedule" Write-host "Schedule: $($schedule.schedule)" write-host "Yesterday: $yesterday" Write-host "==============================================================`n" If ($schedule.schedule -match $yesterday) { $Completed = get-bejobhistory -JobType Backup -JobStatus Completed | ?{$_.Name -eq $job.Name} -ErrorAction SilentlyContinue $Succeeded = get-bejobhistory -JobType Backup -JobStatus Succeeded | ?{$_.Name -eq $job.Name} -ErrorAction SilentlyContinue $SucceededWithExceptions = get-bejobhistory -JobType Backup -JobStatus SucceededWithExceptions | ?{$_.Name -eq $job.Name} -ErrorAction SilentlyContinue $Fout = get-bejobhistory -JobType Backup -JobStatus Error | ?{$_.Name -eq $job.Name} | ?{$_.EndTime -ge ((get-date).AddDays(-1))} -ErrorAction SilentlyContinue $Canceled = get-bejobhistory -JobType Backup -JobStatus Canceled | ?{$_.Name -eq $job.Name} | ?{$_.EndTime -ge ((get-date).AddDays(-1))} -ErrorAction SilentlyContinue $Missed = get-bejobhistory -JobType Backup -JobStatus Missed | ?{$_.Name -eq $job.Name} | ?{$_.EndTime -ge ((get-date).AddDays(-1))} -ErrorAction SilentlyContinue $SucceededBackup = @() # Array for failed backups because of errors when combined the same as succeeded jobs if ($Completed) { # If there are any backups failed with the status Error $SucceededBackup += $Completed # Add them to the array $failedBackup } if ($Succeeded) { # If there are any backups failed with the status Canceled $SucceededBackup += $Succeeded # Add them to the array $failedBackup } if ($SucceededWithExceptions) { # If there are any backups failed with the status Missed $SucceededBackup += $SucceededWithExceptions # Add them to the array $failedBackup } $SucceededBackup = $SucceededBackup | Sort-Object Endtime -descending | Select-Object -First 1 $failedBackup = @() # Array for failed backups because of errors when combined the same as succeeded jobs if ($Fout) { # If there are any backups failed with the status Error $failedBackup += $Fout # Add them to the array $failedBackup } if ($Canceled) { # If there are any backups failed with the status Canceled $failedBackup += $Canceled # Add them to the array $failedBackup } if ($Missed) { # If there are any backups failed with the status Missed $failedBackup += $Missed # Add them to the array $failedBackup } $failedBackup = $failedBackup | Sort-Object Endtime -descending | Select-Object -First 1 if ([Environment]::GetEnvironmentVariable("backupHours", "Process")) { # Check if the backup hours are defined in AEM via the environment variable $backupHours = [Environment]::GetEnvironmentVariable("backupHours", "Process") # Put these values into a variable } IF ($SucceededBackup){ if ($succeededBackup.EndTime.AddHours($backupHours) -le [DateTime]::Now) { $alertMessages += "No backup was done in $($backupHours) hours for $($job.name)" # Add an alert message if there has not been a backup job in the past 24h } } IF ($failedBackup){ if ($failedBackup.EndTime -ge $succeededBackup.EndTime) { # Comparison to check if there has been any error in the last backups $alertMessages += "Backup $($failedBackup) has errors" # Alert if there are any } } If (get-BEJob -status active | ?{$_.Name -eq $job.Name} | FL) { $Running = "$($job.Name) is still running" # Check if backup is still running $alertMessages += "Backup $($job.Name) is still running" # Add an alert message if still running } Write-host "--------------------------------------------------------------" Write-host "Succeeded Backups voor job $($job.name): " Write-host "--------------------------------------------------------------`n" write-host $SucceededBackup $SucceededBackup.endtime write-host "`n" Write-host "--------------------------------------------------------------" Write-host "Failed Backups voor job $($job.name): " Write-host "--------------------------------------------------------------`n" write-host $failedBackup $FailedBackup.endtime write-host "`n" Write-host "--------------------------------------------------------------" Write-host "Running Backups voor job $($job.name): " Write-host "--------------------------------------------------------------`n" write-host $Running write-host "`n" } Else { Write-host "The backup did not run yesterday because of the Schedule`n" } } return $alertMessages } Get-Service 'BackupExecManagementService' -ErrorAction Stop # Get the service BackupExecManagementService. If it doesn't exists, stop the script. It's mandetory to use the CLI param ([Int32]$backupHours=24) # Set backup hours to 24 as default $applications1 = Get-ItemProperty HKLM:\SOFTWARE\wow6432node\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion # Get version info of Backup Exec $applications2 = Get-ItemProperty HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\* | Select-Object DisplayName, DisplayVersion # Get version info of Backup Exec $bacupExecApp = $applications1 + $applications2 | ? { $_.DisplayName -like "Symantec Backup Exec (TM)*" -Or $_.DisplayName -like "Veritas Backup Exec (TM)*" } | ? { $_.DisplayVersion } | Select-Object -First 1 # Combine the 2 lists of application information. Select the first where de the display name is like Symantec Backup Exec (TM)* or Veritas Backup Exec (TM)*. $currentVersion = New-Object -TypeName Version -argumentList $bacupExecApp.DisplayVersion # Define the display version in a variable $backup2012Version = New-Object -TypeName Version -argumentList "14.0" # Define Backup 2012+ versions in a variable $backup16Version = New-Object -TypeName Version -argumentList "16.0" # Define Backup 2016 versions in a variable $alertMessages = @() # Array for alert messages $yesterday = @() $yesterday += ((get-date).AddDays(-1)).DayOfWeek IF($Yesterday -eq "Saturday") { $Yesterday += "Zaterdag" $yesterday = $yesterday -join " | " | Out-String } if (-not $bacupExecApp) { # Check if there is a Backup Exec application installed Write-Alert -Alert "Not Installed" # If not, use the Funtion Write-Alert to write an alert message to AEM } if ($currentVersion -like '14.*') { # Check if application version is like 14.* $alertMessages = Monitor-CLI # If it is, use the Function Monitor-CLI to monitor the backup jobs } elseif ($currentVersion -like '16.*') { # Check if application version is like 16.* $alertMessages = Monitor-CLI # If it is, use the Function Monitor-CLI to monitor the backup jobs } else { $alerts = Monitor-CMD # Else, use the Function Monitor-CMD to monitor the backup jobs $alertMessages = $alerts # Combine all alert messages } if ($alertMessages.Count -gt 0){ # Check if there are any alert messages $alert = $alertMessages -join " | " | Out-String # If so, join al alert messages in a specified format Write-Alert -Alert $alert # Use the Function Write-Alert to write an alert messages to AEM } write-host 'End of Script' # Write 'end of script' - at the end if there re no error messages - to the host exit 0; # Exit the script at the very end, if there are no error messages |