用于检查AD复制的Powershell脚本

时间:2017-03-30 22:41:52

标签: powershell active-directory

我调整了我在网上找到的AD复制powershell脚本,其中包含以下代码:

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.如果找到任何其他值,它应输出源,伙伴和哈希表中的方向值。

目前,如果它遇到问题,它会跳转到else块,输出所请求的信息,然后运行ExitWithCode函数,该函数最终会杀死脚本,因此不会检查错误后发生的任何事情。

我一直在看这个太久而且没有成功,所以我把它扔到那里因为它可能只是一些简单的我不知道。

1 个答案:

答案 0 :(得分:1)

查看你的for循环变量

ReadXml

ForEach ($result in $results) { 中的每个 $result 。在以下$results语句中,您应该查看一个if,而是对所有结果进行比较。此处的子表达式语法也不是必需的。

$result

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

因此,我们只需进行一些小修改,然后使用单数 If ("$($results.'Last Result')" -eq "0")

$result

这应该可以获得您正在寻找的结果。我注意到你正在寻找与字符串0相等的问题。由于LHS设置了比较的类型,因此这不是问题。看看这篇其他帖子,以便更好地了解PowerShell在这里所做的工作。

Why is $false -eq "" true?

如果您的上一个结果是int 0,那将是真的

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

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

0 -eq "0"