[玩转系统] 理解 PowerShell 7 中的并行 ForEach-Object
作者:精品下载站 日期:2024-12-14 07:55:28 浏览:15 分类:玩电脑
理解 PowerShell 7 中的并行 ForEach-Object
您很可能在 PowerShell 7 Personally 的最新预览版中听说过 ForEach-Object 的新 -parallel 参数。我等这个已经很久了。我过去只使用 PowerShell 工作流程,因为它提供了一种并行运行命令的方法。将此功能作为语言的一部分是一个受欢迎的补充。但这不是魔法,当你使用它时,会产生现实世界的后果。 -Parallel 参数将启动一组运行空间并在每个运行空间中运行脚本块。并行运行并不意味着按顺序运行。
这是新参数的实际应用示例。
我引入了随机睡眠间隔来帮助证明命令是并行运行的。每个并行操作完成时,结果都会写入管道。让我们更深入地研究一下这个问题。
直管
这是使用 ForEach-Object 的直接管道示例。
Measure-Command {
1..5000 | ForEach-Object { [math]::Sqrt($_) * 2 }
}
我花了 34 毫秒才完成。这是相同的命令,但使用 -parallel 运行。
Measure-Command {
1..5000 | ForEach-Object -parallel { [math]::Sqrt($_) * 2 }
}
这花了 89秒。显然,使用此参数时会产生开销。
然而,还有潜在的改进空间。默认情况下,该命令一次启动 5 个运行空间。您可以使用 -ThrottleLimit 参数增加或减少此值。
Measure-Command {
1..5000 | ForEach-Object -parallel { [math]::Sqrt($_) * 2 } -throttlelimit 25
}
这个版本几乎用了5秒就完成了!相比之下,使用 ForEach 枚举器:
Measure-Command {
foreach ($x in (1..5000)) { [math]::Sqrt($x) * 2 }
}
大约需要 7 毫秒。
运行脚本块
让我们增加复杂性并做一些更实际的事情。这是一个脚本块,它将为我提供一个显示给定文件夹中文件使用情况的对象。
$t = {
param ([string]$Path)
Get-ChildItem -path $path -recurse -file -erroraction SilentlyContinue |
Measure-Object -sum -Property Length -Maximum -Minimum |
Select-Object @{Name = "Computername"; Expression = { $env:COMPUTERNAME } },
@{Name = "Path"; Expression = { Convert-Path $path } },
Count, Sum, Maximum, Minimum
}
Measure-Command {
"c:\work", "c:\scripts", "d:\temp", "C:\users\jeff\Documents", "c:\windows" |
ForEach-Object -process { Invoke-Command -scriptblock $t -argumentlist $_ }
}
在我的具有 32GB 内存的 Windows 10 桌面上本地运行此程序花费了 34 秒多一点的时间。这是使用 -Parallel 的相同命令。
Measure-Command {
"c:\work", "c:\scripts", "d:\temp", "C:\users\jeff\Documents", "c:\windows" | ForEach-Object -parallel {
$path = $_
Get-ChildItem -path $path -recurse -file -erroraction SilentlyContinue |
Measure-Object -sum -Property Length -Maximum -Minimum |
Select-Object @{Name = "Computername"; Expression = { $env:COMPUTERNAME } },
@{Name = "Path"; Expression = { Convert-Path $path } },
Count, Sum, Maximum, Minimum
}
}
您应该注意到语法上有很大差异。因为每个并行脚本块都在新的运行空间中运行,所以传递像 $t 这样的变量会更困难。有一些方法可以解决这个问题。对我来说,演示最简单的解决方案是简单地复制脚本块。
该命令运行大约需要 50 秒。不过,如果我将油门限制调到 6,它会在大约 20 秒内完成。
远程命令
-Parallel 开始有意义的地方是涉及远程计算机的命令或任何包含某种形式的可变性的命令。这是您可能运行的传统命令。
Measure-Command {
'srv1', 'srv2', 'win10', 'dom1', 'srv1', 'srv2', 'win10', 'dom1' | ForEach-Object {
Get-WinEvent -FilterHashtable @{Logname = "system"; Level = 2, 3 } -MaxEvents 100 -ComputerName $_
}
}
我只有几个虚拟机可供测试,因此我对它们重复该命令。大约 3 秒内完成。与 -Parallel 方法相比:
Measure-Command {
'srv1', 'srv2', 'win10', 'dom1', 'srv1', 'srv2', 'win10', 'dom1' | ForEach-Object -parallel {
Get-WinEvent -FilterHashtable @{Logname = "system"; Level = 2, 3 } -MaxEvents 100 -ComputerName $_
}
}
花费了不到 1 秒的时间。让我们增加样本量。
Measure-Command {
$d = ('srv1', 'srv2', 'win10', 'dom1')*5 |
ForEach-Object {
Get-WinEvent -FilterHashtable @{Logname = "system"; Level = 2, 3 } -ComputerName $_
}
}
与此相比,这花了 9.7 秒:
Measure-Command {
$d = ('srv1', 'srv2', 'win10', 'dom1')*5 |
ForEach-Object -parallel {
Get-WinEvent -FilterHashtable @{Logname = "system"; Level = 2, 3 } -ComputerName $_
}
}
3.7 秒内完成
大规模 PowerShell
让我们真正看看这在规模上是什么样子。我什至会尝试模拟服务器和网络延迟。
Measure-Command {
$d = ('srv1', 'srv2', 'win10', 'dom1') * 100 | ForEach-Object {
Get-WinEvent -FilterHashtable @{Logname = "system"; Level = 2, 3 } -ComputerName $_
#simulate network/server latency
Start-Sleep -Seconds (Get-Random -Minimum 1 -Maximum 5)
}
}
在我的桌面上,这需要超过 18 分钟才能完成,返回近 41,000 条记录。以下是使用 -parallel 的默认 PowerShell 7 版本:
Measure-Command {
$d = ('srv1', 'srv2', 'win10', 'dom1') * 100 | ForEach-Object -parallel {
Get-WinEvent -FilterHashtable @{Logname = "system"; Level = 2, 3 } -ComputerName $_
Start-Sleep -Seconds (Get-Random -Minimum 1 -Maximum 5)
}
}
现在命令在 3 分 35 秒内完成。
默认油门限制值可能会更改。杰弗里·斯诺弗 (Jeffrey Snover) 表示他认为应该更高,我想我同意。让我们看看使用 Invoke-Command 中的默认 ThrottleLimit 值时会发生什么。
Measure-Command {
$d = ('srv1', 'srv2', 'win10', 'dom1') * 100 | ForEach-Object -parallel {
Get-WinEvent -FilterHashtable @{Logname = "system"; Level = 2, 3 } -ComputerName $_
Start-Sleep -Seconds (Get-Random -Minimum 1 -Maximum 5)
} -throttlelimit 32
}
这在 49 秒内完成!
工作流程替代方案
最后一个比较是一个公认的粗糙工作流程,与其他示例相似。我切换到 Get-Eventlog 因为我认为工作流程不喜欢通过序列化连接发送过滤哈希表。
Workflow GetLogs {
Param()
Sequence {
$computers = ('srv1.company.pri', 'srv2.company.pri', 'win10.company.pri', 'dom1.company.pri') * 100
foreach -parallel ($computer in $computers) {
inlinescript {
Write-Verbose "$(Get-Date) Processing $using:computer"
Start-Sleep -Seconds (Get-Random -Minimum 1 -Maximum 5)
Get-Eventlog -LogName system -EntryType error, Warning -ComputerName $using:computer
} #inline
} #foreach
} #sequence
} #workflow
}
$d = getlogs -pscomputername localhost -ErrorAction SilentlyContinue
这不是 PowerShell 工作流程的目的,尽管我预计很多人都尝试过以这种方式使用它们。该命令在 10:05 完成,尽管如果使用更高的油门限制可能会有所改善。
结论
您可以得出的唯一绝对结论是,您需要进行自己的测试来确定使用 -parallel 对您的命令或项目是否有意义。就我个人而言,我的看法是 -parallel 最适合具有大量可变性的大规模操作。使用 Invoke-Command 编写可扩展的命令可能会得到类似的结果。
$computers = ('srv1', 'srv2', 'win10', 'dom1') * 100
$d = Invoke-Command {
Get-WinEvent -FilterHashtable @{Logname = "system"; Level = 2, 3 }
Start-Sleep -Seconds (Get-Random -Minimum 1 -Maximum 5)
} -throttlelimit 32 -ComputerName $computers
是的,由于必须设置和拆除 PSSession,因此存在开销。对我来说,这在 1 分 56 秒内完成,这仍然是可以接受的性能,而且作为奖励,这不需要 PowerShell 7。
我计划继续尝试此功能,并且很想听听您的使用体验。我相信最终社区会就何时使用它达成共识,但现在我们很高兴能弄清楚这一点!
猜你还喜欢
- 03-30 [玩转系统] 如何用批处理实现关机,注销,重启和锁定计算机
- 02-14 [系统故障] Win10下报错:该文件没有与之关联的应用来执行该操作
- 01-07 [系统问题] Win10--解决锁屏后会断网的问题
- 01-02 [系统技巧] Windows系统如何关闭防火墙保姆式教程,超详细
- 12-15 [玩转系统] 如何在 Windows 10 和 11 上允许多个 RDP 会话
- 12-15 [玩转系统] 查找 Exchange/Microsoft 365 中不活动(未使用)的通讯组列表
- 12-15 [玩转系统] 如何在 Windows 上安装远程服务器管理工具 (RSAT)
- 12-15 [玩转系统] 如何在 Windows 上重置组策略设置
- 12-15 [玩转系统] 如何获取计算机上的本地管理员列表?
- 12-15 [玩转系统] 在 Visual Studio Code 中连接到 MS SQL Server 数据库
- 12-15 [玩转系统] 如何降级 Windows Server 版本或许可证
- 12-15 [玩转系统] 如何允许非管理员用户在 Windows 中启动/停止服务
取消回复欢迎 你 发表评论:
- 精品推荐!
-
- 最新文章
- 热门文章
- 热评文章
[影视] 黑道中人 Alto Knights(2025)剧情 犯罪 历史 电影
[古装剧] [七侠五义][全75集][WEB-MP4/76G][国语无字][1080P][焦恩俊经典]
[实用软件] 虚拟手机号 电话 验证码 注册
[电视剧] 安眠书店/你 第五季 You Season 5 (2025) 【全10集】
[电视剧] 棋士(2025) 4K 1080P【全22集】悬疑 犯罪 王宝强 陈明昊
[软件合集] 25年6月5日 精选软件22个
[软件合集] 25年6月4日 精选软件36个
[短剧] 2025年06月04日 精选+付费短剧推荐33部
[短剧] 2025年06月03日 精选+付费短剧推荐25部
[软件合集] 25年6月3日 精选软件44个
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电视剧] 欢乐颂.5部全 (2016-2024)
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[影视] 【稀有资源】香港老片 艺坛照妖镜之96应召名册 (1996)
[剧集] 神经风云(2023)(完结).4K
[剧集] [BT] [TVB] [黑夜彩虹(2003)] [全21集] [粤语中字] [TV-RMVB]
[实用软件] 虚拟手机号 电话 验证码 注册
[资源] B站充电视频合集,包含多位重量级up主,全是大佬真金白银买来的~【99GB】
[影视] 内地绝版高清录像带 [mpg]
[书籍] 古今奇书禁书三教九流资料大合集 猎奇必备珍藏资源PDF版 1.14G
[电视剧] [突围] [45集全] [WEB-MP4/每集1.5GB] [国语/内嵌中文字幕] [4K-2160P] [无水印]
[剧集] [央视][笑傲江湖][2001][DVD-RMVB][高清][40集全]李亚鹏、许晴、苗乙乙
[电影] 美国队长4 4K原盘REMUX 杜比视界 内封简繁英双语字幕 49G
[电影] 死神来了(1-6)大合集!
[软件合集] 25年05月13日 精选软件16个
[精品软件] 25年05月15日 精选软件18个
[绝版资源] 南与北 第1-2季 合集 North and South (1985) /美国/豆瓣: 8.8[1080P][中文字幕]
[软件] 25年05月14日 精选软件57个
[短剧] 2025年05月14日 精选+付费短剧推荐39部
[短剧] 2025年05月15日 精选+付费短剧推荐36部
- 最新评论
-
- 热门tag