使用 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 库之上,据说可以处理长路径。我自己没用过,但可能值得一试。