[英]Powershell GCI, to Depth speed
I need a way to speed up the following code for use on a VERY large server. 我需要一种方法来加速以下代码在非常大型的服务器上使用。 All I need is the list of the fullname param. 我需要的是全名参数列表。 I would like to use something like the following: http://newsqlblog.com/2012/05/22/concurrency-in-powershell-multi-threading-with-runspaces/ 我想使用类似以下的内容: http : //newsqlblog.com/2012/05/22/concurrency-in-powershell-multi-threading-with-runspaces/
I was reading about it and it seems pretty simple, however I cannot wrap my head around allowing threads to create new Threads in the existing pool... and how to pass that pool along. 我正在阅读有关它的内容,这似乎很简单,但是我无法绕开允许线程在现有池中创建新线程的方法……以及如何传递该池。
Any help would be great, because the speed of this is just terrible and I have SOOOO many more resources then I am utalizing. 任何帮助都将是非常有用的,因为这样做的速度简直太糟糕了,而且我还有很多要用的资源,然后再进行最终统计。
Function Get-ChildItemToDepth {
Param(
[String]$Path = $PWD,
[int]$ToDepth = 255,
[Byte]$CurrentDepth = 0
)
if ($ToDepth -lt 0) {
return get-item $path
}
$CurrentDepth++
Get-ChildItem $Path | Where-Object { $_.PSIsContainer } | %{ $_
If ($CurrentDepth -le $ToDepth) {
Get-ChildItemToDepth -Path $_.FullName `
-ToDepth $ToDepth -CurrentDepth $CurrentDepth
}
}
}
NOTE: I am restricted to v2.0 注意:我仅限于v2.0
Summary: I basically need the path to all folders up to $depth into an array as fast as digitally possible. 简介:我基本上需要尽可能快地以数字方式将所有文件夹直至$ depth的路径放入数组。
MISSERABLE FAILURE ATTEMPT: 错误的尝试失败次数:
$func = `
{
Param(
[String]$Path = $PWD,
[int]$ToDepth = 255,
[Byte]$CurrentDepth = 0,
$p = $pool
)
if ($ToDepth -lt 0) {
return $path
}
$CurrentDepth++
$folders = Get-ChildItem $Path | Where-Object { $_.PSIsContainer } | select -expand FullName
If ($CurrentDepth -le $ToDepth) {
foreach ($path in $folders) {
$pipeline = [System.Management.Automation.PowerShell]::create()
$pipeline.RunspacePool = $pool
$pipeline.AddScript($func).AddArgument($path).AddArgument($ToDepth).AddArgument($CurrentDepth).AddArgument($pool)
$AsyncHandle = $pipeline.BeginInvoke()
$folders += $pipeline.EndInvoke($AsyncHandle)
$pipeline.Dispose()
}
}
return $folders
}
$path = "\\server\users-folder\"
$toDepth = 3
$pool = [RunspaceFactory]::CreateRunspacePool(1, 4)
$pool.ApartmentState = "STA"
$pool.Open()
$pipeline = [System.Management.Automation.PowerShell]::create()
$pipeline.RunspacePool = $pool
$pipeline.AddScript($func).AddArgument($path).AddArgument($toDepth).AddArgument($CurrentDepth).AddArgument($pool)
$AsyncHandle = $pipeline.BeginInvoke()
$RESULTS = $pipeline.EndInvoke($AsyncHandle)
$pipeline.Dispose()
$pool.Close()
try to invoke this in a workflow - a powerful native powershell multithreading solution available out of the box with PowerShell 3.0 尝试在工作流中调用它-PowerShell 3.0提供了一个功能强大的本机Powershell多线程解决方案
Workflow Invoke-Function
{
Function Get-ChildItemToDepth {
Param(
[String]$Path = $PWD,
[int]$ToDepth = 255,
[Byte]$CurrentDepth = 0
)
if ($ToDepth -lt 0) {
return $path
}
$CurrentDepth++
Get-ChildItem $Path | Where-Object { $_.PSIsContainer } | %{ $_
If ($CurrentDepth -le $ToDepth) {
Get-ChildItemToDepth -Path $_.FullName `
-ToDepth $ToDepth -CurrentDepth $CurrentDepth
}
}
}
Get-ChildItemToDepth
}
This is a pretty messy implementation, I just wrapped your function and a call around a workflow so you could copy-paste it into a session for ease of testing. 这是一个非常混乱的实现,我只是将您的函数和一个调用包装在工作流中,因此您可以将其复制粘贴到会话中以方便测试。 Please let me know how that works for you. 请让我知道它如何为您服务。 If you want to see the difference in speed I would pipe the results of the function to Measure 如果要查看速度差异,可以将函数的结果传递给Measure
Get-ChildItemToDepth | Measure
Invoke-Function | Measure
Usage (after you pasted the workflow into a session) 用法(将工作流程粘贴到会话中之后)
Invoke-Function
Go to http://psasync.codeplex.com and download the psasync module (documentation here http://newsqlblog.com/2012/12/17/psasync-module-multithreaded-powershell/ ). 转到http://psasync.codeplex.com并下载psasync模块(此处的文档为http://newsqlblog.com/2012/12/17/psasync-module-multithreaded-powershell/ )。 Then ... 然后 ...
Import-Module psasync
$AsyncPipelines = @()
# Allow 4 concurrent processes ... adjust up / down as hardware allows
$pool = Get-RunspacePool 4
# You can play with this to get better performance by going deeper into the directory structure to populate more dirs in the array
# gross generalization -> more dirs + more runspaces in $pool = faster performance
$rootDirs = Get-ChildItem c:\ | Where-Object{$_.PSIsContainer}
# Create a script block to run code per directory stored in $rootDirs
$ScriptBlock = { `
Param(
[String]$Path = $path
)
Get-ChildItem $path -recurse | Where-Object{$_.PSIsContainer}
}
# Load up processes on the runspace pool
foreach($dir in $rootDirs) {
$AsyncPipelines += Invoke-Async -RunspacePool $pool -ScriptBlock $ScriptBlock -Parameters $dir.FullName
}
# "Listen" to the pipelines and grab the results
$dirs = Receive-AsyncResults -Pipelines $AsyncPipelines
# PROFIT
$dirs | Foreach-Object{$_.FullName}
And thanks for reading newsqlblog.com ;) 并感谢您阅读newsqlblog.com;)
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.