creating PowerShell custom objects creating PowerShell custom objects powershell powershell

creating PowerShell custom objects


Objects can be constructed from a hashtable either with the New-Object cmdlet:

$obj = New-Object -Type PSObject -Property @{    'Url'   = $SiteCollection.Url    'Email' = $email}

or (if you have PowerShell v3 or newer) the [PSCustomObject] type accelerator:

$obj = [PSCustomObject]@{    'Url'   = $SiteCollection.Url    'Email' = $email}

Also, you can simply output the objects inside the loop and collect the entire loop output in a variable like this:

$object = @(foreach ($SiteCollection in $SiteCollections) {    ...    New-Object -Type PSObject -Property @{        'Url'   = $SiteCollection.Url        'Email' = $email    }})

The array subexpression operator (@()) around the foreach loop ensures that the result is an array, even if the loop output is less than 2 objects.

Using a calculated property would be another option:

$object = @(Get-PnPTenantSite | Select-Object Url, @{n='Email';e={    Connect-PnPOnline -Url $_.Url -Credentials $cred | Out-Null    Get-PnPRequestAccessEmails}})


Shortening the code a bit:

$cred = Get-CredentialGet-PnPTenantSite | ForEach-Object {  Connect-PnPOnline -Url $_.Url -Credentials $cred  [PSCustomObject] @{    Url = $_.Url    Email = Get-PnPRequestAccessEmails  }}

The [PSCustomObject] type accelerator only exists in PowerShell 3.0 and later.


Especially if your array is going to get very large, you might want to consider using an arraylist instead of a vanilla array. With a standard array, every time you add data to it, it recreates the whole array, as opposed to just tacking your data on the end. An arraylist simply appends and is much faster for building large arrays.

$outArray = New-Object System.Collections.ArrayListforeach ($SiteCollection in $SiteCollections) {    Connect-PnPOnline -Url $SiteCollection.Url -Credentials $cred    $email = Get-PnPRequestAccessEmails    Write-Host "Email for $($SiteCollection.Url): $($email)"    $obj = New-Object System.Object    $obj | Add-Member -type NoteProperty -name Url -value $SiteCollection.Url    $obj | Add-Member -type NoteProperty -name Email -value $email    [void]$outArray.Add($obj)}