Active Directory health check – DCDIAG friendly view

We can monitor all Domain Controllers events using different monitoring tools like System Center Operation Manager or any other tools from any other 3rd parties. But how about automating a health check of a domain controller and instead of having a text document with all the information inside where we need to look after  errors and warning we can create a user friendly table easy to read and interpret. We just need somehow to run a DCDIAG and then parse the output using Regex and display it.

DCDIAG is as an end-user reporting program, a command-line tool that encapsulates detailed knowledge of how to identify abnormal behavior in the system. Dcdiag displays command output at the command prompt.

What we need now is to create a Powershell function that takes the output from dcdiag, analyze the output and then present it in a easy readable format.

The function will be:

Function Test-ADInfrastructure {
    
	Param (
		[Parameter(Mandatory=$true)]
        $domain,                                       # Domain

        [Parameter(Mandatory=$false)]
        [string]$namingconvention = "*",                # Server naming convention

        [Parameter(Mandatory=$false)]
        $tmpFile = [System.Io.Path]::GetTempFileName(),  # temp file
        
        [String]$OutputFile
	)
	
    # run dcdiag and get the output

    dcdiag.exe /e /n:$domain | Out-File $tmpFile

    $dcDiagOutput = Get-Content $tmpFile
    Copy-Item $tmpFile $outputFile
    Remove-Item $tmpFile


    $regex = "\.{25}\s(.*?)\s(passed|failed)\stest\s(.*?)$"

    # Obtain am array with elements
    # of type @{Server, Test, Passed}
    $testResults = @()
    $dcDiagOutput | Foreach-Object {

    	if ( $_ -match $regex) {
    		#$matches
    		
    		$testResults += New-Object PSObject -Property @{
    			'Server' = $matches[1] -as [String];
    			'Test' = $matches[3] -as [String];
    			'Passed' = ($matches[2] -eq 'passed')
    		} | Select Server,Test,Passed
    	}
    }
    # group elements by Server
    $dcDiagTmp = $testResults | Where { $_.Server -like $namingconvention } | Group-Object -Property Server -AsHashTable


    # return elements of type
    # @{Server, TestName1, TestName2, FrsEvent, ... , VerifyReferences}
    #
    # e.g.
    #
    #   Server             : SRV-DC-01
    #   Connectivity       : True
    #   Advertising        : True
    #   FrsEvent           : True
    #   DFSREvent          : True
    #   SysVolCheck        : True
    #   KccEvent           : True
    #   KnowsOfRoleHolders : True
    #   MachineAccount     : True
    #   NCSecDesc          : True
    #   NetLogons          : True
    #   ObjectsReplicated  : True
    #   Replications       : True
    #   RidManager         : True
    #   Services           : False
    #   SystemLog          : True
    #   VerifyReferences   : True
    #
    foreach ($server in $dcDiagTmp.Keys) {
    	
    	$tmp = New-Object PSObject -Property @{'Server' = $server} 

    	$dcDiagTmp.$($server) | Foreach-Object {
    		$tmp | Add-Member NoteProperty -Name $($_.Test) -Value $($_.Passed)
    	}
    	
    	Write-Output $tmp
    }
}

There is just one mandatory parameter which is -domain. Also this function has other non-mandatory parameters like: -namingconvention and -tmpfile. Domain was set as mandatory parameter in order to be able to run this function on multiple domains in one go. We can set it as Mandatory=$false and replace the null value with $env:userdomain. This variable will pick up the domain from where you run the command.

In order to have a easy readable output I’ve used a regex syntax, Regex stands for regular expression.

$regex = "\.{25}\s(.*?)\s(passed|failed)\stest\s(.*?)$"

All about Regular expresion can be found here:https://en.wikipedia.org/wiki/Regular_expression

For all the servers we will get an output like:

# return elements of type
    # @{Server, TestName1, TestName2, FrsEvent, ... , VerifyReferences}
    #
    # e.g.
    #
    #   Server             : SRV-DC-01
    #   Connectivity       : True
    #   Advertising        : True
    #   FrsEvent           : True
    #   DFSREvent          : True
    #   SysVolCheck        : True
    #   KccEvent           : True
    #   KnowsOfRoleHolders : True
    #   MachineAccount     : True
    #   NCSecDesc          : True
    #   NetLogons          : True
    #   ObjectsReplicated  : True
    #   Replications       : True
    #   RidManager         : True
    #   Services           : False
    #   SystemLog          : True
    #   VerifyReferences   : True
    #

Based on the above output we can create a table and read it easily. Also we can colour the output so in case some test failed we can spot it quickly.

dcdiag2

Leave a Reply

Your email address will not be published. Required fields are marked *