Dalebert
Dalebert

Reputation: 35

Adding array elements to a PSObject

Preface: I haven't any formal training with script writing. So I'm sure many of you will be banging you head against the table wondering what I'm doing.

I am working to gather information on our current catalog of Teams sites, and respective site owners. I have a PS script to gather the list of sites, then it loops through each site to get list of owners. After I gather that owner list (stored in a var) I loop through that var to get the user name and store each user name in an array as a new element. That element is then used later when adding a new member to a PSObject so I can export the results to a CSV. Here's a bit of the code;

#Var's
    $Count = 1
    $TSO = New-Object PSObject
    $SiteOwner = @("SiteOwner0","SiteOwner1","SiteOwner2","SiteOwner3","SiteOwner4","SiteOwner5","SiteOwner6","SiteOwner7") #Array to create column headers in the CSV
    
#STEP 1: Get a list of the sites
    $Sites = get-team | sort-object DisplayName

#STEP 2: Get a list of the owners of the different sites
    FOREACH ($i in $Sites){
            $h = Get-TeamUser -GroupID $i.GroupID | Where {$_.role -eq "Owner"}
            $Count += 1

            Write-Host . -ForeGroundColor "Cyan" -NoNewLine
            #Add the new columns to $TSO
            $TSO | Add-Member -MemberType NoteProperty -Name "SiteName" -Value $i.DisplayName -Force
            $TSO | Add-Member -MemberType NoteProperty -Name "GroupOwner" -Value $i.Description -Force
            $TSO | Add-Member -MemberType NoteProperty -Name "Visibility" -Value $i.Visibility -Force
            $TSO | Add-Member -MemberType NoteProperty -Name "Archived" -Value $i.Archived -Force
            $TSO | Add-Member -MemberType NoteProperty -Name "SiteEmail" -Value $i.MailNickname -Force

            #loop through each member to discover the assigned role
            FOREACH ($o in $h){
                Write-Host . -ForeGroundColor "Cyan" -NoNewLine
                #Build the dynamics of the owners before passing to $TSO
                $OHolder += $o.user
                } #END NESTED FOREACH
                
                #Handle BLANK elements in the $OHolder array
                #The number 8 is the number of array elements we need a value for
                $Comp = 0
                
                While($Comp -lt 8){
                
                If($OHolder[$Comp] -ne $null){
                    $TSO | Add-Member -MemberType NoteProperty -Name $SiteOwner[$Comp] -Value $OHolder[$Comp] -Force
                    }
                ELSEIF(-not ($OHolder[$Comp])){
                    $OHolder[$Comp] = "NA"
                    $TSO | Add-Member -MemberType NoteProperty -Name $SiteOwner[$Comp] -Value $OHolder[$Comp] -Force
                    }
                    
                    #Increment the $Comp
                    $Comp += 1
                    
                }#END WHILE

                #Resetting the $Comp outside the loop
                $Comp = 0
#************* END STEP 2 *************************
            
            #Squirt out the info to a CSV
            $TSO | Export-CSV -Path $OPathOut -NoTypeInformation -Append -Force
            
            #Reset the $OHOLDER Array
            $OHolder = @()
    } #END FOREACH

My problem is this; When adding the site owner to the PSObject for siteowner ($TSO | Add-Member -MemberType NoteProperty -Name $SiteOwner[$Comp] -Value $OHolder[$Comp] -Force) it's counting each character of the value as an element.

For example: $OHolder will have two elements, $OHolder[0] is supposed to equal "[email protected]" and $OHolder[1] is suppose to equal "[email protected]". What actually happens is the length of the array becomes 29 (for each character) rather than 2.

How can I add the users to the PSObject as intended? Right now the output will have:

SiteOwner0 | SiteOwner1 | SiteOwner2
d          | o          | e
@          |d           |o

Upvotes: 1

Views: 1231

Answers (2)

AdminOfThings
AdminOfThings

Reputation: 25001

Do not use += to add items to an array. It is inefficient if the arrays become large. A new array is created each time after the current array contents are read into memory. You can simply output each item inside of the foreach and assign the array variable to the foreach output.

$OHolder = @(FOREACH ($o in $h){
    Write-Host . -ForeGroundColor "Cyan" -NoNewLine
    #Build the dynamics of the owners before passing to $TSO
    $o.user # Output 
})

In the simplistic example above, a loop is likely not even necessary as $OHolder = ,$h.user should suffice in PowerShell v3+.

Upvotes: 1

YannCha
YannCha

Reputation: 241

You are not defining $OHolder variable before using += operator.

By default powershell seems to define a string variable in this case.

$undefVar = $null
$undefVar += "test"
$undefVar += "some"
# content of $undefVar is now testsome

Try to move $OHolder = @() before the loop FOREACH ($o in $h){

Upvotes: 0

Related Questions