powershell - 批量使用 ActiveDirectory cmdlet 时出现 Active Directory transient 错误

标签 powershell active-directory

我有一个从数据源同步用户的系统。数据源由用户信息组成。同步新用户时,会触发创建或更新用户的 PowerShell 任务。这一切都很好,但是当新/更新用户的数量变得太大时,一些任务会失败并出现一些有趣的错误,例如:

"The server has returned the following error: invalid enumeration context."



或者

"A connection to the directory on which to process the request was unavailable. This is likely a transient condition."



在进行故障排除时,这些错误发生的原因似乎很明显是缺乏资源。这是因为所有同时触发的任务都在自己的 PS session 中导入模块。

所以我尝试了一些不同的东西并测量 Import-Module 的速度等。所以我得出结论,运行 Import-Module 更快。然后 Get-ADUser例如,只需 Get-ADUser (这也将导入模块)。
Measure-Command {Import-Module ActiveDirectory}

Average time 340 ms


Measure-Command {Get-ADUser -Filter *}

Average time 420 ms


Get-ADUser导入模块后

Average time 10 ms



但这些边际差异不会对问题产生任何影响。所以我不得不进一步看。我发现禁用驱动器可能有助于加快进程,所以我在导入模块之前添加了以下内容:
$Env:ADPS_LoadDefaultDrive = 0
Measure-Command {Import-Module ActiveDirectory}

Average time 85 ms



快4倍!但同时错误仍然存​​在于大量用户(例如 50 个任务)。所以我想在脚本中轮询可用性,或者做一个do..while环形。或者,触发单独任务的系统可能需要重新设计,以拥有某种队列。

有人认识这种情况吗?或者他们想就这个主题分享一些想法?

最佳答案

It is because all the simultaneously triggered tasks are importing the module on their own PS session.



然后,您需要确保不会发生这种情况,或者至少不会出现资源不足的情况。所以你有两个选择:
  • 限制在任何时候运行的任务数量(一次可能 5 个)。
  • 使其成为一项可以在多个帐户上运行的任务。这样模块只会被加载一次。

  • 我认为选项 2 是更好的解决方案。例如,您的同步作业不会立即触发脚本,而是将用户名写入文件(甚至在内存中),一旦找到所有用户,它就会触发 PowerShell 脚本并传递列表(或脚本可以读取写入的文件)。你有选择 - 任何最有效的。

    更新:所有 .NET 都可在 PowerShell 中使用,因此另一种选择是将整个脚本更改为使用 .NET 的 DirectoryEntry而不是 ActiveDirectory 模块,它会使用更少的内存。在 PowerShell 中甚至有它的快捷方式。例如,[ADSI]"LDAP://$distinguishedName"将创建一个 DirectoryEntry用户的对象。这是一次实质性的重写,但性能要好得多(速度和内存消耗)。

    以下是使用 DirectorySearcher 进行搜索的一些示例(使用 [ADSISearcher] 快捷方式):https://blogs.technet.microsoft.com/heyscriptingguy/2010/08/23/use-the-directorysearcher-net-class-and-powershell-to-search-active-directory/

    下面是使用 DirectoryEntry 创建帐户的示例: https://www.petri.com/creating-active-directory-user-accounts-adsi-powershell

    关于powershell - 批量使用 ActiveDirectory cmdlet 时出现 Active Directory transient 错误,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53478669/

    相关文章:

    .net - Powershell 从字符串中生成 System.Type

    azure - 支持 Active Directory Graph Api,无需 Azure 应用程序

    c# - 从 Active Directory 获取用户组时出错,在单声道中使用 LDAP

    powershell - 将自定义对象传递到另一个ps1脚本

    c# - 使用PrincipalContext和PrincipalSearcher从单独的服务器访问Active Directory用户

    active-directory - 如何将 Microsoft ADAM 配置为类似于 Active Directory?

    powershell - 使用 powershell 在 AD 中获取组织职位

    powershell - 使用Powershell将一个文件分成多个文件

    node.js - 在 nodejs 中执行长时间运行的 powershell 脚本

    powershell - 仅从Get-ChildItem返回目录