我调整了我在网上找到的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函数,该函数最终会杀死脚本,因此不会检查错误后发生的任何事情。
我一直在看这个太久而且没有成功,所以我把它扔到那里因为它可能只是一些简单的我不知道。
答案 0 :(得分:1)
查看你的for循环变量
ReadXml
ForEach ($result in $results) {
中的每个 $result
。在以下$results
语句中,您应该查看一个if
,而是对所有结果进行比较。此处的子表达式语法也不是必需的。
$result
请注意,这是完全有效的代码,但它无法获得您期望的结果。它将返回所有'最后结果为0。因此,即使整个集合中的一个为0,真实条件也将始终触发。
因此,我们只需进行一些小修改,然后使用单数 If ("$($results.'Last Result')" -eq "0")
$result
这应该可以获得您正在寻找的结果。我注意到你正在寻找与字符串0相等的问题。由于LHS设置了比较的类型,因此这不是问题。看看这篇其他帖子,以便更好地了解PowerShell在这里所做的工作。
如果您的上一个结果是int 0,那将是真的
If ($result.'Last Result' -eq "0")
您的逻辑似乎存在缺陷,正如您在如何处理整体成功和个人失败的评论中所提到的那样。而不是像你一样循环遍历结果,我认为我们需要检查整个集合,并且只在遇到错误时才循环。
0 -eq "0"