PowerShell Where-Object 布尔值和管道输出(用于查找域之间重复的 AD 机器)
PowerShell Where-Object Boolean and pipeline output (to find duplicate AD machines between domains)
出乎我意料的奇怪输出。我如何找出我做错了什么?
我正在尝试找出存在于两个域中的 Active Directory 台机器,并找到它们之间不活动的一台(登录时间最早的一台)。
在脚本的上方,所有具有 lastlogontimestamp 和一些其他属性的计算机都从 Active Directory 拉入数组 DomainAComputers 和 DomainBComputers;下面是找出哪台机器是我们应该删除的机器。
# Match machines between domains to find duplicates - Works fine.
$Duplicates = $Computers | ? {($DomainAComputers.name -match $_.name) -and ($DomainBComputers.name -match $_.name)}
# Create a custom array with only the INACTIVE machine between the 2 domains
$DuplicateInactive = @()
# Loop through each machine
Foreach ($comp in $Duplicates){
$DomApc = $DomainAComp | ? {$_.name -eq $comp.name} #pull single comp entry from DomA array
$DomBpc = $DomainBComp | ? {$_.name -eq $comp.name} #pull single comp entry from DomB array
# Compare to see if DomA pc is not in use.
$DupDomAinactive = $DomApc | ? {$DomApc.lastlogontimestamp.DateTime -le $DomBpc.lastlogontimestamp.DateTime}
# Compare to see if DomB pc is not in use
$DupDomBinactive = $DomBpc | ? {$DomBpc.lastlogontimestamp.DateTime -le $DomApc.lastlogontimestamp.DateTime}
#output results to custom array
$DuplicateInactive += $DupDomAInactive
$DuplicateInactive += $DupDomBInactive
}
问题:如果我查询
$DomApc.lastlogontimestamp.DateTime -le $DomBpc.lastlogontimestamp.DateTime
,结果为真; DomBpc -le DomApc
则相反,returns 为假。
(例如,DomA - 27/04/2018 4:22:37 PM is less than DomB - 7/05/2018 12:18:06 PM
- returns 正确。)
然后我希望返回 true 的那个会把它的结果传递回 $DupDomAinactive,并被添加到 $DuplicateInactive
,然而事实似乎并非如此。
在总共 54 个中,$duplicateinactive.count
显示 54,但是 $duplicateinactive
的输出显示大约 10 个条目(5 台机器两次)。我希望正好有一半返回 true,因此有 27 个结果。
我哪里做错了,有更简单的方法吗?
我会先在 table 中收集计算机名和上次注销日期。
$Duplicates = $Computers |
Where-Object {($DomainAComputers.name -match $_.name) -and
($DomainBComputers.name -match $_.name)} |
ForEach-Object {
$Comp = $_
$DomApc = $DomainAComp | ? {$_.name -eq $comp}
$DomBpc = $DomainBComp | ? {$_.name -eq $comp}
[PSCustomObject]@{
'Computer' = $_
'DomALastLogOut' = $DomApc.lastlogontimestamp.DateTime
'DomBLastLogOut' = $DomBpc.lastlogontimestamp.DateTime
}
}
$Duplicates
您应该在 Where
中使用当前对象($PSItem
或 $_
)而不是整个对象数组($DomApc
或 $DomBpc
) (? {$_...}
) 子句。
换句话说:
#compare to see if DomA pc is not in use.
$DupDomAinactive = $DomApc | ? {$DomApc.lastlogontimestamp.DateTime -le $DomBpc.lastlogontimestamp.DateTime}
#compare to see if DomB pc is not in use
$DupDomBinactive = $DomBpc | ? {$DomBpc.lastlogontimestamp.DateTime -le $DomApc.lastlogontimestamp.DateTime}
应该是:
#compare to see if DomA pc is not in use.
$DupDomAinactive = $DomApc | ? {$_.lastlogontimestamp.DateTime -le $DomBpc.lastlogontimestamp.DateTime}
#compare to see if DomB pc is not in use
$DupDomBinactive = $DomBpc | ? {$_.lastlogontimestamp.DateTime -le $DomApc.lastlogontimestamp.DateTime}
谢谢;我认为我的做法存在多个问题;我发现,当我尝试执行布尔运算时,通过 if 语句将其放入是最好的方法(而不是直接通过我怀疑正在用 $true\$false 结果做一些奇怪的事情的 where-object传回去了)。
还需要为两个域使用两个单独的输出;并使用 Sort-object 去除输出中的重复项(因为它比较两次,每个域一次)。
我使用了 LotPing 的使用一个管道的想法,但它缺少比较域的关键部分(-le
过滤器)。最终输出:
$DomADup = @()
$DomBDup = @()
$Computers |
Where-Object {($DomAComputers.name -match $_.name) -and
($DomBComputers.name -match $_.name)} |
ForEach-Object {
$Comp = $_
$DomApc = $DomAComputers | ? {$_.name -eq $comp.name}
$DomBpc = $DomBComputers | ? {$_.name -eq $comp.name}
if($DomApc.lastlogontimestamp.DateTime -le $DomBpc.lastlogontimestamp.DateTime) {$DomADup +=$DomApc}
if($DomBpc.lastlogontimestamp.DateTime -le $DomApc.lastlogontimestamp.DateTime) {$DomBDup +=$DomBpc}
}
$DomAToDelete = $DomADup | sort-object -property Name -unique
$DomBToDelete = $DomBDup | sort-object -property Name -unique
出乎我意料的奇怪输出。我如何找出我做错了什么?
我正在尝试找出存在于两个域中的 Active Directory 台机器,并找到它们之间不活动的一台(登录时间最早的一台)。
在脚本的上方,所有具有 lastlogontimestamp 和一些其他属性的计算机都从 Active Directory 拉入数组 DomainAComputers 和 DomainBComputers;下面是找出哪台机器是我们应该删除的机器。
# Match machines between domains to find duplicates - Works fine.
$Duplicates = $Computers | ? {($DomainAComputers.name -match $_.name) -and ($DomainBComputers.name -match $_.name)}
# Create a custom array with only the INACTIVE machine between the 2 domains
$DuplicateInactive = @()
# Loop through each machine
Foreach ($comp in $Duplicates){
$DomApc = $DomainAComp | ? {$_.name -eq $comp.name} #pull single comp entry from DomA array
$DomBpc = $DomainBComp | ? {$_.name -eq $comp.name} #pull single comp entry from DomB array
# Compare to see if DomA pc is not in use.
$DupDomAinactive = $DomApc | ? {$DomApc.lastlogontimestamp.DateTime -le $DomBpc.lastlogontimestamp.DateTime}
# Compare to see if DomB pc is not in use
$DupDomBinactive = $DomBpc | ? {$DomBpc.lastlogontimestamp.DateTime -le $DomApc.lastlogontimestamp.DateTime}
#output results to custom array
$DuplicateInactive += $DupDomAInactive
$DuplicateInactive += $DupDomBInactive
}
问题:如果我查询
$DomApc.lastlogontimestamp.DateTime -le $DomBpc.lastlogontimestamp.DateTime
,结果为真; DomBpc -le DomApc
则相反,returns 为假。
(例如,DomA - 27/04/2018 4:22:37 PM is less than DomB - 7/05/2018 12:18:06 PM
- returns 正确。)
然后我希望返回 true 的那个会把它的结果传递回 $DupDomAinactive,并被添加到 $DuplicateInactive
,然而事实似乎并非如此。
在总共 54 个中,$duplicateinactive.count
显示 54,但是 $duplicateinactive
的输出显示大约 10 个条目(5 台机器两次)。我希望正好有一半返回 true,因此有 27 个结果。
我哪里做错了,有更简单的方法吗?
我会先在 table 中收集计算机名和上次注销日期。
$Duplicates = $Computers |
Where-Object {($DomainAComputers.name -match $_.name) -and
($DomainBComputers.name -match $_.name)} |
ForEach-Object {
$Comp = $_
$DomApc = $DomainAComp | ? {$_.name -eq $comp}
$DomBpc = $DomainBComp | ? {$_.name -eq $comp}
[PSCustomObject]@{
'Computer' = $_
'DomALastLogOut' = $DomApc.lastlogontimestamp.DateTime
'DomBLastLogOut' = $DomBpc.lastlogontimestamp.DateTime
}
}
$Duplicates
您应该在 Where
中使用当前对象($PSItem
或 $_
)而不是整个对象数组($DomApc
或 $DomBpc
) (? {$_...}
) 子句。
换句话说:
#compare to see if DomA pc is not in use.
$DupDomAinactive = $DomApc | ? {$DomApc.lastlogontimestamp.DateTime -le $DomBpc.lastlogontimestamp.DateTime}
#compare to see if DomB pc is not in use
$DupDomBinactive = $DomBpc | ? {$DomBpc.lastlogontimestamp.DateTime -le $DomApc.lastlogontimestamp.DateTime}
应该是:
#compare to see if DomA pc is not in use.
$DupDomAinactive = $DomApc | ? {$_.lastlogontimestamp.DateTime -le $DomBpc.lastlogontimestamp.DateTime}
#compare to see if DomB pc is not in use
$DupDomBinactive = $DomBpc | ? {$_.lastlogontimestamp.DateTime -le $DomApc.lastlogontimestamp.DateTime}
谢谢;我认为我的做法存在多个问题;我发现,当我尝试执行布尔运算时,通过 if 语句将其放入是最好的方法(而不是直接通过我怀疑正在用 $true\$false 结果做一些奇怪的事情的 where-object传回去了)。
还需要为两个域使用两个单独的输出;并使用 Sort-object 去除输出中的重复项(因为它比较两次,每个域一次)。
我使用了 LotPing 的使用一个管道的想法,但它缺少比较域的关键部分(-le
过滤器)。最终输出:
$DomADup = @()
$DomBDup = @()
$Computers |
Where-Object {($DomAComputers.name -match $_.name) -and
($DomBComputers.name -match $_.name)} |
ForEach-Object {
$Comp = $_
$DomApc = $DomAComputers | ? {$_.name -eq $comp.name}
$DomBpc = $DomBComputers | ? {$_.name -eq $comp.name}
if($DomApc.lastlogontimestamp.DateTime -le $DomBpc.lastlogontimestamp.DateTime) {$DomADup +=$DomApc}
if($DomBpc.lastlogontimestamp.DateTime -le $DomApc.lastlogontimestamp.DateTime) {$DomBDup +=$DomBpc}
}
$DomAToDelete = $DomADup | sort-object -property Name -unique
$DomBToDelete = $DomBDup | sort-object -property Name -unique