Reputation: 135
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
Upvotes: 12
Views: 15476
Reputation: 47
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.ArrayList
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
[void]$outArray.Add($obj)
}
Upvotes: 0
Reputation: 200193
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
}})
Upvotes: 21
Reputation: 24515
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.
Upvotes: 3