为什么这个 Powershell ForEach 循环每次迭代都会变慢?

2023-12-12

我的代码按预期工作。我真的很想知道是否有人知道为什么我下面描述的事情可能会发生。也就是说,如果有人有任何进一步优化日常工作的想法,我会本着每天都是上学日的精神感激地接受他们!

该脚本正在查询我们所有的域控制器以获取最新的最后登录特定 OU 中所有用户的属性。 (我这样做而不是使用上次登录时间戳属性,因为我需要脚本运行时的绝对最新登录信息。)

在测试过程中,为了检查代码是否按照我的预期执行,我添加了一些控制台输出(包含在下面的代码片段中)。

当我这样做时,我注意到第二次的每次迭代ForEach ( $DC in $AllDCs )循环中,在嵌套循环写入控制台输出的第一行之前有一个明显的暂停。暂停的持续时间随着外循环的每次迭代而增加,并且内循环后续输出的速度也明显下降。在运行过程中,查看十多个 DC 的输出,我估计控制台线路的写入速率至少下降了 4 倍。

$AllDCs = Get-ADDomainController -Filter *

$AllRecords = @{}

ForEach ( $DC in $AllDCs ) {

    $UserList = Get-ADUser -filter * -Server $DC -SearchBase $ini.OUDN.NewStartsInternal -SearchScope OneLevel -Properties lastLogon
    $UserList = $UserList | Where { $_.SamAccountName -match $ini.RegEx.PayNo }

    $AllRecords.Add($DC.Hostname,$UserList)

}

$Logons = @{}

ForEach ( $DC in $AllDCs ) {                                   ; this loop is the one I'm talking about
    
    ForEach ( $User in $AllRecords.$($DC.HostName) ) {

        If ( $Logons.ContainsKey($User.SamAccountName) ) {     ;this line amended on advice from mklement0
            
            If ( $Logons.$($User.SamAccountName) -lt $User.lastLogon ) {
            
                $Logons.$($User.SamAccountName) = $User.lastLogon
                Write-Host "Updated $($User.SamAccountName) to $($User.lastLogon)" -ForegroundColor Green

            } Else {

                Write-Host "Ignored $($User.SamAccountName)"

            }

        } Else {

            $Logons.Add( $User.SamAccountName , $User.lastLogon )

            Write-Host "Created $($User.SamAccountName)" -ForegroundColor Yellow

        }

    }

}

我在这里实际上没有任何时间限制,因为我们只谈论几百个用户和十几个域控制器。无论如何,我已经大大减少了运行时间。以前,它循环遍历用户并逐一查询每个用户的每个 DC,毫不奇怪,这花费了更长的时间。

UPDATE:

我从下面的第一条评论中实现了 mklement0 的建议,如果有的话,脚本实际上运行得比以前慢。外循环迭代之间的延迟较长,并且内循环的输出似乎受到随机延迟的影响。平均而言,我认为内部循环每秒进行约 2 到 3 次迭代,在我看来,这对于循环已保存在本地内存中的数据来说非常慢。我知道 PowerShell 因速度慢而闻名,但这似乎很特殊。

该脚本通常在虚拟机上运行,​​所以我在自己的计算机上测试了它,速度慢了很多,所以这不是虚拟机的资源问题。

更新2:

我删除了所有Write-Host命令并简单地计时外循环的每次迭代。

首先,删除所有控制台写入会显着提高性能,这是我所期望的,尽管我没有意识到提高了多少。它轻松地将运行时间缩短到原来的五分之一。

就循环时间而言,奇怪的行为仍然存在。在 12 次迭代中,前 7 次在 1 秒内完成,完成最后 5 次大约需要 35 秒。这种行为每次都会或多或少地重复。与前七个 DC 相比,最后五个 DC 的主机名没有任何不同,这可能会减慢哈希表查找速度。

我对现在的运行时间非常满意,但仍然对这种奇怪的行为感到非常困惑。


所以,这是我对你的代码的看法,我没有改变很多东西,但我感觉这应该更快一点,但我可能是错的。

注意,我正在使用LDAPFilter = '(LastLogon=*)'代替Filter = '*'因为,如果它是一个不跨域复制的属性,那么在查询每个域控制器时将节省时间。

$AllDCs = Get-ADDomainController -Filter *
$logons = @{}

$params = @{
    LDAPFilter  = '(LastLogon=*)'
    Server      = ''
    SearchBase  = $ini.OUDN.NewStartsInternal
    SearchScope = 'OneLevel'
    Properties  = 'lastLogon'
}

foreach($DC in $AllDCs) {
    $params.Server = $DC
    $UserList = Get-ADUser @params
    
    foreach($user in $UserList) {
        if($user.samAccountName -notmatch $ini.RegEx.PayNo) {
            continue
        }

        if($logons[$user.samAccountName].LastLogon -lt $user.LastLogon) {
            # On first loop iteration should be always entering
            # this condition because
            # $null -lt [datetime]::MaxValue => True AND
            # $null -lt [datetime]::MinValue => True
            # Assuming $user.LastLogon is always a populated attribute
            # which also explains my LDAPFilter = '(LastLogon=*)' from before

            $logons[$user.samAccountName] = $user
        }
    }
}
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么这个 Powershell ForEach 循环每次迭代都会变慢? 的相关文章

随机推荐

  • 使用 foreach 从数据库中获取数据 - 从上到下

    数据库 id name 1 aaa 2 bbb 3 ccc 250 zz3 foreach datafromdb as value echo value gt name 这告诉我 aaa bbb ccc zz3 从左到右 if table
  • 使用 DNS 重定向到另一个带有路径的 URL [关闭]

    Closed 这个问题不符合堆栈溢出指南 目前不接受答案 我正在尝试通过 DNS 将一个域重定向到另一个域 我知道使用 IN CNAME 是可能的 www proof com IN CNAME www proof two com 我需要的是
  • 在 JavaScript 中停止回发

    我有一个带有 JQuery Thickbox 的 ASP Web 表单 我有一个在用户单击时打开 Thickbox 的图像 一旦打开厚盒 它会向我显示一个包含多行的网格和一个用于选择一行的按钮 在用户选择记录后 它返回到所选记录的主页并导致
  • Cordova本地通知Android插件2.2升级

    我正在使用 Phonegap Cordova 2 2 在 Android 上开发 提醒 应用程序 用户输入一个具体的提醒日期 我应该准时通知他 我使用 Android 的通知插件 但它支持早期版本的手机间隙 我按照本教程解决了cordova
  • Xamarin.Forms 中选项卡式页面中的标题截止

    Android 中的标签页标题被截断 但在 iOS 设备上运行良好 我正在使用这个代码 public Tabbar this BarTextColor Color Maroon New Feed var navigationNewFeed
  • 嵌套函数的实现

    我最近发现gcc允许定义嵌套函数 在我看来 这是一个很酷的功能 但我不知道如何实现它 虽然通过传递上下文指针作为隐藏参数来实现对嵌套函数的直接调用当然并不困难 但 gcc 还允许获取指向嵌套函数的指针并将该指针传递给任意其他函数 该函数又可
  • 向表中的每一行插入一个随机数

    我目前有一个包含大约 600 000 行的 oracle 表 lovalarm 我需要能够运行一个查询 该查询将循环遍历每一行并将字段 lovsiteid 更新为 14300 到 17300 之间的随机数 到目前为止我有 update lo
  • 一天的时间跨度怎么可能只有 8 个小时?

    我保存了以分钟为单位的持续时间 并希望输出 1 天 5 小时 30 分钟 目前 我将分钟添加到时间跨度中并执行如下操作 TimeSpan ts new TimeSpan 0 0 1800 0 Response Write ts Days d
  • 如何使用Beautifulsoup解析网站

    我是网络抓取新手 我想获取页面的 html 但是当我运行该程序时 我得到 html 为空并且控制台显示 javascript from bs4 import BeautifulSoup import requests import urll
  • 未指定网络安全配置,使用平台默认值

    我正在尝试打印值列表ListView来自网页 我有这两个权限
  • 在 Jquery 中创建无限循环

    HTML结构是这样的 ul class innerfade li style display none some Text li li style display none bla bla bla li li style display n
  • 如何在psql中切换数据库?

    在MySQL中 我使用了use database name 什么是psql相等的 在 PostgreSQL 中 您可以使用 connect客户端工具psql的元命令 connect DBNAME 或者简而言之 c DBNAME
  • 使用 NEST C# 在 Elastic Search 中使用多个索引进行全文搜索

    我正在尝试使用 NEST 客户端搜索多个索引 Elasticsearch 我只需点击以下链接 叠加帖子 如何使用 Nest ElasticSearch 在多个索引内进行搜索 唯一的区别是我的索引已经存在但没有返回 示例代码 using Sy
  • 单击子元素也会触发其父元素的单击事件[重复]

    这个问题在这里已经有答案了 Scenario 我的主干应用程序中的视图由几个部分组成boxes which are div elements 当用户单击一个框并按住鼠标按钮 500 毫秒时 我想显示一个delete左上角的按钮 当用户点击其
  • C++ 委托构造函数

    你好 我对 Java 比 C 更熟悉 test h class Test private int a b c public Test int a int b int c test c Test Test int a int b int c
  • 如何使用 FTP 下载 R 包

    我需要在无法访问 Internet 的 Windows 7 PC 上支持 R 环境 我想下载 最终下载到 DVD 所有 5 000 个软件包的当前版本 以供这台 PC 上的 R 用户使用 是否有 FTP 脚本或其他好方法来下载 R 包的所有
  • 如何每500ms获取一次相机预览帧

    我正在开发示例应用程序 它通过 android 中的相机为我提供指向图像或对象的颜色代码 我的应用程序与此应用程序类似 我正在使用this为此的应用程序代码 使用此应用程序代码 我可以连续获取相机预览帧 并为我提供当前预览帧的颜色代码 我想
  • NotificationHub推送通知返回:从Token Provider获取的Token错误

    我有 Wp8 1 Silverlight 应用程序 它从 Mobileservice 旧的 azure 服务 接收推送通知 WNS 因此 由于新功能 我想更新到新服务 我现在已经创建 升级了一个新服务器以使用应用程序服务 移动应用程序 并使
  • 使用 Grand Central Dispatch,我如何检查是否有一个块已经在运行?

    我正在使用 GCD 从互联网上进行一些后台加载 除了一点缺陷之外 这效果很好 在我的应用程序中 我有 3 个选项卡 当单击任何选项卡时 GCD 开始为相应的选项卡进行后台加载 如果用户决定从第一个选项卡转到第二个选项卡 当 GCD 已开始下
  • 为什么这个 Powershell ForEach 循环每次迭代都会变慢?

    我的代码按预期工作 我真的很想知道是否有人知道为什么我下面描述的事情可能会发生 也就是说 如果有人有任何进一步优化日常工作的想法 我会本着每天都是上学日的精神感激地接受他们 该脚本正在查询我们所有的域控制器以获取最新的最后登录特定 OU 中