-
-
Save AlexAsplund/c98bd06484d87a6e67a4250a182f1f49 to your computer and use it in GitHub Desktop.
| Class AdhcResult { | |
| [string]$Source | |
| [string]$TestName | |
| [bool]$Pass | |
| $Was | |
| $ShouldBe | |
| [string]$Category | |
| [string]$Message | |
| $Data | |
| [string[]]$Tags | |
| } | |
| Function New-AdhcResult { | |
| [cmdletbinding()] | |
| param( | |
| # Source of the result. The computer that was tested | |
| [parameter(ValueFromPipelineByPropertyName)] | |
| [string]$Source = $env:COMPUTERNAME, | |
| # Name of the test | |
| [parameter(Mandatory,ValueFromPipelineByPropertyName)] | |
| [string]$TestName, | |
| # True = Test pass | |
| [parameter(Mandatory,ValueFromPipelineByPropertyName)] | |
| [bool]$Pass, | |
| [parameter(ValueFromPipelineByPropertyName)] | |
| $Was, | |
| [parameter(ValueFromPipelineByPropertyName)] | |
| $ShouldBe, | |
| # General category of the test. Like "Directory Services" or "DNS" | |
| [parameter(Mandatory,ValueFromPipelineByPropertyName)] | |
| [string]$Category, | |
| # A more specific subcategory like "FSMO" or "DNS Forwarding" | |
| [parameter(ValueFromPipelineByPropertyName)] | |
| [string]$SubCategory, | |
| # Tags for this test like "Security", "Updates", "Logon" | |
| [parameter(Mandatory,ValueFromPipelineByPropertyName)] | |
| [string[]]$Tags, | |
| # General message | |
| [parameter(ValueFromPipelineByPropertyName)] | |
| [string]$Message, | |
| # Extra data to the test result. Like accountnames or SPN's etc. | |
| [parameter(ValueFromPipelineByPropertyName)] | |
| $Data | |
| ) | |
| Begin { | |
| } | |
| Process { | |
| [AdhcResult]@{ | |
| Source = $Source | |
| TestName = $TestName | |
| Pass = $Pass | |
| Was = $Was | |
| ShouldBe = $ShouldBe | |
| Category = $Category | |
| SubCategory = $SubCategory | |
| Message = $Message | |
| Data = $Data | |
| Tags = $Tags | |
| } | |
| } | |
| End { | |
| } | |
| } | |
| Function Test-AdhcDCDiag { | |
| [cmdletbinding()] | |
| param( | |
| # Name of the DC | |
| [parameter(ValueFromPipeline)] | |
| [string]$ComputerName, | |
| # What DCDiag tests would you like to run? | |
| [ValidateSet( | |
| "All", | |
| "Advertising", | |
| "DNS", | |
| "NCSecDesc", | |
| "KccEvent", | |
| "Services", | |
| "NetLogons", | |
| "CrossRefValidation", | |
| "CutoffServers", | |
| "CheckSecurityError", | |
| "Intersite", | |
| "CheckSDRefDom", | |
| "Connectivity", | |
| "SysVolCheck", | |
| "Replications", | |
| "ObjectsReplicated", | |
| "DcPromo", | |
| "RidManager", | |
| "Topology", | |
| "MachineAccount", | |
| "LocatorCheck", | |
| "OutboundSecureChannels", | |
| "RegisterInDNS", | |
| "VerifyEnterpriseReferences", | |
| "KnowsOfRoleHolders", | |
| "VerifyReplicas", | |
| "VerifyReferences" | |
| )] | |
| [string[]]$Tests = "All", | |
| # Excluded tests | |
| [ValidateSet( | |
| "Advertising", | |
| "DNS", | |
| "NCSecDesc", | |
| "KccEvent", | |
| "Services", | |
| "NetLogons", | |
| "CrossRefValidation", | |
| "CutoffServers", | |
| "CheckSecurityError", | |
| "Intersite", | |
| "CheckSDRefDom", | |
| "Connectivity", | |
| "SysVolCheck", | |
| "Replications", | |
| "ObjectsReplicated", | |
| "DcPromo", | |
| "RidManager", | |
| "Topology", | |
| "MachineAccount", | |
| "LocatorCheck", | |
| "OutboundSecureChannels", | |
| "RegisterInDNS", | |
| "VerifyEnterpriseReferences", | |
| "KnowsOfRoleHolders", | |
| "VerifyReplicas", | |
| "VerifyReferences" | |
| )] | |
| [string[]]$ExcludedTests | |
| ) | |
| Begin { | |
| $DCDiagTests = @{ | |
| Advertising = @{} | |
| CheckSDRefDom = @{} | |
| CheckSecurityError = @{ | |
| ExtraArgs = @( | |
| "/replsource:$((Get-ADDomainController -Filter *).HostName | ? {$_ -notmatch $env:computername} | Get-Random)" | |
| ) | |
| } | |
| Connectivity = @{} | |
| CrossRefValidation = @{} | |
| CutoffServers = @{} | |
| DcPromo = @{ | |
| ExtraArgs = @( | |
| "/ReplicaDC", | |
| "/DnsDomain:$((Get-ADDomain).DNSRoot)", | |
| "/ForestRoot:$((Get-ADDomain).Forest)" | |
| ) | |
| } | |
| DNS = @{} | |
| SysVolCheck = @{} | |
| LocatorCheck = @{} | |
| Intersite = @{} | |
| KccEvent = @{} | |
| KnowsOfRoleHolders = @{} | |
| MachineAccount = @{} | |
| NCSecDesc = @{} | |
| NetLogons = @{} | |
| ObjectsReplicated = @{} | |
| OutboundSecureChannels = @{} | |
| RegisterInDNS = @{ | |
| ExtraArgs = "/DnsDomain:$((Get-ADDomain).DNSRoot)" | |
| } | |
| Replications = @{} | |
| RidManager = @{} | |
| Services = @{} | |
| Topology = @{} | |
| VerifyEnterpriseReferences = @{} | |
| VerifyReferences = @{} | |
| VerifyReplicas = @{} | |
| } | |
| $TestsToRun = $DCDiagTests.Keys | Where-Object {$_ -notin $ExcludedTests} | |
| If($Tests -ne 'All'){ | |
| $TestsToRun = $Tests | |
| } | |
| if(($Tests | Measure-Object).Count -gt 1 -and $Tests -contains "All"){ | |
| Write-Error "Invalid Tests parameter value: You can't use 'All' with other tests." -ErrorAction Stop | |
| } | |
| Write-Verbose "Executing tests: $($DCDiagTests.Keys -join ", ")" | |
| } | |
| Process { | |
| if(![string]::IsNullOrEmpty($ComputerName)) { | |
| $ServerArg = "/s:$ComputerName" | |
| } | |
| else { | |
| $ComputerName = $env:COMPUTERNAME | |
| $ServerArg = "/s:$env:COMPUTERNAME" | |
| } | |
| Write-Verbose "Starting DCDIAG on $ComputerName" | |
| $TestResults = @() | |
| $TestsToRun | Foreach { | |
| Write-Verbose "Starting test $_ on $ComputerName" | |
| $TestName = $_ | |
| $ExtraArgs = $DCDiagTests[$_].ExtraArgs | |
| if($_ -in @("DcPromo", "RegisterInDNS")){ | |
| if($env:COMPUTERNAME -ne $ComputerName){ | |
| Write-Verbose "Test cannot be performed remote, invoking dcdiag" | |
| $Output = Invoke-Command -ComputerName $ComputerName -ArgumentList @($TestName,$ExtraArgs) -ScriptBlock { | |
| $TestName = $args[0] | |
| $ExtraArgs = $args[1] | |
| dcdiag /test:$TestName $ExtraArgs | |
| } | |
| } | |
| else { | |
| $Output = dcdiag /test:$TestName $ExtraArgs | |
| } | |
| } | |
| else { | |
| $Output = dcdiag /test:$TestName $ExtraArgs $ServerArg | |
| } | |
| $Fails = ($Output | Select-String -AllMatches -Pattern "fail" | Measure-Object).Count | |
| $Passes = ($Output | Select-String -AllMatches -Pattern "passed" | Measure-Object).Count | |
| $Pass = ($Fails -eq 0 -and $Passes -gt 0) | |
| $ResultSplat = @{ | |
| Source = $ComputerName | |
| TestName = "$_" | |
| Pass = ($Fails -eq 0 -and $Passes -gt 0) | |
| Was = $Fails,$Passes | |
| ShouldBe = 0,0 | |
| Category = "DCDIAG" | |
| Message = "$Output[-1]" | |
| Data = $Output | |
| Tags = @('DCDIAG',$_) | |
| } | |
| New-AdhcResult @ResultSplat | |
| } | |
| $TestResults | |
| } | |
| End { | |
| } | |
| } |
Hi Alex,
I am running this in a test environment on a Windows Server 2016 Std,
here is the error I am getting:
Cannot create object of type "AdhcResult". The SubCategory property was not found for the AdhcResult object. The available property is: [Source <System.String>] , [TestName <System.String>] , [Pass <System.Boolean>] , [Was <System.Object>] , [ShouldBe <System.Object>] , [Category <System.String>] , [Message <System.String>] , [Data <System.Object>] , [Tags <System.String[]>] At E:\Powershell\AD HealthCheck\Test-AdhcDcDiag.ps1:62 char:9
[AdhcResult]@{~~~~~~~~~~~~~~
- CategoryInfo : InvalidArgument: (:) [], RuntimeException
- FullyQualifiedErrorId : ObjectCreationError
This is solved when you use this Class in the beginning of the script:
Class AdhcResult { [string]$Source [string]$TestName [bool]$Pass $Was $ShouldBe [string]$Category [string]$SubCategory [string]$Message $Data [string[]]$Tags }
Following on from what @Raffytje found, it was still generating the same error for me, until I saw the SubCategory property was missing.
Fixed class is below.
Class AdhcResult {
[string]$Source
[string]$TestName
[bool]$Pass
$Was
$ShouldBe
[string]$Category
[string]$SubCategory
[string]$Message
$Data
[string[]]$Tags
}
Hi Alex,
I am running this in a test environment on a Windows Server 2016 Std,
here is the error I am getting:
Cannot create object of type "AdhcResult". The SubCategory property was not found for the AdhcResult object. The available property is: [Source <System.String>] ,
[TestName <System.String>] , [Pass <System.Boolean>] , [Was <System.Object>] , [ShouldBe <System.Object>] , [Category <System.String>] , [Message <System.String>] , [Data
<System.Object>] , [Tags <System.String[]>]
At E:\Powershell\AD HealthCheck\Test-AdhcDcDiag.ps1:62 char:9