我有一个生成孤立OneDrive报告的简单脚本。它正在工作,但速度很慢,所以我只是想知道如何修改我的脚本来加快这个过程。如有任何帮助或建议,我们将不胜感激。
基本上这就是我正在做的:
- 从"所有者";列,并使用AzureAD进行检查以查看是否出现任何错误
- 如果我遇到错误,请在prem ADGroup上进行检查
- 如果该所有者存在于预处理ADGroup中,那么它就是孤儿
- 仅将该用户导出到新的csv文件
$ImportData = "E:scriptsAllOneDriveUser.csv"
$Report = "E:scriptsOrphanOneDrive.csv"
$CSVImport = Import-CSV $ImportData
ForEach ($CSVLine in $CSVImport) {
$CSVOwner = $CSVLine.Owner
try{
Get-AzureADUser -ObjectId $CSVOwner
}catch{
$StatusMessage = $_.Exception.Message
if($Null -eq $StatusMessage){
Write-Host "User Found, Ignore from orphan list."
}else{
#Owner not found in AzureAD
$group = 'TargetGroup'
$filter = '(memberof={0})' -f (Get-ADGroup $group).DistinguishedName
$filterName = Get-ADUser -LDAPFilter $filter
$ModifiedOwner = $CSVOwner -split"@"[0]
if( $ModifiedOwner[0] -in $filterName.Name ){
Write-host "Adding it into orphaned list"
$CSVLine | Export-Csv $Report -Append -notypeinformation -force
}else{
Write-Host "Not orphaned"
}
}
}
}
我在导入csv文件中有8000多条记录,在预处理AD组中有5000多名成员,所以这需要很长时间。
在这种情况下,使用HashSet<T>
可以极大地改进脚本,但代码的主要问题是,您要反复查询同一组,它应该在循环之外!
还有Export-Csv -Append
的使用,每次循环迭代都会很慢地附加到文件中,这更好地简化了管道的流程,因此Export-Csv
只接收对象并导出一次,而不是每次打开和关闭FileStream
。
希望内联评论解释你可以遵循的逻辑来改进它。
$ImportData = "E:scriptsAllOneDriveUser.csv"
$Report = "E:scriptsOrphanOneDrive.csv"
# we only need to query this once! outside the try catch
# a HashSet<T> enables for faster lookups,
# much faster than `-in` or `-contains`
$filter = '(memberof={0})' -f (Get-ADGroup 'GroupName').DistinguishedName
$members = [Collections.Generic.HashSet[string]]::new(
[string[]] (Get-ADUser -LDAPFilter $filter).UserPrincipalName,
[System.StringComparer]::OrdinalIgnoreCase
)
Import-CSV $ImportData | ForEach-Object {
# hitting multiple times a `catch` block is expensive,
# better use `-Filter` here and an `if` condition
$CSVOwner = $_.Owner
if(Get-AzureADUser -Filter "userprincipalname eq '$CSVOwner'") {
# we know this user exists in Azure, so go next user
return
}
# here is for user not found in Azure
# no need to split the UserPrincipalName, HashSet already has
# a unique list of UserPrincipalNames
if($hash.Contains($CSVOwner)) {
# here is if the UPN exists as member of AD Group
# so output this line
$_
}
} | Export-Csv $Report -NoTypeInformation