【问题标题】:Cannot add items to Powershell array无法将项目添加到 Powershell 数组
【发布时间】:2020-12-23 23:32:36
【问题描述】:

我对 Powershell 比较陌生,但一直无法在网上找到答案。

我正在尝试获取每个禁用用户的电子邮件数量以交换 2010,但还需要获取用户的标题表单 AD,因为组织使用 AD 中的 Title 属性按类型对用户进行分组

我已经编写了以下内容,但无法获得所需的数据,它只是将长度和数字返回到 CSV 文件,例如 “长度” “10” “3” “34”

如果我将 $title 排除在 $Disabled+= 的分配之外,则用户名和项目计数将添加到 csv 文件中,但我也确实需要标题。谁能指出我哪里出错了。

Import-Module ActiveDirectory

$i=0

$disUsers = Get-ADUser -Filter * -SearchBase "ou=User Disabled Accounts,dc=test,dc=com" -Properties SamAccountName,Title

$Disabled = @()

$disUsers | Foreach-Object{      
    $sam = $_.SamAccountName
    $title = $_.Title
    $mailDetail=Get-MailboxStatistics $sam | Select -Property DisplayName,ItemCount
    $Disabled += $title, $mailDetail
    $i++;   
 }


$Disabled | Export-Csv -Path $env:userprofile\desktop\DisabledADUserTitlewithMailbox.csv -NoTypeInformation

不幸的是,使用 Steve 提供的代码会出现以下错误

Exception calling "Add" with "2" argument(s): "Item has already been added. Key in dictionary: 'ADCDisabledMail'  Key being added: 'ADCDisabledMail'" ...     

Exception calling "Add" with "2" argument(s): "Key cannot be null. Parameter name: key"...

编辑 在 Steven 的帮助下,我能够通过以下方式完成这项工作

'Import-Module ActiveDirectory' 

$i=0

$disUsers=Get-ADUser -Filter {mailNickName -like '*'} -SearchBase "ou=User Disabled Accounts,dc=test,dc=com" -Properties SamAccountName,Title 

$dis2 = $disUsers.count

$DisabledUser = @()

$disUsers | Foreach-Object{

Write-Host "Processing record $i of $dis2"

                $sam = $_.SamAccountName

                $title = $_.Title

$mailDetail=Get-MailboxStatistics $sam | Select-Object DisplayName, @{ Name = 'Title'; Expression = {$title}}, ItemCount  

                                $DisabledUser+= $mailDetail
  $i++;   

}

$DisabledUser | Export-Csv -Path $env:userprofile\desktop\DisabledADUserTitlewithMailbox.csv -NoTypeInformation

【问题讨论】:

  • 您的 CSV 仅包含 Length,因为您仅向 Export-Csv 发送字符串。 Export-Csv 查看管道中的第一个对象并将其属性作为 CSV 文件的标题。然后检索每个属性的值并为每个对象输出它们(每行一个对象)。一个字符串只有一个Length 属性。所以你看到的结果是预期的。
  • 感谢@AdminOfThings 的解释。

标签: arrays powershell active-directory exchange-server


【解决方案1】:

听起来您真正想做的是关联数据以创建一个小报告。您正在处理来自不同命令的数据,因此您需要一个属性来加入。在这种情况下,我将查看由Get-MailboxStatistics 返回的 LegacyExchangeDN AD 属性和 LegacyDN 属性。代码可能类似于:

$DisabledUsers = @{}

Get-ADUser -SearchBase 'ou=User Disabled Accounts,dc=test,dc=com' -Filter * -Properties 'Title','legacyExchangeDN' |
ForEach-Object{ $DisabledUsers.Add( $_.legacyExchangeDN, $_ ) }

$DisabledUsers.Values.SamAccountName | 
Get-MailboxStatistics |
Select-Object DisplayName, ItemCount, @{ Name = 'Title'; Expression = { $DisabledUsers[$_.LegacyDN].Title } }

这将输出如下内容:

DisplayName   ItemCount Title
-----------   --------- -----
Mr. Smith        113576 Executives

如果您希望它直接转到 CSV 文件,只需在 Select-Object 命令之后添加 Export-CSV 命令,如下所示:

$DisabledUsers = @{}

Get-ADUser -SearchBase 'ou=User Disabled Accounts,dc=test,dc=com' -Filter * -Properties 'Title','legacyExchangeDN' |
ForEach-Object{ $DisabledUsers.Add( $_.legacyExchangeDN, $_ ) }

$DisabledUsers.Values.SamAccountName | 
Get-MailboxStatistics |
Select-Object DisplayName, ItemCount, @{ Name = 'Title'; Expression = { $DisabledUsers[$_.LegacyDN].Title } } |
Export-CSV -Path $env:userprofile\desktop\DisabledADUserTitlewithMailbox.csv -NoTypeInformation

我会使用 Exchange 命令行管理程序中的 Get-User,但是它没有 LegacyExchangeDN 作为返回的属性。它确实有 SamAccountName,但使用它会迫使我通过Get-Mailbox 连接所有内容。无论如何,这是使用哈希表引用不同集合中相关值的一种非常常见的技术。

我确信需要做一些额外的工作才能使报告恰到好处。

另外,尽量避免使用+= 运算符来追加数组。获取数组的最佳方法是让 PowerShell 像我上面那样提供它。但是,如果您无法绕过它,最常见的替代方案是 ArrayList。像大多数事情一样,有几种方法可以解决它,下面只是 1 个示例。

# To create:
$ArrList = [Collections.ArrayList]@()

#To Add a value:
[Void]$ArrList.Add( 'ValueOrObjectHere' )

注意:+= 和 ArrayList 的文档/讨论很容易 用谷歌机器找...

更新:

解决最近编辑中记录的错误:

第一个错误基本上是不可能的。原谅我,但我必须假设你犯了一些错误来产生这个错误。 LegacyExchangeDN 应始终以 '/o=...' 开头,错误引用的键是 'ADCDisabledMail' 。此外,LegacyExchangeDN 在 Active Directory 中自然是唯一的,因此您几乎不可能有重复。因此,我没有做出任何努力,也没有任何保证来防止这种不太可能发生的错误。

注意:如果您重复测试代码,则必须重新创建 散列,$DisabledUsers = @{} 否则散列将存在于 以前的运行和重复的键错误是肯定的......

第二个错误,他们的“密钥不能为空”可能是由于引用的 OU 中未启用邮箱的 AD 帐户有效地导致这些用户的 LegacyExchangeDN 属性为空。因此,空键....您可以通过修改过滤器以仅返回启用邮件的用户来避免这种情况:

$disUsers = Get-ADUser -Filter  { mailNickName -like '*' } -SearchBase "ou=User Disabled Accounts,dc=test,dc=com" -Properties SamAccountName,Title

注意:作为参考,mailNickName 通常是别名属性 返回Get-Mailbox

【讨论】:

  • 感谢您的帮助我已经尝试了您的解决方案,但它会引发以下错误并且生成的 CSV 为空。我已将错误添加到我的第一篇文章中作为编辑,因为评论部分不会包含完整的错误
  • 感谢@Steven,代码按照提供的方式运行,错误是返回的错误。我知道第二个错误可能是没有启用邮件的用户,我是该组织的新手,并被告知所有用户都启用了邮件。
  • 我很欣赏您被告知的内容,但您可以通过否定过滤器轻松确认; -Filter { mailNickName -notlike '*' }。这将告诉您给定 OU 中是否有非邮箱用户。注意:LegacyExchangeDN 是 Exchange 环境中的必需属性。如果它真的是空的,你会有各种各样的其他问题。有什么我不明白的吗?你使用 Office 365 吗?您可以尝试在不添加到哈希表的情况下运行查询吗?还按照描述运行否定过滤器,让我知道返回的内容。注意:代码在我的环境中运行良好...
  • 嗨@Steven 抱歉耽搁了,我遇到了另一个问题。该组织是仅用于 Exchange 的内部组织,但我们将 Office 365 用于 Outlook 和其他办公应用程序。我无法成功运行您的代码,但我能够接受这个想法并修改我的原始代码以获得我需要的东西,我已将它包含在我的问题的编辑中,非常感谢。至于 LegacyExchangeDN 的 ADCDisabledMail 值,我正在调查,它可能来自以前的 Exchange 升级,而且我们很快会再次升级,我一定会检查一下。
  • 我很高兴它成功了!教训比我的特定代码是否在您的环境中工作更重要。
猜你喜欢
  • 1970-01-01
  • 2018-08-03
  • 2010-11-25
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-10-21
相关资源
最近更新 更多