Probably the Craziest Powershell One-Liner I've Written To Date

Someone at work asked me to identify duplicate computers in two separate AD forests, and remove the one that was no longer needed.  It's assumed as part of business policy that there should not be duplicate server hostnames anywhere in the company - even if they reside in different forests or domains.  But for some reason or another, a computer might get migrated from DomainA to DomainB, but the computer object stays behind in the old domain, etc.  So I decided to just collect all the computers from DomainA and DomainB (in ForestA and ForestB respectively), point out the computer accounts that had the same name in each domain, and list their PwdLastSet attribute next to their name.  If the machine had not updated its password in over 30 days in DomainA, while the machine password was up to date in DomainB, then it was reasonably safe to assume that the machine had been migrated out of DomainA and into DomainB, or vice versa.

I only had Powershell v2 on hand, so I didn't have the relative luxury of automatic foreach, etc.  After collecting the computer objects like $DomainAComputers = Get-ADComputer -Filter * -Properties *, check out this hideous monstrosity I came up with to compare them in a single line:

PS C:\Users\ryan> foreach($C In $(Compare-Object $($DomainAComputers|?{!($_.DistinguishedName.Contains("Disabled Accounts"))}|%{$_.Name}) $($DomainBComputers|?{!($_.DistinguishedName.Contains("Disabled Accounts"))}|%{$_.Name}) -IncludeEqual | ? { $_.SideIndicator -eq "==" })) { $o = $($DomainAComputers|?{$_.Name -eq $C.InputObject}); $n = $($DomainBComputers|?{$_.Name -eq $C.InputObject}); $o.DnsHostName + "`t" + $o.PasswordLastSet + "`t" + $n.DnsHostName + "`t" + $n.PasswordLastSet }

The output looks like this:

computer1.domainA.com    04/17/2013    computer1.domainB.com    01/21/2010
computer2.domainA.com    05/05/2013    computer2.domainB.com    10/11/2011
etc...

You can easily see now that the two computers in DomainA are active, while the computer objects of the same name in DomainB are stale, so I'll delete them.

Now don't get me wrong - this is not elegant or clever. It's thoroughly unreadable and ugly and I'd not brag about it except to say, "Haha, look how much s*#! I can cram on one single line of Powershell!"

A couple things that I thought were interesting:

  • Get-ADComputer gives you a free pseudo-attribute called PasswordLastSet, which is a nicely formatted DateTime. But it's not a "real" attribute of the object in Active Directory. Rather, it's the Powershell cmdlet's courtesy attribute where it automatically converts the real attribute - PwdLastSet - from file time (epoch seconds) to a .NET DateTime object. Many of the Active Directory cmdlets work that way.
  • Compare-Object -ExcludeDifferent didn't seem to work and I'm not sure why.  So I had to just use -IncludeEqual instead and isolate the names that were equal.
Comments are closed