Add to Hashtable in Loop

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

  • This topic has 12 replies, 5 voices, and was last updated 1 year ago by
    Participant
    .
Viewing 12 reply threads
  • 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: 5
      Replies: 2368
      Points: 5,987
      Helping Hand
      Rank: Community MVP

      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: 30
      Replies: 828
      Points: 2,554
      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
      Senior Moderator
      Topics: 3
      Replies: 123
      Points: 653
      Helping Hand
      Rank: Major 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: 5
      Replies: 2368
      Points: 5,987
      Helping Hand
      Rank: Community MVP

      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: 30
      Replies: 828
      Points: 2,554
      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        [email protected]    COMP01       comp01.powershell.org
      js1        [email protected]    COMP02       comp02.powershell.org
      js2        [email protected]    COMP01       comp01.powershell.org
      js2        [email protected]    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: 30
      Replies: 828
      Points: 2,554
      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
      }
Viewing 12 reply threads
  • The topic ‘Add to Hashtable in Loop’ is closed to new replies.