param([string]$tsmFile)
#--------------------------------------------------------------------------------------------------#
Function Get-TSMInformation {
$tsmInformation = @()
$schedulerServices = "HKLM:\SOFTWARE\IBM\ADSM\CurrentVersion\BackupClient\Scheduler Service"
$windowsServivces = "HKLM:\SYSTEM\CurrentControlSet\Services"
if(Test-Path -path $schedulerServices) {
$tsmServices = @(Get-Item $schedulerServices | ForEach-Object { $_.Property })
foreach($windowsService in Get-ChildItem $windowsServivces) {
if($tsmServices -contains (Split-Path -leaf $windowsService.Name)) {
$tsmServiceName = (Split-Path -leaf $windowsService.Name)
$tsmServiceSubKey = Get-Item ($windowsServivces + "\" + (Split-Path -leaf $windowsService.Name))
$startValue = $tsmServiceSubKey.GetValue("Start")
$clientNodeName = ($tsmServiceSubKey.OpenSubKey("Parameters")).GetValue("clientNodeName")
$scheduleLog = ($tsmServiceSubKey.OpenSubKey("Parameters")).GetValue("scheduleLog")
$currentStatus = (Get-Service -name $tsmServiceName).Status
$clientNodeInformation = New-Object -typeName PSObject
Add-Member -inputObject $clientNodeInformation -type NoteProperty -name "tsmServiceName" -value $tsmServiceName
Add-Member -inputObject $clientNodeInformation -type NoteProperty -name "startValue" -value $startValue
Add-Member -inputObject $clientNodeInformation -type NoteProperty -name "clientNodeName" -value $clientNodeName
Add-Member -inputObject $clientNodeInformation -type NoteProperty -name "scheduleLog" -value $scheduleLog
Add-Member -inputObject $clientNodeInformation -type NoteProperty -name "status" -value $currentStatus
$tsmInformation += $clientNodeInformation
}
}
}
return $tsmInformation
}
#--------------------------------------------------------------------------------------------------#
Function Read-EndOfFileByByteChunk($fileName,$totalNumberOfLines,$byteChunk) {
if($totalNumberOfLines -lt 1) { $totalNumberOfLines = 1 }
if($byteChunk -le 0) { $byteChunk = 10240 }
$linesOfText = New-Object System.Collections.ArrayList
if([System.IO.File]::Exists($fileName)) {
$fileStream = New-Object System.IO.FileStream($fileName,[System.IO.FileMode]::Open,[System.IO.FileAccess]::Read,[System.IO.FileShare]::ReadWrite)
$asciiEncoding = New-Object System.Text.ASCIIEncoding
$fileSize = $fileStream.Length
$byteOffset = $byteChunk
[byte[]] $bytesRead = New-Object byte[] $byteChunk
$totalBytesProcessed = 0
$lastReadAttempt = $false
do {
if($byteOffset -ge $fileSize) {
$byteChunk = $fileSize - $totalBytesProcessed
[byte[]] $bytesRead = New-Object byte[] $byteChunk
$byteOffset = $fileSize
$lastReadAttempt = $true
}
$fileStream.Seek((-$byteOffset), [System.IO.SeekOrigin]::End) | Out-Null
$fileStream.Read($bytesRead, 0, $byteChunk) | Out-Null
$chunkOfText = New-Object System.Collections.ArrayList
$chunkOfText.AddRange(([System.Text.RegularExpressions.Regex]::Split($asciiEncoding.GetString($bytesRead),"\r\n")))
$firstLineLength = ($chunkOfText[0].Length)
$byteOffset = ($byteOffset + $byteChunk) - ($firstLineLength)
if($lastReadAttempt -eq $false -and $chunkOfText.count -lt $totalNumberOfLines) {
$chunkOfText.RemoveAt(0)
}
$totalBytesProcessed += ($byteChunk - $firstLineLength)
$linesOfText.InsertRange(0, $chunkOfText)
} while($totalNumberOfLines -ge $linesOfText.count -and $lastReadAttempt -eq $false -and $totalBytesProcessed -lt $fileSize)
$fileStream.Close()
if($linesOfText.count -gt 1) {
$linesOfText.RemoveAt($linesOfText.count-1)
}
$deltaLines = ($linesOfText.count - $totalNumberOfLines)
if($deltaLines -gt 0) {
$linesOfText.RemoveRange(0, $deltaLines)
}
} else {
$linesOfText.Add("[ERROR] $fileName not found") | Out-Null
}
return $linesOfText
}
#--------------------------------------------------------------------------------------------------#
Set-Variable -name returnNormal -option Constant -value 0
Set-Variable -name returnWarning -option Constant -value 1
Set-Variable -name returnError -option Constant -value 2
Set-Variable -name returnUnknown -option Constant -value 3
Set-Variable -name computerFqdn -option Constant -value (([System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties()).HostName + "." + ([System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties()).DomainName)
Set-Variable -name backupWindow -option Constant -value 24 # in Hours
Set-Variable -name deafService -option Constant -value 36 # in Hours
Set-Variable -name enableRestarts -option Constant -value $true # Allow check to restart TSM if the service
Set-Variable -name lookBack -option Constant -value 250 # Number of lines to tail
Set-Variable -name maximumFailures -option Constant -value 5 # Your tolerance for failed files
Set-Variable -name successfulBackup -value $false
Set-Variable -name todaysBackupFound -value $false
Set-Variable -name backupStillRunning -value $false
Set-Variable -name completionTime -value $null
Set-Variable -name totalFailed -value 0
Set-Variable -name logEntries -value @()
Set-Variable -name exitMessage -value "Massive Script Failure"
Set-Variable -name exitValue -value $returnError
#--------------------------------------------------------------------------------------------------#
if($tsmFile -eq "$" -or (!$tsmFile)) {
$tsmInfo = @(Get-TSMInformation)
foreach($tsmInstance in $tsmInfo) {
if($tsmInstance.scheduleLog -match "\\dsmsched.log") {
$tsmLogFile = $tsmInstance.scheduleLog
break
}
}
} else {
$tsmLogFile = ($env:programfiles + "\Tivoli\TSM\baclient\$tsmFile")
}
if(Test-Path -path $tsmLogFile) {
$logEntries = Read-EndOfFileByByteChunk $tsmLogFile $lookBack 1280
foreach($logEntry in $logEntries) {
if($logEntry.Length -ge 19) {
$dateTest = $logEntry.SubString(0,19) -as [DateTime]
if($dateTest) {
if(((Get-Date) - (Get-Date $logEntry.SubString(0,19))).TotalHours -le $backupWindow) {
if($logEntry -match "Scheduled event '(.*?)' completed successfully.") {
$successfulBackup = $true
$completionTime = Get-Date $logEntry.SubString(0,19)
}
if($logEntry -match "Total number of objects failed:") {
[int]$totalFailed = ($logEntry -Replace "(.*)Total number of objects failed:", "").Trim()
}
$todaysBackupFound = $true
}
$lastLine = $logEntry
}
}
}
if($successfulBackup -eq $false -and $todaysBackupFound -eq $true) {
$lastLogTime = ((Get-Date) - (Get-Date $lastLine.SubString(0,19))).TotalMinutes
if($lastLogTime -le 15) {
$backupStillRunning = $true
}
}
if($todaysBackupFound -eq $false) {
if(((Get-Date) - (Get-Date $lastLine.SubString(0,19))).TotalHours -ge $deafService) {
$tsmInformation = @(Get-TSMInformation)
if($tsmInformation.Count -gt 0) {
foreach($tsmInstance in $tsmInformation) {
if($tsmInstance.scheduleLog -eq $tsmLogFile) {
if($tsmInstance.status -eq "Running") {
Restart-Service -name $tsmInstance.tsmServiceName
$exitMessage = ("TSM Scheduler `"" + $tsmInstance.tsmServiceName + "`" has not contacted the TSM server in $deafService hours. Restarting service.")
} else {
Start-Service -name $tsmInstance.tsmServiceName
$exitMessage = ("TSM Scheduler `"" + $tsmInstance.tsmServiceName + "`" was stopped and hasn't contacted the TSM server in $deafService hours. Starting service.")
}
$exitValue = $returnError
break
}
}
} else {
$exitMessage = ("Unable to determine which service is associated to $tsmLogFile")
$exitValue = $returnError
}
} else {
$exitMessage = ("Unable to find data in the last $backupWindow hours in $tsmLogFile. Last Backup log date: " + (Get-Date $lastLine.SubString(0,19)))
$exitValue = $returnError
}
} elseif($totalFailed -gt $maximumFailures) {
$exitMessage = "Backup completed with $totalFailed failed objects."
$exitValue = $returnWarning
} elseif($successfulBackup -eq $true) {
$exitMessage = "Backup completed successfully: $completionTime"
$exitValue = $returnNormal
} elseif($backupStillRunning -eq $true) {
$exitMessage = ("Backup still running! Please allow to complete. Current status: " + $lastLine -Replace "\\","/")
$exitValue = $returnWarning
} else {
$exitMessage = ("Unable to find a successful backup. Last status: " + $lastLine -Replace "\\","/")
$exitValue = $returnError
}
Write-Host $exitMessage
$Host.SetShouldExit($exitValue)
Showing posts with label Service. Show all posts
Showing posts with label Service. Show all posts
Friday, August 12, 2011
Nagios Check for Scheduled TSM Backups (Updated)
I have cleaned the code from my previous post, Nagios Check for Scheduled TSM Backups, that included some superfluous code derived from my post, Audit Tivoli Storage Manager Backup Client Schedules on Windows Servers. The updated code is more efficient and returns service status faster in the event of an extended period of "deafness" between the client and the TSM server and subsequent restart of the TSM service.
Labels:
Backup,
PowerShell,
Registry,
Service,
TSM
Wednesday, May 18, 2011
Correct Order to Start and Stop BlackBerry Enterprise Server Services Using PowerShell
A common activity I perform after patching Exchange Servers and Domain Controllers is to restart BlackBerry services on client BlackBerry servers. Failure to do so can lead to issues for BlackBerry users such as failed delivery, lookup failures and inability to send. RIM recommends a specific order for these services to be stopped and started. Since patching occurs typically occurs in the dead of night to avoid impacting end users, you want to get things done quickly but accurately so you can get some sleep. In the code samples below, I take advantage of Get-Service, Stop-Service and Start-Service to execute the correct order of the process. I store the required service order in an array and take advantage of the natural looping order of elements in "foreach" to manipulate the services. The remaining services are discovered by obtaining all services with the name BlackBerry and filtering out the services that required a specific order for stopping and starting. If there are any issues with stopping or stopping the services, the code immediately exits so you can take manual intervention, research and resolve the problem.
Stopping BlackBerry Services:
Stopping BlackBerry Services:
#--------------------------------------------------------------------------------------------------#
Set-Variable -name selectedServices -option Constant -value @("BlackBerry Controller","BlackBerry Dispatcher","BlackBerry Router")
#--------------------------------------------------------------------------------------------------#
foreach($selectedService in $selectedServices) {
if((Get-Service -Name $selectedService).Status -ne "Stopped") {
Write-Output "Stopping $selectedService..."
Stop-Service -Name $selectedService
if((Get-Service -Name $selectedService).Status -ne "Stopped") {
Write-Output "$selectedService failed to stop. Exiting..."
exit
} else {
Write-Output "$selectedService successfully stopped."
}
} else {
Write-Output "$selectedService already stopped!"
}
}
foreach($blackberryService in (Get-Service -Name Blackberry*)) {
if($selectedServices -notcontains $blackberryService.Name) {
if($blackberryService.Status -ne "Stopped") {
Write-Output ("Stopping " + $blackberryService.Name + "...")
Stop-Service -Name $blackberryService.Name
if((Get-Service -Name $blackberryService.Name).Status -ne "Stopped") {
Write-Output ($blackberryService.Name + " failed to stop. Exiting...")
exit
} else {
Write-Output ($blackberryService.Name + " successfully stopped.")
}
} else {
Write-Output ($blackberryService.Name + " already stopped!")
}
}
}Starting BlackBerry Services: #--------------------------------------------------------------------------------------------------#
Set-Variable -name selectedServices -option Constant -value @("BlackBerry Router","BlackBerry Dispatcher","BlackBerry Controller")
#--------------------------------------------------------------------------------------------------#
foreach($selectedService in $selectedServices) {
if((Get-Service -Name $selectedService).Status -ne "Running") {
Write-Output "Starting $selectedService..."
Start-Service -Name $selectedService
if((Get-Service -Name $selectedService).Status -ne "Running") {
Write-Output "$selectedService failed to start. Exiting..."
exit
} else {
Write-Output "$selectedService successfully started."
}
} else {
Write-Output "$selectedService already running!"
}
}
foreach($blackberryService in (Get-Service -Name Blackberry*)) {
if($selectedServices -notcontains $blackberryService.Name) {
if($blackberryService.Status -ne "Running") {
Write-Output ("Starting " + $blackberryService.Name + "...")
Start-Service -Name $blackberryService.Name
if((Get-Service -Name $blackberryService.Name).Status -ne "Running") {
Write-Output ($blackberryService.Name + " failed to start. Exiting...")
exit
} else {
Write-Output ($blackberryService.Name + " successfully started.")
}
} else {
Write-Output ($blackberryService.Name + " already running!")
}
}
}
Labels:
BlackBerry,
PowerShell,
RIM,
Service
Subscribe to:
Posts (Atom)