Last active
December 20, 2019 08:29
-
-
Save liveaverage/6324046 to your computer and use it in GitHub Desktop.
Local Check_MK Powershell check that dynamically populates DFS Backlog Counts for all replicated folder groups. Outputs individual DFS backlog counts (one per replication direction) and performance data for individual replicated folder groups, along with a 'global' DFS Backlog count aggregating the status of all replication folder groups. The co…
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
$computer = [System.Net.Dns]::GetHostName() | |
$Computer = [System.Net.Dns]::GetHostName() | |
# Fix issue with console text wrap: | |
$Host.UI.RawUI.BufferSize = New-Object Management.Automation.Host.Size (500, 300) | |
$OK = 0 | |
$Warn = 1 | |
$Crit = 2 | |
$Unk = 3 | |
#Warning/Critical Backlog [File] Counts: | |
$w_count = 350 | |
$c_count = 700 | |
[string]$RGName = "" | |
[string]$RFName = "" | |
$DebugPreference = "SilentlyContinue" | |
$ErrorActionPreference = "SilentlyContinue" | |
#region DFSQuery | |
### These thresholds are irrelevant for the local Check_MK thresholds (native to Steve Grinker's script): | |
[int]$WarningThreshold = 50 | |
[int]$ErrorThreshold = 500 | |
Function PingCheck | |
{ | |
Param | |
( | |
[string]$Computer = "localhost", | |
[int]$timeout = 120 | |
) | |
Write-Debug $computer | |
Write-Debug $timeout | |
$Ping = New-Object System.Net.NetworkInformation.Ping | |
trap | |
{ | |
Write-Debug "The computer $computer could not be resolved." | |
continue | |
} | |
Write-Debug "Checking server: $computer" | |
$reply = $Ping.Send($computer,$timeout) | |
Write-Debug $reply | |
If ($reply.status -eq "Success") | |
{ | |
return $True | |
} else { | |
return $False | |
} | |
} | |
Function Check-WMINamespace ($computer, $namespace) | |
{ | |
$Namespaces = $Null | |
$Namespaces = Get-WmiObject -class __Namespace -namespace root -computername $computer | Where {$_.name -eq $namespace} | |
If ($Namespaces.Name -eq $Namespace) | |
{ | |
return $True | |
} else { | |
return $False | |
} | |
} | |
Function Get-DFSRGroup ($computer, $RGName) | |
{ | |
## Query DFSR groups from the MicrosftDFS WMI namespace. | |
If ($RGName -eq "") | |
{ | |
$WMIQuery = "SELECT * FROM DfsrReplicationGroupConfig" | |
} else { | |
$WMIQuery = "SELECT * FROM DfsrReplicationGroupConfig WHERE ReplicationGroupName='" + $RGName + "'" | |
} | |
$WMIObject = Get-WmiObject -computername $computer -Namespace "root\MicrosoftDfs" -Query $WMIQuery | |
return $WMIObject | |
} | |
Function Get-DFSRConnections ($computer) | |
{ | |
## Query DFSR connections from the MicrosftDFS WMI namespace. | |
$WMIQuery = "SELECT * FROM DfsrConnectionConfig" | |
$WMIObject = Get-WmiObject -computername $computer -Namespace "root\MicrosoftDfs" -Query $WMIQuery | |
return $WMIObject | |
} | |
Function Get-DFSRFolder ($computer, $RFname) | |
{ | |
## Query DFSR folders from the MicrosftDFS WMI namespace. | |
If ($RFName -eq "") | |
{ | |
$WMIQuery = "SELECT * FROM DfsrReplicatedFolderConfig" | |
} else { | |
$WMIQuery = "SELECT * FROM DfsrReplicatedFolderConfig WHERE ReplicatedFolderName='" + $RFName + "'" | |
} | |
$WMIObject = Get-WmiObject -computername $computer -Namespace "root\MicrosoftDfs" -Query $WMIQuery | |
return $WMIObject | |
} | |
Function Get-DFSRBacklogInfo ($Computer, $RGroups, $RFolders, $RConnections) | |
{ | |
$objSet = @() | |
Foreach ($Group in $RGroups) | |
{ | |
$ReplicationGroupName = $Group.ReplicationGroupName | |
$ReplicationGroupGUID = $Group.ReplicationGroupGUID | |
Foreach ($Folder in $RFolders) | |
{ | |
If ($Folder.ReplicationGroupGUID -eq $ReplicationGroupGUID) | |
{ | |
$ReplicatedFolderName = $Folder.ReplicatedFolderName | |
$FolderEnabled = $Folder.Enabled | |
Foreach ($Connection in $Rconnections) | |
{ | |
If ($Connection.ReplicationGroupGUID -eq $ReplicationGroupGUID) | |
{ | |
$ConnectionEnabled = $Connection.Enabled | |
$BacklogCount = $Null | |
If ($FolderEnabled) | |
{ | |
If ($ConnectionEnabled) | |
{ | |
If ($Connection.Inbound) | |
{ | |
Write-Debug "Connection Is Inbound" | |
$Smem = $Connection.PartnerName.Trim() | |
Write-Debug $smem | |
$Rmem = $Computer.ToUpper() | |
Write-Debug $Rmem | |
#Get the version vector of the inbound partner | |
$WMIQuery = "SELECT * FROM DfsrReplicatedFolderInfo WHERE ReplicationGroupGUID = '" + $ReplicationGroupGUID + "' AND ReplicatedFolderName = '" + $ReplicatedFolderName + "'" | |
$InboundPartnerWMI = Get-WmiObject -computername $Rmem -Namespace "root\MicrosoftDfs" -Query $WMIQuery | |
$WMIQuery = "SELECT * FROM DfsrReplicatedFolderConfig WHERE ReplicationGroupGUID = '" + $ReplicationGroupGUID + "' AND ReplicatedFolderName = '" + $ReplicatedFolderName + "'" | |
$PartnerFolderEnabledWMI = Get-WmiObject -computername $Smem -Namespace "root\MicrosoftDfs" -Query $WMIQuery | |
$PartnerFolderEnabled = $PartnerFolderEnabledWMI.Enabled | |
If ($PartnerFolderEnabled) | |
{ | |
$Vv = $InboundPartnerWMI.GetVersionVector().VersionVector | |
#Get the backlogcount from outbound partner | |
$WMIQuery = "SELECT * FROM DfsrReplicatedFolderInfo WHERE ReplicationGroupGUID = '" + $ReplicationGroupGUID + "' AND ReplicatedFolderName = '" + $ReplicatedFolderName + "'" | |
$OutboundPartnerWMI = Get-WmiObject -computername $Smem -Namespace "root\MicrosoftDfs" -Query $WMIQuery | |
$BacklogCount = $OutboundPartnerWMI.GetOutboundBacklogFileCount($Vv).BacklogFileCount | |
} | |
} else { | |
Write-Debug "Connection Is Outbound" | |
$Smem = $Computer.ToUpper() | |
Write-Debug $smem | |
$Rmem = $Connection.PartnerName.Trim() | |
Write-Debug $Rmem | |
#Get the version vector of the inbound partner | |
Write-Debug $WMIQuery | |
$WMIQuery = "SELECT * FROM DfsrReplicatedFolderInfo WHERE ReplicationGroupGUID = '" + $ReplicationGroupGUID + "' AND ReplicatedFolderName = '" + $ReplicatedFolderName + "'" | |
$InboundPartnerWMI = Get-WmiObject -computername $Rmem -Namespace "root\MicrosoftDfs" -Query $WMIQuery | |
$WMIQuery = "SELECT * FROM DfsrReplicatedFolderConfig WHERE ReplicationGroupGUID = '" + $ReplicationGroupGUID + "' AND ReplicatedFolderName = '" + $ReplicatedFolderName + "'" | |
$PartnerFolderEnabledWMI = Get-WmiObject -computername $Rmem -Namespace "root\MicrosoftDfs" -Query $WMIQuery | |
$PartnerFolderEnabled = $PartnerFolderEnabledWMI.Enabled | |
If ($PartnerFolderEnabled) | |
{ | |
$Vv = $InboundPartnerWMI.GetVersionVector().VersionVector | |
#Get the backlogcount from outbound partner | |
$WMIQuery = "SELECT * FROM DfsrReplicatedFolderInfo WHERE ReplicationGroupGUID = '" + $ReplicationGroupGUID + "' AND ReplicatedFolderName = '" + $ReplicatedFolderName + "'" | |
$OutboundPartnerWMI = Get-WmiObject -computername $Smem -Namespace "root\MicrosoftDfs" -Query $WMIQuery | |
$BacklogCount = $OutboundPartnerWMI.GetOutboundBacklogFileCount($Vv).BacklogFileCount | |
} | |
} | |
} | |
} | |
$obj = New-Object PSObject -Property @{ | |
ReplicationGroupName = $ReplicationGroupName; | |
ReplicatedFolderName = $ReplicatedFolderName; | |
SendingMember = $Smem; | |
ReceivingMember = $Rmem; | |
BacklogCount = $BacklogCount; | |
FolderEnabled = $FolderEnabled; | |
ConnectionEnabled = $ConnectionEnabled; | |
Inbound = $Connection.Inbound; | |
BacklogStatus = ''; | |
} | |
# Add-Member -InputObject $obj -Membertype NoteProperty -Name ReplicationGroupName -Value $ReplicationGroupName -Force | |
# write-debug $ReplicationGroupName | |
# | |
# Add-Member -InputObject $obj -Membertype NoteProperty -Name ReplicatedFolderName -Value $ReplicatedFolderName -Force | |
# write-debug $ReplicatedFolderName | |
# | |
# Add-Member -InputObject $obj -Membertype NoteProperty -Name SendingMember -Value $Smem -Force | |
# write-debug $Smem | |
# | |
# Add-Member -InputObject $obj -Membertype NoteProperty -Name ReceivingMember -Value $Rmem -Force | |
# write-debug $Rmem | |
# | |
# Add-Member -InputObject $obj -Membertype NoteProperty -Name BacklogCount -Value $BacklogCount -Force | |
# write-debug $BacklogCount | |
# | |
# Add-Member -InputObject $obj -Membertype NoteProperty -Name FolderEnabled -Value $FolderEnabled -Force | |
# write-debug $FolderEnabled | |
# | |
# Add-Member -InputObject $obj -Membertype NoteProperty -Name ConnectionEnabled -Value $ConnectionEnabled -Force | |
# write-debug $ConnectionEnabled | |
# | |
# Add-Member -InputObject $obj -Membertype NoteProperty -Name Inbound -Value $Connection.Inbound -Force | |
# write-debug $Connection.Inbound | |
If ($BacklogCount -ne $Null) | |
{ | |
If ($BacklogCount -lt $WarningThreshold) | |
{ | |
$Backlogstatus = "Low" | |
} | |
elseif (($BacklogCount -ge $WarningThreshold) -and ($BacklogCount -lt $ErrorThreshold)) | |
{ | |
$Backlogstatus = "Warning" | |
} | |
elseif ($BacklogCount -ge $ErrorThreshold) | |
{ | |
$Backlogstatus = "Error" | |
} | |
} else { | |
$Backlogstatus = "Disabled" | |
} | |
#Add-Member -InputObject $obj -Membertype NoteProperty -Name BacklogStatus -Value $BacklogStatus -Force | |
$obj.Backlogstatus = $Backlogstatus | |
$global:list += $obj | |
$objSet += $obj | |
$obj = $null | |
} | |
} | |
} | |
} | |
} | |
return $objSet | |
} | |
Write-Debug "Computer = $Computer" | |
Write-Debug "RFName = $RFName" | |
Write-Debug "RGName = $RGName" | |
Write-Debug "WarningThreshold = $WarningThreshold" | |
Write-Debug "ErrorThreshold = $ErrorThreshold" | |
$Pingable = PingCheck $computer | |
If ($Pingable) | |
{ | |
$NamespaceExists = Check-WMINamespace $computer "MicrosoftDfs" | |
If ($NamespaceExists) | |
{ | |
Write-Debug "Collecting RGroups from $computer" | |
$RGroups = Get-DFSRGroup $computer $RGName | |
Write-Debug "Rgroups = $Rgroups" | |
Write-Debug "Collecting RFolders from $computer" | |
$RFolders = Get-DFSRFolder $computer $RFName | |
Write-Debug "RFolders = $RFolders" | |
Write-Debug "Collecting RConnections from $computer" | |
$RConnections = Get-DFSRConnections $computer | |
Write-Debug "RConnections = $RConnections" | |
Write-Debug "Calculating Backlog from $computer" | |
$BacklogInfo = Get-DFSRBacklogInfo $Computer $RGroups $RFolders $RConnections | |
#Write-Output $BacklogInfo | |
} else { | |
Write-Error "MicrosoftDfs WMI Namespace does not exist on '$computer'. Run locally on a system with the Namespace, or provide computer parameter of that system to run remotely." | |
} | |
} else { | |
Write-Error "The computer '$computer' did not respond to ping." | |
} | |
#endregion | |
#Debug: | |
#echo "Backlog count: $($BacklogInfo.count); $($BacklogInfo.GetType())" | |
#echo "Backlog count: $($dfsbacklog.count); $($dfsbacklog.GetType())" | |
if (($BacklogInfo.count -le 0) -or ($BacklogInfo -eq $null)) | |
{ | |
echo "$Unk DFSRBacklog - Unknown - DFSRBacklog could not enumerate Backlog counts" | |
} | |
else | |
{ | |
$statustxt = "" | |
$retw = 0 | |
$retc = 0 | |
$reto = 0 | |
foreach ($share in $BacklogInfo) | |
{ | |
#Remove spaces from folder name (Causes issues with Check_MK): | |
$name = ($share.ReplicatedFolderName) -replace '\s+','_' | |
$name += "_$($share.SendingMember)" | |
# Sometimes the WMI queries return an array of ints; select unique ones and convert to int (should be identical integers) | |
if($share.BacklogCount -isnot [int]) | |
{ | |
$share.BacklogCount = [int]($share.BacklogCount | Sort-Object | Get-Unique -asstring) | |
} | |
if (($share.BacklogCount -lt $w_count) -and ($share.BacklogCount -lt $c_count)) | |
{ | |
echo `<`<`<local`>`>`> | |
echo "$Ok DFSRBacklog_$name - OK - Count: $($share.BacklogCount) $($share.SendingMember)->$($share.ReceivingMember) " | |
continue; | |
} | |
elseif ($share.BacklogCount -ge $w_count -and $share.BacklogCount -lt $c_count) | |
{ | |
echo `<`<`<local`>`>`> | |
echo "$Warn DFSRBacklog_$name - WARN - Count: $($share.BacklogCount) $($share.SendingMember)->$($share.ReceivingMember) " | |
$statustxt += "[$($share.ReplicatedFolderName)] Count: $($share.BacklogCount) $($share.SendingMember)->$($share.ReceivingMember), " | |
$retw += 1 | |
} | |
elseif ($share.BacklogCount -ge $c_count) | |
{ | |
echo `<`<`<local`>`>`> | |
echo "$Crit DFSRBacklog_$name - CRIT - Count: $($share.BacklogCount) $($share.SendingMember)->$($share.ReceivingMember) " | |
$statustxt += "[$name] Count: $($share.BacklogCount) $($share.SendingMember)->$($share.ReceivingMember), " | |
$retc += 1 | |
} | |
else | |
{ | |
echo `<`<`<local`>`>`> | |
echo "$Unk DFSRBacklog_$name - UNKNOWN - Count: $($share.BacklogCount) $($share.SendingMember)->$($share.ReceivingMember) " | |
$statustxt += "[$name] Count: $($share.BacklogCount) $($share.SendingMember)->$($share.ReceivingMember), " | |
} | |
$name = $null | |
} | |
#GLOBAL DFS Status (Checks Shares when inventory hasn't been updated) | |
echo `<`<`<local`>`>`> | |
if ($retw -eq 0 -and $retc -eq 0) | |
{ | |
echo "$Ok Global_DFSRBacklog - Ok - All Shares OK" | |
} | |
elseif ($retw -ne 0 -and $retc -eq 0) | |
{ | |
echo "$Warn Global_DFSRBacklog - Warning - $statustxt" | |
} | |
elseif ($retc -ne 0) | |
{ | |
echo "$Crit Global_DFSRBacklog - Critical - $statustxt" | |
} | |
} |
You're correct that the default SYSTEM or NETWORK SERVICE accounts cannot execute the script; you have to explicitly define a "Log On As" user account for the check_mk_agent service. This account also needs to have the permissions outlined here:
http://liveaverage.com/news/check_mk-dfs-backlog-monitoring/
Please let me know if you have any other questions or problems.
I have the script working just fine in my environment. Is there a way to graph out the queue?
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Sorry for the delays on a response. Here's a full write-up on the requirements for WMI and Component Service security:
http://liveaverage.com/news/check_mk-dfs-backlog-monitoring/