Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

creating PowerShell custom objects

I created a custom object in PowerShell. I was able to solve the problem I wanted to solve. I wanted to have an object with two columns, one for the site collection, one for the email.

However, I am wondering if there is an easier solution. Do you have any suggestions?

Here is my code:

$cred = Get-Credential

Connect-PnPOnline "https://tenant.sharepoint.com" -Credentials $cred
$SiteCollections = Get-PnPTenantSite

$object = @()

foreach ($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
    $object += $obj
}

Write-Output $object
like image 851
Zoltán Avatar asked Nov 06 '17 21:11

Zoltán


2 Answers

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
}})
like image 84
Ansgar Wiechers Avatar answered Oct 09 '22 15:10

Ansgar Wiechers


Shortening the code a bit:

$cred = Get-Credential
Get-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.

like image 29
Bill_Stewart Avatar answered Oct 09 '22 14:10

Bill_Stewart