Add to Hashtable in Loop

I would like to understand why my loop doesn’t add all entries to my hash table.

I’ve build a hash table with users, next step is to get the computers and add them dynamical into the hash. In my Output for the loop i can see that some users have more than one Computer but only the first one gets added.

 

$HashTab = [ordered]@{
"Name" = $Name
}

Computers = Get-ADComputer
$count = 1
foreach ($Computer in $Computers)
{
$Column = "Computer" + $count
$UserCompOLD = $Computer.name
$UserCompNew = $Computer.extensionAttribute1
$UserComp = $UserCompOLD + "(" + $UserCompNew + ")"
$HashTab.add($Column, $UserComp)            
$count += 1
}


I’d recommend to use PSCustomObject instead. I consider this as much easier to handle. Here is an example how to use it:

$ComputerList = Get-ADComputer

$ResultList = foreach ($Computer in $ComputerList) {
[PSCustomObject]@{
UserCompOLD = $Computer.name
UserCompNew = $Computer.extensionAttribute1
UserComp = “{0} ({1})” -f $Computer.name ,$Computer.extensionAttribute1
}
}
$ResultList |
Format-Table -AutoSize

I changed my hashtable to PSCustomObject and it seems like its the same problem.

$Users = Get-ADUser -Server $Domain -Filter * -Properties *
foreach ($User in $Users)
{
 $HashTab = $NULL
 $HashTab = [PSCustomObject]@{
     "sAMAccountName" = $User.sAMAccountName
     "Surname" = $User.Surname
      "GivenName" = $User.GivenName
 }

 $Computers = Get-ADComputer -Server $Domain -Filter { extensionAttribute12 -Like $User.sAMAccountName } -Properties *
 $count = 1
 foreach ($Computer in $Computers)
 {
    $Column = "Computer" + $count
    $UserCompOLD = $Computer.name
    $UserCompNew = $Computer.extensionAttribute10
    $UserComp = $UserCompOLD + "(" + $UserCompNew + ")"
    $HashTab | Add-Member -MemberType NoteProperty -Name $Column -Value $UserComp
    $count = $count + 1
 }
 $CSVOutput += $HashTab
 $CSVOutput | Sort-Object Name | Export-Csv $CSVFile -NoTypeInformation -Delimiter ";" -Encoding Default
}

 

It looks like this, a Column Computer2 is missing

sAMAccountName,Surname,GivenName,Computer1

Value,Value,Value,Value,

It seems like there are several logic errors. Break it down piece by piece and make sure it all works. Should other things be inside the first user foreach loop? $hashtab gets overwritten each time through the first loop. $hashtab is then being added to $csvoutput one time at the bottom. What is $count for?

What is

$Computers.Length
after line 11? Does it actually contain an array of computers?

Also, try this:

Set-PSDebug -Trace 1

and look at the steps of the loops. Are they executing as you expect?

Hashtab saves the user data for each user and adds it to the csvoutput, it gets overwritten for the next user. This works fine, i just wanted to add the computers and i don’t know if the user has one or ten computers. I need to export a csv file.

 

The $Computers.Length is Null if the user has only one computer and 2 if he has two computers

I wrote an outpout and it looks like this for the computer loop if the user has two computers

Write-Host $count Computer: $UserCompOLD = User: $User.GivenName
1 Computer: Usercomp-W7 = User: Robo

2 Computer: Usercomp-W10 = User: Robo

and set-psdebug looks likes this for both

DEBUG: ! SET $UserComp = 'Usercomp-W7(NEWPC)'.
DEBUG: 107+ >>>> $HashTab | Add-Member -MemberType NoteProperty -Name $Column -Value $UserComp

You like to make it harder than necessary, don’t you? :wink: :smiley: Your code

$Users = Get-ADUser -Server $Domain -Filter * -Properties *
foreach ($User in $Users)
{
$HashTab = $NULL
$HashTab = [PSCustomObject]@{
“sAMAccountName” = $User.sAMAccountName
“Surname” = $User.Surname
“GivenName” = $User.GivenName
}

… can be replaced by this oneliner …

$Hashtab = Get-ADUser -Server $Domain -Filter * | 
    Select-Object -Property sAMAccountName,GivenName,Surname

… and provides the same result.

What is it actually what you are trying to do? Please describe the final result - not the way you think you should go to get the final result.

i would like to export all users i find to a csv with choosen columns and values. Also i would like to lookup all computers that belong to the user and add them dynamical with columns and value. I can find the computer by user mail attribute in the computer extension attribute.

My CSV should look like this

sAMAccountName,Surname,GivenName,Computer1,Computer2

Robo,John,Sam,USerCompW10,USerCompW7

 

it’s only the second part with the computer loop i don’t understand but yes the code might not be perfect :wink:

 

Here’s a simple example of linking user and computer properties that works for me. Maybe it’s of use to you. This is two nested loops. Unfortunately you can’t pipe from foreach, but $( ) fixes that. AD filters are tricky. $( ) to the rescue again. EDIT: I guess your filter would work, but you might as well use “-eq”, since there’s no wildcards.

$users = echo js1,js2 | get-aduser 

$( foreach ($user in $users) {
  $computers = get-adcomputer -filter "description -like '*$($user.samaccountname)*'" 
  foreach ($computer in $computers) {
    [pscustomobject]@{
      UserName = $user.samaccountname
      Email = $user.userprincipalname
      ComputerName = $computer.name
      HostName = $computer.DNSHostName
    }
  }
} ) | export-csv usercomputer.csv


import-csv usercomputer.csv

UserName   Email                 ComputerName HostName
--------   -----                 ------------ --------
js1        js1@powershell.org    COMP01       comp01.powershell.org
js1        js1@powershell.org    COMP02       comp02.powershell.org
js2        js2@powershell.org    COMP01       comp01.powershell.org
js2        js2@powershell.org    COMP02       comp02.powershell.org

Maybe its something with my data if i try this it works

$HashTab = [PSCustomObject]@{
	"Name"  = "User"
	"Test"   = "Yes"
}
$Computers = "One","Two"
$count = 1
foreach ($Computer in $Computers)
{
	$Column = "Computer" + $count
	$HashTab | Add-Member -MemberType NoteProperty -Name $Column -Value $Computer
	$count = $count + 1
}

$HashTab
Name Test Computer1 Computer2
---- ---- --------- ---------
User Yes  One       Two

 

But wouldn’t you need a foreach users loop on the outside and a foreach computers loop on the inside for all the users?

Yes i just followed your advice to break it down piece by piece and make sure it all works :wink:

I also tried it with the outside loop and $Computers = “One”, “Two”, this works. I guess it’s the $Computers = Get-ADComputer Variable

Try This Code

$Computers = Get-ADComputer -Filter *
$count = 1
foreach ($Computer in $Computers)
{ 
$proc = @{
SNo = "Computer" + $count
ComputerName = $Computer.name
}
$count +=1
$HashTab = [pscustomobject]$proc
$HashTab
}