Add to Hashtable in Loop

Welcome Forums General PowerShell Q&A Add to Hashtable in Loop

This topic contains 12 replies, has 5 voices, and was last updated by

 
Participant
3 months, 1 week ago.

  • Author
    Posts
  • #161130

    Participant
    Topics: 1
    Replies: 5
    Points: 22
    Rank: Member

    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
    }
    
    
    
  • #161160

    Participant
    Topics: 1
    Replies: 1530
    Points: 2,591
    Helping Hand
    Rank: Community Hero

    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
  • #161247

    Participant
    Topics: 1
    Replies: 5
    Points: 22
    Rank: Member

    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,

  • #161264
    js

    Participant
    Topics: 25
    Replies: 678
    Points: 1,629
    Helping Hand
    Rank: Community Hero

    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?

  • #161265

    Participant
    Topics: 2
    Replies: 54
    Points: 278
    Helping Hand
    Rank: Contributor

    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?

  • #161271

    Participant
    Topics: 1
    Replies: 5
    Points: 22
    Rank: Member

    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
  • #161276

    Participant
    Topics: 1
    Replies: 1530
    Points: 2,591
    Helping Hand
    Rank: Community Hero

    You like to make it harder than necessary, don't you? 😉 😀 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.

  • #161277

    Participant
    Topics: 1
    Replies: 5
    Points: 22
    Rank: Member

    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 😉

     

  • #161279
    js

    Participant
    Topics: 25
    Replies: 678
    Points: 1,629
    Helping Hand
    Rank: Community Hero

    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
    
  • #161283

    Participant
    Topics: 1
    Replies: 5
    Points: 22
    Rank: Member

    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

     

  • #161288
    js

    Participant
    Topics: 25
    Replies: 678
    Points: 1,629
    Helping Hand
    Rank: Community Hero

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

  • #161289

    Participant
    Topics: 1
    Replies: 5
    Points: 22
    Rank: Member

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

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

  • #161355

    Participant
    Topics: 0
    Replies: 13
    Points: 43
    Helping Hand
    Rank: Member

    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
    }

The topic ‘Add to Hashtable in Loop’ is closed to new replies.