Skip to content

Instantly share code, notes, and snippets.

@liveaverage
Last active December 20, 2019 08:29
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save liveaverage/6324046 to your computer and use it in GitHub Desktop.
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…
$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"
}
}
@leopdurr
Copy link

leopdurr commented Jan 3, 2014

Hi nice script, Do I just copy this script to my checkMK/local folder? how can I apply this scipt?

Thanks

@stephenjirvine
Copy link

Hey:

I note you mention "OTE: Custom WMI and Component Service security is REQUIRED to get this working as expected."

Can you give some info as to what that is, check_mk_agent running as "NETWORK SERVICE" can;t run this script.

@liveaverage
Copy link
Author

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/

@liveaverage
Copy link
Author

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.

@JonWolberg
Copy link

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