Логический и конвейерный вывод PowerShell Where-Object (для поиска дублированных компьютеров AD между доменами) - PullRequest
0 голосов
/ 08 мая 2018

Странный вывод из того, что я ожидал. Как мне узнать, что я делаю не так?

Я пытаюсь найти Active Directory компьютеров, которые существуют в двух доменах, и найти неактивный между ними (тот, который вошел в систему с самым старым временем).

Далее сценарий, все компьютеры с меткой времени lastlogon и некоторыми другими свойствами перетаскиваются из 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, он возвращает ложь. (Например, 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 машин дважды). Я ожидал бы, что будет ровно половина, вернувшая истину, поэтому 27 результатов.

Что я делаю не так и есть ли намного более простой способ сделать это?

Ответы [ 3 ]

0 голосов
/ 08 мая 2018

Вы должны использовать текущий объект ($PSItem или $_), а не весь массив объектов ($DomApc или $DomBpc) в предложении Where (? {$_...}).

Другими словами:

#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} 
0 голосов
/ 09 мая 2018

Спасибо; Я думаю, что было много проблем с тем, как я это делал; Я обнаружил, что когда я пытаюсь выполнить булеву операцию, лучше всего выполнить ее с помощью оператора if (вместо прямого использования объекта where, который, как я подозреваю, делал странные вещи с результатами $ 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
0 голосов
/ 08 мая 2018

Сначала я собрал бы в таблице даты computername и 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
...