用于检查AD复制的Powershell脚本 [英] Powershell script for checking AD replication

查看:60
本文介绍了用于检查AD复制的Powershell脚本的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我修改了我在网上找到的AD复制Powershell脚本,其中包括以下代码:

I adapted an AD replication powershell script I found online to include the code below:

function ExitWithCode {
param
(
    $exitcode
)

$host.SetShouldExit($exitcode)
exit
}

function Write-Log {
<#
.SYNOPSIS
    Write-Log writes a message to a logfile

.DESCRIPTION
    The Write-Log function is designed to add logging capability to other scripts. 
    In addition to writing output and/or verbose you can write to a log file for 
    later debugging. 
#>
[CmdletBinding()]
Param
(
    [Parameter(Mandatory = $true,ValueFromPipelineByPropertyName = $true)]
    [ValidateNotNullOrEmpty()]
    [Alias('LogContent')]
    [string]$Message,

    [Parameter(Mandatory = $false)]
    [ValidateSet("Error", "Info", "Status")]
    [string]$Level = "Info",

    [Parameter(Mandatory = $false)]
    [Alias('LogPath')]
    [string]$Path = 'C:\dataloop\ADHealthCheck.log'

)

BEGIN {

    [string]$FormattedDate = Get-Date -Format "dd-MM-yyyy HH:mm"

    If (-NOT (Test-Path $path)) {
        Write-Verbose "Creating $Path"
        [System.IO.FileInfo]$LogFile = New-Item $Path -Force -ItemType file
    }
}
PROCESS {   
    [string]$LogLine = "$FormattedDate - $Level - $message"
    $LogLine | Out-File -FilePath $Path -Append

    Switch ($Level) {

        "Info" {Write-Verbose $LogLine}
        "Status" {Write-Output $LogLine}
        "Error" {Write-Error $LogLine}
    }
}
END {}
}

function Get-ADHealthCheck {
    [CmdletBinding()]
        param()

        BEGIN {
        Write-Log "Beginning the AD Health Check..."
        }


        PROCESS {
        $DCs = Get-ADDomainController -Filter * |sort name

        Write-Log "$($DCs.Count) Domain Controllers found" -level Info

        $results = @()

        ForEach ($DC in $DCs) {

            Write-Log "Getting replication metadata for $($DC.HostName)" -level Status
            $ReplStatuses = Get-ADReplicationPartnerMetadata -target $DC.HostName -PartnerType Both -ErrorAction SilentlyContinue 

            If ($ReplStatuses) {

                 Write-Log "$($ReplStatuses.Count) replication links found for $($DC.HostName)" -level Info

                ForEach ($ReplStatus in $ReplStatuses) {

                    $Partner = $ReplStatus.Partner.Split(",")[1].Replace("CN=","")

                    $results += [pscustomobject] @{
                        'Source DC' = $DC.HostName.ToUpper()
                        'Partner DC' = (Get-ADComputer $Partner).DNSHostName.ToUpper()
                        'Direction' = $ReplStatus.PartnerType
                        'Type' = $ReplStatus.IntersiteTransportType
                        'Last Attempt' = $ReplStatus.LastReplicationAttempt
                        'Last Success' = $ReplStatus.LastReplicationSuccess
                        'Last Result' = $ReplStatus.LastReplicationResult
                    }
                }
            }

            Else {

                Write-Log "Unable to get replication status for $($DC.HostName)" -level Error
                $results += [pscustomobject] @{
                    'Source DC' = $DC.HostName.ToUpper()
                    'Partner DC' = "N/A"
                    Direction = "N/A"
                    Type = "N/A"
                    'Last Attempt' = "N/A"
                    'Last Success' = "N/A"
                    'Last Result' = "N/A"
                }
             }
        }

        ForEach ($result in $results) {

            If ("$($results.'Last Result')" -eq "0") {

                Write-Log "There were no replication issues found" -Level Info
                ExitWithCode -exitcode 0 
            }

            Else {

                Write-Log "These domain controllers have replication errors. Please review them..." -Level Error
                $error = $results | where {"$($_.'Last Result')" -ne "0"} | select 'Source DC','Partner DC','Direction' | ft -AutoSize
                Write-Log $error -Level Error
                ExitWithCode -exitcode 2
            }
        }
    }
}
Get-ADHealthCheck

基本上,我现在遇到的唯一问题是最后一个if / else我需要它循环遍历$ results哈希表中的每个条目,并且如果 Last Result键仅包含 0,则以代码0退出。如果找到任何其他值,则应输出源,伙伴,以及哈希表中的方向值。

Basically the only issue I'm having now is the last if/else block. I need it to loop through every entry in the $results hash table and if the "Last Result" key only contains "0", then exit with code 0. If it finds any other values, it should output the source, partner, and direction value(s) fromt he hash table.

当前,如果遇到问题,它将跳转到else块,输出请求的信息,然后运行ExitWithCode函数最终会终止脚本,因此不会检查错误后出现的所有错误。

Currently, if it encounters an issue, it jumps to the else block, outputs the information requested and then runs the ExitWithCode function which eventually kills the script so anything that comes after the error is not checked.

我已经看了太久了,一直没有成功,所以我把它扔到那里,因为它可能只是我缺少的简单东西。

I've been looking at this too long and have been unsuccessful so I'm throwing it out to there since it may just be something simple I'm missing.

推荐答案

看在您的for循环变量中

Look at your for loop variables


ForEach ($result in $results) {


对于每个 $ result $ results 中的$ c> 。在下面的 if 语句中,您应该查看一个 $ result ,但是您正在与进行比较所有结果。此处也不需要您的子表达式语法。

For each single $result in the $results. In the following if statement you should be looking at one $result but instead you are doing a comparison against all results. Your subexpression syntax here is also not required.


 If ("$($results.'Last Result')" -eq "0") 


请注意,这是完全有效的代码,但不会得到您所期望的结果。它将返回所有最后结果(均为0)。因此,即使整个集合中的一个为0,也始终会触发真实条件。

Note that this is perfectly valid code but it will not get you the results you expect. It will return all 'last result's that are 0. So if even one in the whole collection is 0 the true condition will always fire.

因此,只需进行一些较小的更改,并使用单数 $ result

So lets just make some minor changes and use the singular $result

If ($result.'Last Result' -eq "0") 

那应该为您提供所需的结果。我注意到您正在寻找与字符串0相等的问题。由于LHS设置了用于比较的类型,因此这不会成为问题。看看另一篇文章,以更好地了解PowerShell在这里的功能。

That should get you the result you are looking for. I notice that you are looking for equality with the string 0. That will not be an issue here since the LHS sets the type for the comparison. Have a look at this other post to get a better understanding of what PowerShell does here.

为什么$ false -eq

如果您的最后一个结果是整数0,那将是真的

If your last result was the int 0 this would be true

0 -eq "0"






正如您在有关如何处理整体成功和个别失败的评论中提到的那样,您的逻辑似乎存在缺陷。我认为我们不必像您那样遍历结果,而是需要整体检查集合并仅在遇到错误时才进行循环。


Your logic appears to be flawed as you have mentioned in comments on how to handle overall success and individual failures. Instead of looping through the results like you were I think we need to check the collection as a whole and loop only if errors are encountered.

# Lets check if any of the results contain failure
$failedChecks = $results | Where-object{$_.'Last Result' -ne 0}

# Evaluate $failedChecks as a boolean. If there are no failed checks Else can be assumed that everything is fine. 
if($failedChecks){
    Write-Log "These domain controllers have replication errors. Please review them..." -Level Error
    $error = $failedChecks | select 'Source DC','Partner DC','Direction' | ft -AutoSize | Out-String
    Write-Log $error -Level Error
    ExitWithCode -exitcode 2        
} else {
    Write-Log "There were no replication issues found" -Level Info
    ExitWithCode -exitcode 0 
}

这篇关于用于检查AD复制的Powershell脚本的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆