1

I have a list of computer names and I need a report of their OU, their mangedby attribute and their name. I have created a stack with each setting I want but they are not lining up. For 650 computers the count attribute for both the managedby and OU stack are 650 but when I output the data to a txt file I only get 603 lines from the ManagedBy. This would be fine if the data lined up when combined but blank data does not appear to alter the stack when I add it to a txt file. My code is below. After I generate the stacks I export them to a txt file where I Have a macro that can truncate the data for me. Any help would be appreciated.

$stackDN = New-Object System.Collections.Stack
$stackMB = New-Object System.Collections.Stack
$stackNE = New-Object System.Collections.Stack
foreach($computer in $computers){

try{
    Get-ADComputer -Identity $computer -Server $domain -Properties * -ErrorAction Stop
    $object  = Get-ADComputer -Identity $computer -Server $domain -Properties *
    $stackDN.Push($object.DistinguishedName)
    $mb = $object.ManagedBy
    $stackMB.Push($object.ManagedBy)
    $stackMB.push('MB not listed')

}
catch{

$stackNE.Push($computer)
}
} 

$stackDN | Out-File -FilePath H:\dn.txt
$stackMB | out-file -FilePath H:\mb.txt
$stackNE | out-file -FilePath H:\ne.txt'
3

There's a lot of...unconventional...Powershell in your existing code. I think you're making things more difficult for yourself than they need to be. In particular, using the .NET Stack object is not necessary and trying to store each list in its own stack is not optimal for organization as you've found.

Your code seems to indicate you already have a $computers variable that contains your list of computer names. So let's start there. You've got the right idea iterating over the collection, but let's switch to using the ForEach-Object cmdlet instead of the ForEach statement. It's better for passing the results through on the pipeline to other commands.

$adComputers = $computers | ForEach-Object {
    Get-ADComputer $_ -Properties managedBy
}

There are a few things going on in the code above. The $_ is how you reference the "current item" in the ForEach-Object loop. We're also explicitly asking AD for the managedBy attribute because it's not included in the default attributes returned. We don't specify Name or DistingiushedName because those are in the default output. But it wouldn't hurt to add them (and some would argue it's better for readability).

Now that we have our computer objects in their own collection, let's make a report out of them. For data like this that is largely just a set of rows and columns, CSV output is usually the way to go. We just need to select the specific attributes we want from each object and then call Export-Csv.

$adComputers | Select Name,ManagedBy,DistinguishedName | 
    Export-Csv .\report.csv -NoTypeInformation

You can leave out the Export-Csv call to preview what will be in the CSV. But the DN fields will likely get truncated unless you're using a really wide window. I also included the -NoTypeInformation because it leaves out a header line that most people viewing the report won't care about.

Technically speaking, you don't even need to split these commands up. It can just be a big one-liner like this.

$computers | %{ Get-ADComputer $_ -Prop managedBy } |
    Select Name,ManagedBy,DistinguishedName |
    Export-Csv .\report.csv -NoTypeInformation

Note that I switch the ForEach-Object to it's shorthand alias % which is much quicker to type on the command line. I also shortened -Properties to -Prop which is sufficiently non-ambiguous for Powershell to know what you mean.

2
  • Ryan, This is perfect. Thank you. I was having a lot of trouble getting the Export-CSV cmdlet to display information but now I understand how to call that with Select. However, I'm still a little confused on the differences of foreach-object and foreach(). Is there some function of foreach-object that makes your one liner work that using foreach() would not be able to handle? – Mike Eckerle Mar 30 '17 at 12:48
  • 3
    It's primarily the way they process the input. Here's a Technet blog post that explains more in depth. blogs.technet.microsoft.com/heyscriptingguy/2014/07/08/… – Ryan Bolger Mar 30 '17 at 22:21

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.