【问题标题】:PowerShell Office 365 Script to get user and mailbox information togetherPowerShell Office 365 脚本一起获取用户和邮箱信息
【发布时间】:2018-03-10 08:09:24
【问题描述】:

我是 PowerShell 的新手(今天早上开始)。我已成功连接到我的 Office 365,并且能够从 Office 365 获取用户列表,并从 Exchange 部分获取邮箱字段。我不知道如何将它们结合起来。

我正在寻找的是能够从邮箱对象中导出某些字段,但仅限于那些属于非阻止、许可的 Office 365 用户的邮箱。我们有很多用户的邮箱尚未删除,但他们可能不再获得许可或被阻止。

这是我现在运行的两个导出。它们是完整的出口。我尝试通过 isLicensed 过滤到 Office 265 用户,但我从未得到任何结果,所以我只是下载了所有内容并使用 Excel 对其进行了后期处理。但我需要定期运行它...

代码如下:

Get-Mailbox -ResultSize Unlimited | Select-Object DisplayName,Name,PrimarySMTPAddress,CustomAttribute2 | Export-CSV  C:\temp\o365\mailboxes.csv
Get-MsolUser -all | Select-Object SignInName, DisplayName, Office, Department, Title, IsLicensed | export-csv c:\temp\o365\Users.csv

任何帮助将不胜感激。

【问题讨论】:

  • 你能发布你目前拥有的代码吗?如果我们能具体看到您要使用的内容,可能会更有意义。
  • 刚刚添加了我的代码。我认为这是非常基本的。

标签: powershell office365 exchange-server


【解决方案1】:

好的,据我所知,您正在尝试做什么...您想要获取所有 O365 用户的列表,这些用户的 IsLicensed 属性为 $trueBlockCredential 属性为 $false .在这些用户中,您希望从他们的邮箱对象中提取一些数据; DisplayName、Name、PrimarySMTPAddress 和 CustomAttribute2。

我们有几种方法可以做到这一点。第一个更容易放在 shell 中,但实际运行需要更长的时间。第二个需要一些设置,但很快就能完成。

第一种方法

既然我们从Get-MsolUser 知道我们想要什么的标准是什么,我们将使用管道提取我们想要的东西并将其直接扔到Get-Mailbox

Get-MsolUser -All | Where-Object {$_.IsLicensed -eq $true -and $_.BlockCredential -eq $false} | 
Select-Object UserPrincipalName | 
ForEach-Object {Get-Mailbox -Identity $_.UserPrincipalName | Select-Object DisplayName,Name,PrimarySMTPAddress,CustomAttribute2}

O365 PowerShell 不喜欢给我们提供过滤初始查询的方法,所以我们在第二步中处理它,这里...

Where-Object {$_.IsLicensed -eq $true -and $_.BlockCredential -eq $false}

这意味着,对于从Get-MsolUser -All 传入的每个项目,我们只希望那些将属性Islicensed 设置为$true 和BlockCredential 设置为$false 的项目。

现在,就确定要查找的邮箱而言,我们只关心Get-MsolUser 的结果,因此我们将从与我们之前的过滤器匹配的每个对象中获取一个属性。

Select-Object UserPrincipalName

如果您只运行到目前为止的所有内容,您将在您的 shell 中获得一个 UPN 列表,用于我们现在将通过管道传输到 Get-Mailbox 的所有帐户。

继续我们的循环...如果您还没有学习ForEach-Object,它用于针对管道中的每个项目运行一个脚本块({} 之间的所有内容),一次一个。

Get-Mailbox -Identity $_.UserPrincipalName

欢迎来到管道运营商 ($_)。我们之前的Select-Object 正在通过管道提供一组对象,这个占位符变量将在我们处理它们时保存每个对象。由于这些对象都具有UserPrincipalName 属性,因此我们引用该属性以将值传递给Get-MailboxIdentity 参数。


侧边栏

这是一个如何工作的简单示例..

PS> 1,2,3 | ForEach-Object {Write-Host $_}
1
2
3

每个项目都沿着管道传递,我们一次写出一个。这与您的标准 foreach 循环非常相似。你可以在this Scripting Guy post了解更多关于它们的区别。

继续……


Select-Object DisplayName,Name,PrimarySMTPAddress,CustomAttribute2

我们用最后一个Select-Object 来总结您想要的信息。然后,您可以在 shell 中查看结果,或者通过管道将结果输入Export-Csv,以便在 Excel 中使用。

现在...由于管道是按顺序工作的,因此会产生一些开销。我们正在运行一个命令,收集结果,然后一次将这些结果传递给下一个命令。当我们到达我们的Get-Mailbox 时,我们实际上为我们收集的每个UPN 运行一次Get-Mailbox。在我的组织中,这大约需要 2.5 分钟,而我们的邮箱不到 500 个。如果您正在处理更大的数字,运行它的时间可能会增长得非常快。

第二种方法

由于第一种方法中的大量处理开销是使用管道,我们可以通过尽可能早和彻底地处理我们的数据收集来消除大部分开销。

$Users = Get-MsolUser -All | Where-Object {$_.IsLicensed -eq $true -and $_.BlockCredential -eq $false} | Select-Object -ExpandProperty UserPrincipalName
$Mailboxes = Get-Mailbox | Select-Object UserPrincipalName,DisplayName,Name,PrimarySMTPAddress,CustomAttribute2

$Results = foreach ($User in $Users) {
    $Mailboxes | Where-Object UserPrincipalName -eq $User
}

$Results | Export-Csv myFile.csv

前两行是不言自明的。我们获取我们关心的所有用户帐户信息(仅 UPN),然后我们获取我们关心的所有邮箱属性。

foreach ($User in $Users)

$Users 中的每个条目都将存储在 $User 中,然后我们将在随后的脚本块中使用它(在 {} 中)。

$Mailboxes | Where-Object UserPrincipalName -eq $User

$Mailboxes 中的每个项目都通过管道传输到Where-Object,然后我们检查UserPrincipalName 属性是否等于$User 的当前值。然后,所有匹配项都存储在 $Results 中,可以再次通过管道传输到 Export-Csv 以在 Excel 中工作。

虽然这种方法更难在 shell 中写出,并且需要一些额外的初始设置,但它的运行速度要快得多;我的组织需要 22 秒,而第一种方法需要 2.5 分钟。

我还应该指出,将UserPrincipalName 与邮箱数据集一起使用只是为了帮助确保它们与帐户数据集之间的可靠匹配。如果您不希望它出现在最终结果中,您可以随时将 $Results 传递到另一个 Select-Object 并仅指定您关心的属性。

希望这会有所帮助!

【讨论】:

  • 我确实有一个问题。假设我想将 $User 中的一些列添加到我的结果集中?例如,如果我想要职位、部门等...?我可以用第二种方法吗?
  • 在我脑海中浮现,并非没有重新研究这两个示例的工作方式。在这两种情况下,我们只返回邮箱数据。用户数据仅用于帮助确定要查看的邮箱。但是,Warren Frame 有一个出色的 PowerShell 函数,称为 Join-Object,您可以了解 here。它使您可以像 SQL 连接一样将两组数据连接到类似的唯一值(即 UserPrincipalName)上。这就是我要开始的地方。
  • 很棒的解释!
猜你喜欢
  • 1970-01-01
  • 2018-04-28
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-09
相关资源
最近更新 更多