【发布时间】:2017-07-14 09:30:00
【问题描述】:
在研究了如何组合数组之后,使用我在此处和其他来源中找到的信息,我能够创建一个脚本,该脚本采用多个数组并将它们组合到一个主键(userprincipalname)上。该脚本的目的是将 Office 365 的许可和使用统计信息与 Active Directory 中的用户帐户信息相结合。
我有兴趣改进的代码块是我结合三个数据源的最后一步。虽然我的代码有效,但它需要 30 多分钟才能运行。我认为这主要是由于我如何循环并分别处理每条记录。此时,虽然代码可以工作,但实际上打开电子表格并在 Excel 中执行 VLOOKUP 会快得多。
下面是合并三个数组的代码:
$MBInfoCC = Import-Excel C:\Work\MBStats.xlsx | Sort-Object -Property UserPrincipalName
$LicInfoCC = Import-Excel C:\Work\LicStats.xlsx | Sort-Object -Property UserPrincipalName
$ADInfoCC = Import-Excel C:\Work\ADUserInfo.xlsx | Sort-Object -Property UserPrincipalName
$ADInfoCC | ForEach-Object {
$gumdrop = $_
[PSCustomObject]@{
'Windows Username' = $ADInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).WindowsUserName
'User Principal Name' = $ADInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).UserPrincipalName
'Display Name' = $ADInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).DisplayName
'Last Name' = $ADInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).LastName
'First Name' = $ADInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).FirstName
'Email Address' = $ADInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).EmailAddress
'Employee Number' = $ADInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).EmployeeNumber
'Description' = $ADInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).Description
'Employee Type' = $ADInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).EmployeeType
'Division' = $ADInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).Division
'Department' = $ADInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).Department
'Account Enabled' = $ADInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).AccountEnabled
'Last Windows Logon' = $ADInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).LastWindowsLogon
'Last Mailbox Access' = $MBInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).LastMailboxLogon
'Office 365 License' = $LicInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).License
'Mailbox Size' = $MBInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).MailboxSize
'Mailbox Type' = $MBInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).MailboxType
'Account Expiration Date' = $ADInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).AccountExpirationDate
'Password Last Set' = $ADInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).PasswordLastSet
'Password Has Expired' = $ADInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).PasswordExpired
'Password Not Required' = $ADInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).PasswordNotRequired
'Password Never Expires' = $ADInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).PasswordNeverExpires
'User Cannot Change Password' = $ADInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}).CannotChangePassword
}
} | Export-Excel -Path C:\Work\FullUserReport.xlsx -FreezeTopRow -AutoSize -BoldTopRow
正如您在代码中所读到的,其工作方式是将所有三个 excel 工作表加载到单独的数组中,每个数组都有一个 UserPrincipalName 字段。 AD 信息包含所有用户,无论他们是否是邮箱用户,因此我将其用作主要用户。我遍历与字段匹配的列表。我还使用 import-excel 模块而不是 import-csv 以便能够应用一些格式。我昨天将 Sort-Object 添加到数组中,以查看对列表进行排序是否会提高性能,它在一定程度上起到了作用,因为运行时间从 40 多分钟下降到 30 多分钟。
谢谢, 克拉克
【问题讨论】:
-
您正在运行大量的 where 过滤器,并且每次您都在过滤整个电子表格。如果先合并对象,然后提取数据,效率会高得多。 Warren Frame 的 Join-Object 可以让这一切变得简单。
-
您可以分配过滤后的对象并使用它,而不是每次都使用 where 过滤。例如:$UsrPrinInstance = $ADInfoCC.Where({$PSItem.UserPrincipalName -eq $gumdrop.UserPrincipalName}) ... 'Windows 用户名' = $UsrPrinInstance.WindowsUserName
标签: arrays powershell active-directory office365