Src/Private/Get-WinADDFSHealth.ps1
|
function Get-WinADDFSHealth { <# .SYNOPSIS Used by As Built Report to get DFS health AD forest info. .DESCRIPTION .NOTES Version: 0.1.0 Author: Przemysław Kłys .EXAMPLE .LINK #> [cmdletBinding()] param( [alias('ForestName')][string] $Forest, [string[]] $ExcludeDomains, [string[]] $ExcludeDomainControllers, [alias('Domain', 'Domains')][string[]] $IncludeDomains, [alias('DomainControllers')][string[]] $IncludeDomainControllers, [switch] $SkipRODC, [int] $EventDays = 1, [switch] $SkipGPO, [switch] $SkipAutodetection, [System.Collections.IDictionary] $ExtendedForestInformation, [pscredential] $Credential ) $Today = (Get-Date) $Yesterday = (Get-Date -Hour 0 -Second 0 -Minute 0 -Millisecond 0).AddDays(-$EventDays) if (-not $SkipAutodetection) { $ForestInformation = Get-WinADForestDetail -Forest $Forest -IncludeDomains $IncludeDomains -ExcludeDomains $ExcludeDomains -ExcludeDomainControllers $ExcludeDomainControllers -IncludeDomainControllers $IncludeDomainControllers -SkipRODC:$SkipRODC -ExtendedForestInformation $ExtendedForestInformation -Extended -Credential $Credential } else { if (-not $IncludeDomains) { Write-PScriboMessage -Message "Get-WinADDFSHealth - You need to specify domain when using SkipAutodetection." return } # This is for case when Get-ADDomainController -Filter * is broken $ForestInformation = @{ Domains = $IncludeDomains DomainDomainControllers = @{} } foreach ($Domain in $IncludeDomains) { $ForestInformation['DomainDomainControllers'][$Domain] = [System.Collections.Generic.List[Object]]::new() foreach ($DC in $IncludeDomainControllers) { try { $DCInformation = Get-ADDomainController -Identity $DC -Server $Domain -ErrorAction Stop -Credential $Credential Add-Member -InputObject $DCInformation -MemberType NoteProperty -Value $DCInformation.ComputerObjectDN -Name 'DistinguishedName' -Force $ForestInformation['DomainDomainControllers'][$Domain].Add($DCInformation) } catch { Write-PScriboMessage -Message "Get-WinADDFSHealth - Can't get DC details. Skipping with error: $($_.Exception.Message)" continue } } } } [Array] $Table = foreach ($Domain in $ForestInformation.Domains) { Write-PScriboMessage -Message "Get-WinADDFSHealth - Processing $Domain" [Array] $DomainControllersFull = $ForestInformation['DomainDomainControllers']["$Domain"] if ($DomainControllersFull.Count -eq 0) { continue } if (-not $SkipAutodetection) { $QueryServer = $ForestInformation['QueryServers']["$Domain"].HostName[0] } else { $QueryServer = $DomainControllersFull[0].HostName } if (-not $SkipGPO) { try { #[Array]$GPOs = @(Get-GPO -All -Domain $Domain -Server $QueryServer) $SystemsContainer = $ForestInformation['DomainsExtended'][$Domain].SystemsContainer if ($SystemsContainer) { $PoliciesSearchBase = -join ("CN=Policies,", $SystemsContainer) } [Array]$GPOs = Get-ADObject -ErrorAction Stop -SearchBase $PoliciesSearchBase -SearchScope OneLevel -Filter * -Server $QueryServer -Properties Name, gPCFileSysPath, DisplayName, DistinguishedName, Description, Created, Modified, ObjectClass, ObjectGUID -Credential $Credential } catch { $GPOs = $null } } try { $CentralRepository = Get-ChildItem -Path "\\$Domain\SYSVOL\$Domain\policies\PolicyDefinitions" -ErrorAction Stop $CentralRepositoryDomain = if ($CentralRepository) { $true } else { $false } } catch { $CentralRepositoryDomain = $false } foreach ($DC in $DomainControllersFull) { try { Write-PScriboMessage -Message "Get-WinADDFSHealth - Processing $($DC.Name) $($DC.HostName) for $Domain" $DCName = $DC.Name $Hostname = $DC.Hostname $DN = $DC.DistinguishedName $LocalSettings = "CN=DFSR-LocalSettings,$DN" $Subscriber = "CN=Domain System Volume,$LocalSettings" $Subscription = "CN=SYSVOL Subscription,$Subscriber" $ReplicationStatus = @{ '0' = 'Uninitialized' '1' = 'Initialized' '2' = 'Initial synchronization' '3' = 'Auto recovery' '4' = 'Normal' '5' = 'In error state' '6' = 'Disabled' '7' = 'Unknown' } $DomainSummary = [ordered] @{ "DomainController" = $DCName "Domain" = $Domain "Status" = $false "ReplicationState" = 'Unknown' "IsPDC" = $DC.OperationMasterRoles -contains 'PDCEmulator' 'GroupPolicyOutput' = $null -ne $GPOs # This shows whether output was on Get-GPO "GroupPolicyCount" = if ($GPOs) { $GPOs.Count } else { 0 }; "SYSVOLCount" = 0 'CentralRepository' = $CentralRepositoryDomain 'CentralRepositoryDC' = $false 'IdenticalCount' = $false "Availability" = $false "MemberReference" = $false "DFSErrors" = 0 "DFSEvents" = $null "DFSLocalSetting" = $false "DomainSystemVolume" = $false "SYSVOLSubscription" = $false "StopReplicationOnAutoRecovery" = $false "DFSReplicatedFolderInfo" = $null } if ($SkipGPO) { $DomainSummary.Remove('GroupPolicyOutput') $DomainSummary.Remove('GroupPolicyCount') $DomainSummary.Remove('SYSVOLCount') } $WarningVar = $null $DFSReplicatedFolderInfoAll = Get-CimData -NameSpace "root\microsoftdfs" -Class 'dfsrreplicatedfolderinfo' -ComputerName $Hostname -WarningAction SilentlyContinue -WarningVariable WarningVar -Verbose:$false $DFSReplicatedFolderInfo = $DFSReplicatedFolderInfoAll | Where-Object { $_.ReplicationGroupName -eq 'Domain System Volume' } if ($WarningVar) { $DomainSummary['ReplicationState'] = 'Unknown' #$DomainSummary['ReplicationState'] = $WarningVar -join ', ' } else { $DomainSummary['ReplicationState'] = $ReplicationStatus["$($DFSReplicatedFolderInfo.State)"] } try { $CentralRepositoryDC = Get-ChildItem -Path "\\$Hostname\SYSVOL\$Domain\policies\PolicyDefinitions" -ErrorAction Stop $DomainSummary['CentralRepositoryDC'] = if ($CentralRepositoryDC) { $true } else { $false } } catch { $DomainSummary['CentralRepositoryDC'] = $false } try { $MemberReference = (Get-ADObject -Credential $Credential -Identity $Subscriber -Properties msDFSR-MemberReference -Server $QueryServer -ErrorAction Stop).'msDFSR-MemberReference' -like "CN=$DCName,*" $DomainSummary['MemberReference'] = if ($MemberReference) { $true } else { $false } } catch { $DomainSummary['MemberReference'] = $false } try { $DFSLocalSetting = Get-ADObject -Credential $Credential -Identity $LocalSettings -Server $QueryServer -ErrorAction Stop $DomainSummary['DFSLocalSetting'] = if ($DFSLocalSetting) { $true } else { $false } } catch { $DomainSummary['DFSLocalSetting'] = $false } try { $DomainSystemVolume = Get-ADObject -Credential $Credential -Identity $Subscriber -Server $QueryServer -ErrorAction Stop $DomainSummary['DomainSystemVolume'] = if ($DomainSystemVolume) { $true } else { $false } } catch { $DomainSummary['DomainSystemVolume'] = $false } try { $SysVolSubscription = Get-ADObject -Credential $Credential -Identity $Subscription -Server $QueryServer -ErrorAction Stop $DomainSummary['SYSVOLSubscription'] = if ($SysVolSubscription) { $true } else { $false } } catch { $DomainSummary['SYSVOLSubscription'] = $false } if (-not $SkipGPO) { try { [Array] $SYSVOL = Get-ChildItem -Path "\\$Hostname\SYSVOL\$Domain\Policies" -Exclude "PolicyDefinitions*" -ErrorAction Stop $DomainSummary['SysvolCount'] = $SYSVOL.Count } catch { $DomainSummary['SysvolCount'] = 0 } } if (Test-Connection $Hostname -ErrorAction SilentlyContinue) { $DomainSummary['Availability'] = $true } else { $DomainSummary['Availability'] = $false } try { [Array] $Events = 0 $DomainSummary['DFSErrors'] = $Events.Count $DomainSummary['DFSEvents'] = $Events } catch { $DomainSummary['DFSErrors'] = $null } $DomainSummary['IdenticalCount'] = $DomainSummary['GroupPolicyCount'] -eq $DomainSummary['SYSVOLCount'] try { # $Registry = Get-PSRegistry -RegistryPath "HKLM\SYSTEM\CurrentControlSet\Services\DFSR\Parameters" -ComputerName $Hostname -ErrorAction Stop } catch { #$ErrorMessage = $_.Exception.Message $Registry = $null } if ($null -ne $Registry.StopReplicationOnAutoRecovery) { $DomainSummary['StopReplicationOnAutoRecovery'] = [bool] $Registry.StopReplicationOnAutoRecovery } else { $DomainSummary['StopReplicationOnAutoRecovery'] = $null # $DomainSummary['StopReplicationOnAutoRecovery'] = $ErrorMessage } $DomainSummary['DFSReplicatedFolderInfo'] = $DFSReplicatedFolderInfoAll $All = @( if (-not $SkipGPO) { $DomainSummary['GroupPolicyOutput'] } $DomainSummary['SYSVOLSubscription'] $DomainSummary['ReplicationState'] -eq 'Normal' $DomainSummary['DomainSystemVolume'] $DomainSummary['DFSLocalSetting'] $DomainSummary['MemberReference'] $DomainSummary['Availability'] $DomainSummary['IdenticalCount'] $DomainSummary['DFSErrors'] -eq 0 ) $DomainSummary['Status'] = $All -notcontains $false [PSCustomObject] $DomainSummary } catch { Write-PScriboMessage -Message "Get-WinADDFSHealth - Failed to gather DFS Health for $Domain $($DC.Name) with error: $($_.Exception.Message)" continue } } } $Table } |