0

I've function DoWork which creates an object and keeps it in $AllMailboxes variable. Then within that function I execute another function ProcessEmail which is supposed to take $Mailbox out of $AllMailboxes and variable by ref, add couple of fields to it and either update $AllMailboxes or create new $collection which then holds all $Mailbox with updated fields

$collection = @()

function DoWork() { 
    Get-User -ResultSize Unlimited | Where { $_.RecipientType -eq 'UserMailbox' } | ForEach { $Users = @{} } { $Users[$_.SamAccountName] = $_ }
    $AllMailboxes = Get-Mailbox -ResultSize Unlimited | Where { $_.RecipientTypeDetails -eq "UserMailbox" } | ForEach {
    $PrimarySmtpDomain = $_.PrimarySmtpAddress.split("@")

    New-Object psobject | 
        Add-Member -PassThru NoteProperty Alias $_.Alias | 
        Add-Member -PassThru NoteProperty Name $_.Name |        
        Add-Member -PassThru NoteProperty DisplayName $_.DisplayName 
        Add-Member -PassThru NoteProperty .... other values
     foreach ($mailbox in $allmailboxes) {
         $FullEmail = "somestring"
         ProcessEmail ([ref] $Mailbox) ($FullEmail)
     }
     $collection | ft # doesn't display anything


}

function ProcessEmail ([ref] $Mailbox, $FullEmail) {
    $RequireAdd = $true
    $addresses = $Mailbox.EmailAddresses
    foreach ($address in $addresses) {
        if ($address -imatch "sip:") { continue }
        if ($address -ireplace("smtp:","") -ieq $FullEmail) {
            $requireAdd = $false
            break
    }

    $Mailbox | Add-Member -MemberType NoteProperty -Name NewEmailToAdd -Value $FullEmail 
    $Mailbox | Add-Member -MemberType NoteProperty -Name NewEmailRequiresAdding -Value $RequireAdd  
    $Mailbox.NewEmailToAdd # displays correctly
    $Mailbox.NewEmailRequiresAdding #display correctly
    $collection += $Mailbox
}

I've tried multiple approces with ref, without ref, creating separate variables but I can't for some reason make it to display anything in $collection or in other means outsied of ProcessEmail function. I'm sure I'm missing something.

3 Answers 3

1

You're making it more complex by using PSReference (which would need you to access the value property). You have no need to here so far.

There's also little need to use that global / script variable except perhaps as an assignment from DoWork as shown in this mock up.

function DoWork {
    foreach ($i in (1..100)) {
        $psObject = [PSCustomObject]@{
            Property1 = 1
            Property2 = 2
        }

        ProcessEmail -Mailbox $psObject -FullEmail $FullEmail

        $psObject
    }
}

function ProcessEmail {
    param(
        $Mailbox,
    )

    $Mailbox | Add-Member NewProperty1 "one"
    $Mailbox | Add-Member NewProperty2 "two"
}

$collection = DoWork

Chris

Sign up to request clarification or add additional context in comments.

4 Comments

Yes, i thought it's over complex. I've revised my code to use simpler approach :-)
But for the sake of learning I wanted to know hot to use ref properly where main object is updated and I can then assign it as I want to.
PSObject is a bad example in that it has a degree of persistence, so this example adjusts the value in a variable containing an integer by way of a PSReference. codefunction one { [Int]$one = 1; two ([Ref]$one); $one }; function two ([Ref]$two) { $two.Value = 2 }; one
Fixing mark down. function one { [Int]$one = 1; two ([Ref]$one); $one }; function two ([Ref]$two) { $two.Value = 2 }; one
1

Seems like you are missing scope. Change it to at least script scope, like this:

$script:collection = @()
$script:collection += $Mailbox

4 Comments

It seems to act better but it only shows 2 fields I added in process email and doesn't show all others that were part of $Mailbox before? Also maybe I should pass $collection by ref as well ? What is best approach to this?
It seems new fields were added but all Mailbox fields are stored inside value now.. @{Alias=weronika.palowska; Name=Weronika Palowska;. So the $Mailbox has 3 fields, 2 new ones and all the other fields within Value.. what would be proper way to expand fields to add 2 more fields
$Mailbox | Add-Member -MemberType NoteProperty -Name NewEmailToAdd -Value $FullEmail - this doesn't seem to add another field
You could try pass ref collection as well.
0

I've actually decided to go

function ProcessEmail ($Mailbox, $FullEmail) {
    $RequireAdd = $true
    $addresses = $Mailbox.EmailAddresses
    foreach ($address in $addresses) {
        if ($address -imatch "sip:") { continue }
        if ($address -ireplace("smtp:","") -ieq $FullEmail) {
            $requireAdd = $false
            break
        }
    }
    $Mailbox | Add-Member -MemberType NoteProperty -Name NewEmailToAdd -Value $FullEmail 
    $Mailbox | Add-Member -MemberType NoteProperty -Name NewEmailRequiresAdding -Value $RequireAdd  
    return ,$mailbox
}    

And simply go by:

$Mailbox = ProcessEmail ($Mailbox) ($FullEmail)
$collection += $Mailbox

Seems to work just fine.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.