#arrays #powershell #active-directory #exchange-server
#массивы #powershell #active-directory #exchange-сервер
Вопрос:
Я относительно новичок в Powershell, но не смог найти ответ в Интернете.
Я пытаюсь получить количество электронных писем на одного отключенного пользователя в Exchange 2010, но также необходимо получить заголовок пользователя в форме AD, поскольку организация группирует пользователей по типу, используя атрибут Title в AD
Я написал следующее, но я не могу получить нужные мне данные, он просто возвращает длину и числа в файл 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:userprofiledesktopDisabledADUserTitlewithMailbox.csv -NoTypeInformation
К сожалению, работа с кодом, предоставленным Стивом, приводит к следующим ошибкам
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"...
Редактировать
С помощью Стивена я смог заставить это работать со следующим
'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:userprofiledesktopDisabledADUserTitlewithMailbox.csv -NoTypeInformation
Комментарии:
1. Ваш CSV содержит только
Length
, потому что вы отправляете только строки вExport-Csv
.Export-Csv
просматривает первый объект в конвейере и принимает его свойства в качестве заголовков для файла CSV. Затем извлекает значение каждого свойства и выводит их для каждого объекта (по одному объекту в строке). Строка имеет толькоLength
свойство. Итак, результат, который вы видите, ожидаемый.2. Спасибо @AdminOfThings за объяснение.
Ответ №1:
Похоже, что вы действительно пытаетесь связать данные для создания небольшого отчета. Вы имеете дело с данными, поступающими из разных команд, поэтому вам нужно свойство для объединения. В этом случае я бы посмотрел на атрибут AD legacyExchangeDN и свойство LegacyDN , возвращаемое Get-MailboxStatistics
. Код может выглядеть примерно так:
$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, просто добавьте Export-CSV
команду после Select-Object
команды, как показано ниже:
$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:userprofiledesktopDisabledADUserTitlewithMailbox.csv -NoTypeInformation
Я бы использовал Get-User
из командной строки Exchange, однако у нее нет legacyExchangeDN в качестве возвращаемого свойства. У него есть sAMAccountName , но его использование вынудило бы меня соединить все Get-Mailbox
. В любом случае, это очень распространенный метод использования хэш-таблицы для ссылки на связанные значения в другой коллекции.
Я уверен, что потребуется некоторая дополнительная работа, чтобы получить правильный отчет.
Кроме того, старайтесь избегать использования =
оператора для добавления массивов. Лучший способ получить массив — позволить PowerShell предоставить его, как я сделал выше. Однако, если вы не можете обойти это, наиболее распространенной альтернативой является ArrayList. Как и в большинстве случаев, есть несколько способов сделать это, ниже приведен всего 1 пример.
# To create:
$ArrList = [Collections.ArrayList]@()
#To Add a value:
[Void]$ArrList.Add( 'ValueOrObjectHere' )
Примечание: Документация / обсуждение
=
и ArrayList легко доступны
найдите с помощью компьютера Google…
Обновить:
Устранение ошибок, отмеченных в самой последней правке:
Первая ошибка в принципе невозможна. Простите меня, но я должен предположить, что вы допустили какую-то ошибку, вызвавшую эту ошибку. legacyExchangeDN всегда должен начинаться с '/o=...'
, и их ключом, на который ссылается ошибка, было ‘ADCDisabledMail’ . Кроме того, LegacyExchangeDNs, естественно, уникальны в Active Directory, поэтому почти нет шансов, что у вас будет дубликат. Таким образом, я не прилагал никаких усилий, и ни одно из них не гарантировано, для предотвращения такой маловероятной ошибки.
Примечание: Если вы повторно тестируете код, вам придется воссоздавать хэш,
$DisabledUsers = @{}
иначе хэш будет существовать с предыдущего запуска, и повторяющиеся ключевые ошибки неизбежны…
Вторая ошибка «ключ не может быть нулевым» может быть связана с тем, что учетные записи AD, не включающие почтовые ящики, в указанном подразделении фактически приводят к тому, что атрибут legacyExchangeDN имеет значение null для этих пользователей. Следовательно, нулевой ключ…. Этого можно избежать, изменив фильтр, чтобы возвращать только пользователей с поддержкой почты:
$disUsers = Get-ADUser -Filter { mailNickName -like '*' } -SearchBase "ou=User Disabled Accounts,dc=test,dc=com" -Properties SamAccountName,Title
Примечание: Для справки, mailNickName обычно является псевдонимом propertry
возвращается сGet-Mailbox
Комментарии:
1. Спасибо за вашу помощь, я попробовал ваше решение, но оно выдает следующие ошибки, и результирующий CSV-файл пуст. Я добавил ошибки в свой первый пост в качестве редактирования, поскольку раздел комментариев не будет принимать полную ошибку
2. Спасибо @Steven, код был выполнен, как указано, и возвращены ошибки. Я понимаю, что вторая ошибка может быть связана с отсутствием пользователей с поддержкой почты, я новичок в организации, и мне сообщили, что у всех была включена почта.
3. Я ценю то, что вам сказали, но вы можете легко подтвердить это, отключив фильтр ;
-Filter { mailNickName -notlike '*' }
. Это сообщит вам, есть ли в данном подразделении пользователи, не являющиеся почтовыми ящиками. Примечание: legacyExchangeDN является обязательным свойством в среде Exchange. Если бы это было действительно null, у вас были бы всевозможные другие проблемы. Я чего-то не понимаю; вы используете Office 365? Можете ли вы попробовать выполнить запрос без добавления в хэш-таблицу? Также запустите отрицательный фильтр, как описано, и дайте мне знать, что возвращается. Примечание: Код отлично работает в моей среде…4. Привет @Steven извините за задержку, я столкнулся с другой проблемой. Организация доступна только для Exchange, но мы используем Office 365 для Outlook и других приложений Office. Мне не удалось успешно запустить ваш код, но я смог воспользоваться идеей и изменить свой исходный код, чтобы получить то, что мне было нужно, я включил это в редактирование моего вопроса, так что большое спасибо. Что касается значения ADCDisabledMail для legacyExchangeDN, я изучаю это, это может быть из предыдущего обновления Exchange, и, поскольку мы скоро снова обновим его, я обязательно проверю.
5. Я рад, что это сработало! Урок важнее, чем то, работал ли мой конкретный код в вашей среде.