PowerShell Where-Object布尔和管道输出(用于在域之间查找重复的AD机器)

时间:2018-05-08 03:14:23

标签: powershell pipe pipeline

奇怪的输出来自我所期望的。我怎么知道我做错了什么?

我正在尝试查找存在于两个域中的Active Directory台机器,并找到它们之间的非活动机器(已使用最早时间登录的机器)。

进一步提升脚本,所有具有lastlogontimestamp和其他一些属性的计算机都从Active Directory中提取到Arrays 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则相反,它返回false。 (示例,DomA - 27/04/2018 4:22:37 PM is less than DomB - 7/05/2018 12:18:06 PM - 返回TRUE。)

我希望返回true的那个会将其结果传回$ DupDomAinactive,然后添加到$DuplicateInactive,但事实并非如此。

在总共54个中,$duplicateinactive.count显示54,但$duplicateinactive的输出显示大约10个条目(5台机器两次)。我希望将有一半返回true,因此有27个结果。

我做错了什么,有更简单的方法吗?

3 个答案:

答案 0 :(得分:0)

我先在表格中收集计算机名和LastLogout日期。

$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

答案 1 :(得分:0)

您应该使用当前对象($_$DomApc)而不是$DomBpc中的整个对象数组(Where? {$_...})({ {1}})条款。

换句话说:

#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} 

答案 2 :(得分:0)

感谢;我认为我这样做有很多问题;我发现当我尝试做一个布尔运算时,将它放在if语句中是最好的方法(而不是直接通过一个where-object,我怀疑它是用$ true \ $ false结果做了一些奇怪的事情传回来了。

还需要为这两个域使用两个单独的输出;并使用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