Getting computername and the Canonical and distinguished OU name from AD
I have a list of servers where I need to get the OU, I have put together a script that will do this.
Get-ADOrganizationalUnit
-Identity $(($adComputer = Get-ADComputer -Identity $env:COMPUTERNAME).DistinguishedName.SubString($adComputer.DistinguishedName.IndexOf("OU=")))
The issue here is that the OU name is hard to read and not easy on the eye, so I figured out that what i need is the CanonicalName. However here is the problem.
I have come up with the snippet below.
Get-ADOrganizationalUnit -Filter * -properties CanonicalName, DistinguishedName
| select-Object CanonicalName,DistinguishedName
The problem with the above is that it gets everything in AD, I need to be able to filter by servername so that when I load up the server list in a file, I can use a foreach loop to get a report of the servername and the OU, I have tried to use the -Server filter to no avail, as I believe that is for the AD server.
During my research I found, PowerShell filter by OU. In my test environment, it has been running for hours with no results back.
The snippet below will return groups, I cannot get servername filter to work.
Get-ADOrganizationalUnit -Properties CanonicalName -Filter *
| Sort-Object CanonicalName
| ForEach-Object { [pscustomobject]@ {
Name = Split-Path $_.CanonicalName -Leaf
CanonicalName = $_.CanonicalName
UserCount = @(Get-AdUser -Filter * -SearchBase $_.DistinguishedName -SearchScope OneLevel).Count
}
}
Solution 1:
This is how I would do it:
- First query all the computers from your list. Here I'm assuming the computer list is coming from a CSV and the computers are on a column named Computers.
- Get the computer's Organizational Unit by removing the Common Name from their DistinguishedName:
(.... -split '(?=OU=)',2)[-1]
- Add the computers objects to a Hash Table where the Keys are the computer's OUs. This will let us query each OU only once.
- Loop over the Hash Table keys (OU's DistinguishedName) querying their CanonicalName.
- Create a new object for each computer with the desired properties.
- Export the result to a Csv.
# If it's a txt file instead:
# $computers = Get-Content path/to/computers.txt
$csv = Import-Csv path/to/csv.csv
$map = @{}
# If it's a txt file, instead:
# foreach($computer in $computers)
foreach($computer in $csv.Computers)
{
try
{
$adComputer = Get-ADComputer $computer
$ou = ($adComputer.DistinguishedName -split '(?=OU=)',2)[-1]
if($val = $map[$ou]) {
$map[$ou] = $val + $adComputer
continue
}
$map[$ou] = , $adComputer
}
catch
{
Write-Warning $_.Exception.Message
}
}
$result = foreach($ou in $map.Keys)
{
$params = @{
Identity = $ou
Properties = 'canonicalName'
}
try
{
$canonical = Get-ADOrganizationalUnit @params
foreach($computer in $map[$ou])
{
[pscustomobject]@{
'Computer Name' = $computer.Name
'OU DistinguishedName' = $ou
'OU CanonicalName' = $canonical.CanonicalName
}
}
}
catch
{
Write-Warning $_.Exception.Message
}
}
$result | Export-Csv .... -NoTypeInformation