【问题标题】:Using ref in powershell to return values from function在 powershell 中使用 ref 从函数返回值
【发布时间】:2016-08-02 07:59:57
【问题描述】:

我有一个函数 DoWork,它创建一个对象并将其保存在 $AllMailboxes 变量中。然后在该函数中,我执行另一个函数 ProcessEmail,它应该从 $AllMailboxes 中取出 $Mailbox 并通过 ref 变量,向其中添加几个字段,然后更新 $AllMailboxes 或创建新的 $collection,然后保存所有 $包含更新字段的邮箱

$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
}

我尝试了多个使用 ref 的方法,没有 ref,创建单独的变量,但由于某种原因,我不能让它在 $collection 或其他方式中显示任何东西,而不是 ProcessEmail 函数。我确定我错过了什么。

【问题讨论】:

    标签: arrays powershell pscustomobject


    【解决方案1】:

    您通过使用 PSReference 使其变得更加复杂(这需要您访问 value 属性)。到目前为止,您无需在这里。

    也几乎不需要使用该全局/脚本变量,除非作为 DoWork 的分配,如本模型所示。

    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
    

    克里斯

    【讨论】:

    • 是的,我认为它过于复杂。我已经修改了我的代码以使用更简单的方法:-)
    • 但是为了学习,我想知道在主对象更新的地方正确使用 ref,然后我可以随意分配它。
    • PSObject 是一个不好的示例,因为它具有一定程度的持久性,因此该示例通过 PSReference 调整包含整数的变量中的值。 codefunction one { [Int]$one = 1;两个([参考]$一个); $一个};函数二 ([Ref]$two) { $two.Value = 2 };一个
    • 修复标记。 function one { [Int]$one = 1; two ([Ref]$one); $one }; function two ([Ref]$two) { $two.Value = 2 }; one
    【解决方案2】:

    似乎您缺少范围。至少将其更改为脚本范围,如下所示:

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

    【讨论】:

    • 它似乎表现得更好,但它只显示了我在处理电子邮件中添加的 2 个字段,并且没有显示之前属于 $Mailbox 的所有其他字段?另外,也许我也应该通过 ref 传递 $collection 吗?最好的方法是什么?
    • 似乎添加了新字段,但所有邮箱字段现在都存储在值内.. @{Alias=weronika.palowska;名称=Weronika Palowska;。所以 $Mailbox 有 3 个字段,2 个新字段和 Value 中的所有其他字段。扩展字段以添加 2 个字段的正确方法是什么
    • $邮箱 | Add-Member -MemberType NoteProperty -Name NewEmailToAdd -Value $FullEmail - 这似乎没有添加另一个字段
    • 你也可以试试 pass ref collection。
    【解决方案3】:

    其实我已经决定去

    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
    }    
    

    然后简单地过去:

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

    似乎工作得很好。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-12-16
      • 1970-01-01
      • 2012-09-06
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多