【问题标题】:Getting the SMTP address for all Display Names in a Distribution Group when there is a Special Character in the Display Name当显示名称中有特殊字符时,获取通讯组中所有显示名称的 SMTP 地址
【发布时间】:2020-01-30 08:53:26
【问题描述】:

所以,我回来询问有关获取已接受发件人、ModeratedBy 和 ManagedBy 的通讯组 SMTP 地址的更多问题。

所以我得到的脚本几乎可以完美运行。但是,当我使用显示名称从 acceptmessagesonlyfromsendorsormembers 中提取 smtp 地址列表时,除非名称中包含特殊字符或其他空格,否则它会起作用。所以显示名称的格式是“Last, First”,只要格式遵循这个规则,我们就可以了。但是,如果姓氏中有空格,例如“Mac Gruber, Steven”或“#IT-Dept”,则不会获取 SMTP 地址。

我很确定问题出在我用来从 acceptmessagesonlyfromsendersormembers 属性中列出的规范名称列表中获取显示名称的拆分逻辑中。

脚本如下。

$props = @(
    "DisplayName"
    "SamAccountName"
    "PrimarySmtpAddress"
    @{n='Accepted Senders';e= {($_.acceptmessagesonlyfromsendersormembers | Foreach-Object {
    (Get-AdUser -Filter "DisplayName -eq '$($_.Split('/')][-1])'" -Property ProxyAddresses |
        Select-Object -Expand ProxyAddresses | Where-Object {$_ -cmatch '^SMTP:'}) -replace '^SMTP:'}) -join '; '}}
    "ModerationEnabled"
    @{N="ModeratedBy";E= {($_.ModeratedBy | ForEach-Object {
    (Get-AdUser -Filter "DisplayName -eq '$($_.Split("/")[-1])'" -Property ProxyAddresses |
        Select-Object -Expand ProxyAddresses | Where-Object {$_ -cmatch '^SMTP:'}) -replace '^SMTP:'}) -join '; '}}
    @{Name="Internal Senders Only";E={$_.RequireSenderAuthenticationEnabled}}
    @{N="ManagedBy";E= {($_.ManagedBy | ForEach-Object {
    (Get-AdUser -Filter "DisplayName -eq '$($_.Split("/")[-1])'" -Property ProxyAddresses |
        Select-Object -Expand ProxyAddresses | Where-Object {$_ -cmatch '^SMTP:'}) -replace '^SMTP:'}) -join '; '}}
        )
Get-DistributionGroup -ResultSize Unlimited | Select-Object $props -First 1000 | export-Csv x:\xxx.csv -NoTypeInformation

一如既往,我们非常感谢任何帮助。

瑞恩

【问题讨论】:

  • 所以我想真正的问题是......当 Get-ADUser 接受 -identity 参数的 DistinguishedName 时,您为什么要尝试从 DistinguishedName 中解析 DisplayName,所以您甚至不需要使用-filter,它只是Get-ADUser $_ -property ProxyAddresses
  • 好的,尝试使用您建议的方法进行更新,但它没有返回任何接受的发件人的电子邮件地址,由管理或主持。作为参考,这里是我更新的内容。我无法复制整个内容,所以我只是把我从接受的发件人 $prop @{ n="Accepted Senders" e={($_.acceptmessagesonlyfromsendersormembers | Foreach-Object { (Get-AdUser $_ -property ProxyAddresses | Select -Expand ProxyAddresses | Where-Object {$_ -cmatch '^SMTP:'}) -replace '^SMTP:'}) -join ';'} } 中更改的内容
  • 抱歉,输出的不是 DistinguishedName,而是 CanonicalName,Get-ADUser 不接受我能确定的 CN。另外,我似乎也无法过滤它。如果你有办法做到这一点,那就太棒了。
  • 编辑帖子以反映 CN 而不是 DN

标签: powershell exchange-server-2013


【解决方案1】:

好的,所以问题是您的 cmdlet 正在输出 CanonicalName,这是一个计算属性,而不是实际存储在 AD 中的内容。在 JRV 的回答 here 的帮助下,我们有一个函数可以将 CanonicalName 转换为 DistinguishedName。 DN 可以直接传递给Get-ADUser,这样可以简化事情。首先是函数,稍作修改以很好地接受管道输入:

Function Convert-CanonicalName{   
    Param(
            [Parameter(Mandatory, ValueFromPipeline)]
            [string[]]$CanonicalName
    )
BEGIN{
    Try{
        $NameTranslate = New-Object -ComObject NameTranslate
        [void]$NameTranslate.GetType().InvokeMember('Init', 'InvokeMethod', $NULL, $NameTranslate, @(3, 2))
    }
    Catch{
        Throw $_
    }
}
PROCESS{
    ForEach($User in $CanonicalName){
        Try{
            [void]$NameTranslate.GetType().InvokeMember('Set', 'InvokeMethod', $NULL, $NameTranslate, @(8,$User))
            $NameTranslate.GetType().InvokeMember('Get', 'InvokeMethod', $NULL, $NameTranslate, @(1))
        }
        Catch{
            Throw $_
        }
    }
}
}

这允许我们将'MyDomain.Net/Users/Big Jimmy' 之类的东西通过管道传递到函数中,并让它将'CN=Big Jimmy,OU=Users,DC=MyDomain,DC=Net' 返回到管道。

继续,让我们采用您的计算属性之一:

@{n='Accepted Senders';e= {($_.acceptmessagesonlyfromsendersormembers | Foreach-Object {
(Get-AdUser -Filter "DisplayName -eq '$($_.Split('/')][-1])'" -Property ProxyAddresses |
    Select-Object -Expand ProxyAddresses | Where-Object {$_ -cmatch '^SMTP:'}) -replace '^SMTP:'}) -join '; '}}

现在,我们实际上不需要 ForEach-Object 循环。这里的一切都将采用一系列事物并处理每个项目并将其适当地传递到管道中。所以我将放弃它,为了便于阅读,我将把管道的每个部分放在自己的行上。我们要做的是从$_.acceptmessagesonlyfromsendersormembers 获取CanonicalNames 输出,将其通过管道传输到将它们转换为DN 的新函数,将其通过管道传输到Get-ADUser,展开属性,过滤SMTP,清理字符串,然后加入它们.

@{n='Accepted Senders';e= {($_.acceptmessagesonlyfromsendersormembers | 
    Convert-CanonicalName |
    Get-AdUser -Property ProxyAddresses |
    Select-Object -Expand ProxyAddresses | 
    Where-Object {$_ -cmatch '^SMTP:'}) -replace '^SMTP:' -join '; '}}

您应该能够以类似的方式修改您的其他项目并获得相同的结果。诚然,我没有要测试的 Exchange 服务器,但是如果您要获得一组 CN,那么这应该可以完成这项工作。

【讨论】:

  • 效果很好!但是,我有一个问题,也许您可​​以提供帮助。我们目前正在使用 Get-ADUser 为接受的发件人列表中的每个用户提取 SMTP 地址。但是,有时该组本身是被接受的发件人。发生这种情况时,我们不会获得用户的 SMTP 地址,因为他们不是 AD 用户,只是通过电子邮件发送的启用对象。无论如何,你能想办法为那些获取 SMTP 地址吗?我们正在尝试使用邮件收件人而不是 Get-ADUser,但它不合作。大声笑
  • 总是有Get-ADObject -Property ProxyAddresses,您也可以像Get-ADUser 一样通过管道将DN 传递给它。这样就可以找到 DL 和用户,问题就解决了。
  • 所以,我们有了解决方案,切换到 Get-ADObject 解决了最后的问题。我想指出的是,我们还找到了实现相同结果的辅助解决方案。我把它包括在这里供参考。 @{Name = 'Accepted Senders'; Expression = {($_.acceptmessagesonlyfromsendersormembers | Foreach-Object {(Get-Recipient -Identity ($_ -split $separator)[-1] | Select primarySMTPaddress).primarysmtpaddress}) -join ','}}, 引用的分隔符实际上是“domain.com”
猜你喜欢
  • 1970-01-01
  • 2012-05-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多