使用 Get-ADUser -Filter {} 时,过程很慢
When using Get-ADUser -Filter {}, process is slow
我正在尝试清除 DFS 共享上的一些孤立用户共享。我想使用 Get-ADUser -Filter
.
将文件夹的全名与指定对象的 HomeDirectory
属性 进行比较
例如,如果我使用 (Get-ADUser $varibale -Properties * | Select Homedirectory)
,当找不到该帐户时,我会收到一条错误消息。所以如果没有找到帐户,我使用 -Filter
来隐藏错误。但是,这比 -Properties * | Select
方法慢得多。
脚本:
$path = Read-Host -Prompt "Share path...."
$Dirs = Get-ChildItem $Path
foreach ($D in $Dirs) {
$Login = Get-ADUser -Filter {HomeDirectory -eq $d.FullName}
if ($d.FullName -ne $Login."HomeDirectory") {
$host.UI.RawUI.WindowTitle = "Checking $d..."
$choice = ""
Write-Host "Comparing $($d.FullName)......." -ForegroundColor Yellow
$prompt = Write-Host "An account with matching Home Directory to $($d.FullName) could not be found. Purge $($d.fullname)?" -ForegroundColor Red
$choice = Read-Host -Prompt $prompt
if ($choice -eq "y") {
function Remove-PathToLongDirectory {
Param([string]$directory)
# create a temporary (empty) directory
$parent = [System.IO.Path]::GetTempPath()
[string] $name = [System.Guid]::NewGuid()
$tempDirectory = New-Item -ItemType Directory -Path (Join-Path $parent $name)
robocopy /MIR $tempDirectory.FullName $directory
Remove-Item $directory -Force
Remove-Item $tempDirectory -Force
}
# Start of Script to delete folders from User Input and Confirms
# the specified folder deletion
Remove-PathToLongDirectory $d.FullName
}
} else {
Write-Host "Done!" -ForegroundColor Cyan
}
Write-Host "Done!" -ForegroundColor Cyan
}
你的代码中有一些次优的东西(比如(重新)定义一个循环内的函数,或者反复创建和删除一个空目录),但你最大的瓶颈可能是你做了一个AD查询每个目录。您应该能够通过进行单个 AD 查询并将其结果存储在数组中来显着加快代码速度:
$qry = '(&(objectclass=user)(objectcategory=user)(homeDirectory=*)'
$homes = Get-ADUser -LDAPFilter $qry -Properties HomeDirectory |
Select-Object -Expand HomeDirectory
这样您就可以检查是否有一个帐户具有给定的主目录,如下所示:
foreach ($d in $dirs) {
if ($homes -notcontains $d.FullName) {
# ... prompt for deletion ...
} else {
# ...
}
}
在性能方面,在使用每个命令删除 2 GB 测试文件夹时,我没有注意到 robocopy /mir
方法和 Remove-Item
方法之间的区别。但是,如果您的路径 length exceeds 260 characters you should probably stick with robocopy
, because Remove-Item
can't handle those。不过,我建议添加一条评论来解释您使用该命令的目的,因为下一个阅读您脚本的人可能和我一样对此感到困惑。
$empty = Join-Path ([IO.Path]::GetTempPath()) ([Guid]::NewGuid())
New-Item -Type Directory -Path $empty | Out-Null
foreach ($d in $dirs) {
if ($homes -notcontains $d.FullName) {
# ... prompt for confirmation ...
if ($choice -eq 'y') {
# "mirror" an empty directory into the orphaned home directory to
# delete its content. This is used b/c regular PowerShell cmdlets
# can't handle paths longer than 260 characters.
robocopy $empty $d.FullName /mir
Remove-Item $d -Recurse -Force
}
} else {
# ...
}
}
Remove-Item $empty -Force
还有一个 PowerShell module 构建在 AlphaFS 库之上,据说可以处理长路径。我自己没用过,但可能值得一试。
我正在尝试清除 DFS 共享上的一些孤立用户共享。我想使用 Get-ADUser -Filter
.
HomeDirectory
属性 进行比较
例如,如果我使用 (Get-ADUser $varibale -Properties * | Select Homedirectory)
,当找不到该帐户时,我会收到一条错误消息。所以如果没有找到帐户,我使用 -Filter
来隐藏错误。但是,这比 -Properties * | Select
方法慢得多。
脚本:
$path = Read-Host -Prompt "Share path...."
$Dirs = Get-ChildItem $Path
foreach ($D in $Dirs) {
$Login = Get-ADUser -Filter {HomeDirectory -eq $d.FullName}
if ($d.FullName -ne $Login."HomeDirectory") {
$host.UI.RawUI.WindowTitle = "Checking $d..."
$choice = ""
Write-Host "Comparing $($d.FullName)......." -ForegroundColor Yellow
$prompt = Write-Host "An account with matching Home Directory to $($d.FullName) could not be found. Purge $($d.fullname)?" -ForegroundColor Red
$choice = Read-Host -Prompt $prompt
if ($choice -eq "y") {
function Remove-PathToLongDirectory {
Param([string]$directory)
# create a temporary (empty) directory
$parent = [System.IO.Path]::GetTempPath()
[string] $name = [System.Guid]::NewGuid()
$tempDirectory = New-Item -ItemType Directory -Path (Join-Path $parent $name)
robocopy /MIR $tempDirectory.FullName $directory
Remove-Item $directory -Force
Remove-Item $tempDirectory -Force
}
# Start of Script to delete folders from User Input and Confirms
# the specified folder deletion
Remove-PathToLongDirectory $d.FullName
}
} else {
Write-Host "Done!" -ForegroundColor Cyan
}
Write-Host "Done!" -ForegroundColor Cyan
}
你的代码中有一些次优的东西(比如(重新)定义一个循环内的函数,或者反复创建和删除一个空目录),但你最大的瓶颈可能是你做了一个AD查询每个目录。您应该能够通过进行单个 AD 查询并将其结果存储在数组中来显着加快代码速度:
$qry = '(&(objectclass=user)(objectcategory=user)(homeDirectory=*)'
$homes = Get-ADUser -LDAPFilter $qry -Properties HomeDirectory |
Select-Object -Expand HomeDirectory
这样您就可以检查是否有一个帐户具有给定的主目录,如下所示:
foreach ($d in $dirs) {
if ($homes -notcontains $d.FullName) {
# ... prompt for deletion ...
} else {
# ...
}
}
在性能方面,在使用每个命令删除 2 GB 测试文件夹时,我没有注意到 robocopy /mir
方法和 Remove-Item
方法之间的区别。但是,如果您的路径 length exceeds 260 characters you should probably stick with robocopy
, because Remove-Item
can't handle those。不过,我建议添加一条评论来解释您使用该命令的目的,因为下一个阅读您脚本的人可能和我一样对此感到困惑。
$empty = Join-Path ([IO.Path]::GetTempPath()) ([Guid]::NewGuid())
New-Item -Type Directory -Path $empty | Out-Null
foreach ($d in $dirs) {
if ($homes -notcontains $d.FullName) {
# ... prompt for confirmation ...
if ($choice -eq 'y') {
# "mirror" an empty directory into the orphaned home directory to
# delete its content. This is used b/c regular PowerShell cmdlets
# can't handle paths longer than 260 characters.
robocopy $empty $d.FullName /mir
Remove-Item $d -Recurse -Force
}
} else {
# ...
}
}
Remove-Item $empty -Force
还有一个 PowerShell module 构建在 AlphaFS 库之上,据说可以处理长路径。我自己没用过,但可能值得一试。