如何在UNC上加速Powershell Get-Childitem

时间:2011-08-25 20:43:41

标签: powershell powershell-v2.0

在Powershell中,

DIRGCI速度很慢,但在CMD中速度很快。有什么方法可以加快速度吗?

在CMD.exe中,经过亚秒级延迟后,此响应速度与CMD窗口可以跟上的速度一样快

dir \\remote-server.domain.com\share\folder\file*.*

在Powershell(v2)中,经过40秒以上的延迟,这会以明显的缓慢(每秒可能3-4行)作出响应

gci \\remote-server.domain.com\share\folder\file*.*

我正在尝试扫描远程服务器上的日志,所以也许有更快的方法。

get-childitem \\$s\logs -include $filemask -recurse | select-string -pattern $regex

4 个答案:

答案 0 :(得分:16)

好的,这就是我这样做的方式,而且似乎有效。

$files = cmd /c "$GETFILESBAT \\$server\logs\$filemask"
foreach( $f in $files ) {
    if( $f.length -gt 0 ) {
        select-string -Path $f -pattern $regex | foreach-object { $_ }
    }
}

然后$ GETFILESBAT指向:

@dir /a-d /b /s %1
@exit

我正在编写并删除PowerShell脚本中的BAT文件,所以我想这是一个仅限PowerShell的解决方案,但它不仅使用PowerShell。

我的初步表现指标显示这个速度要快十倍。

我测试了来自@Shawn Melton引用的link的gci与cmd dir和FileIO.FileSystem.GetFiles。

最重要的是,对于本地驱动器的日常使用,GetFiles是最快的。 到目前为止CMD DIR是可敬的。一旦您使用许多文件引入较慢的网络连接,CMD DIR略快于GetFiles。然后Get-ChildItem ...哇,这个范围从不太糟糕到可怕,取决于所涉及的文件数量和连接速度。

一些测试运行。我在测试中移动了GCI,以确保结果一致。

针对* .tmp文件扫描c:\windows\temp的10次迭代

.\test.ps1 "c:\windows\temp" "*.tmp" 10
GCI... 00:00:01.1391139
GetFiles... 00:00:00.0570057
CMD dir... 00:00:00.5360536

GetFiles比CMD目录快10倍,它本身比GCI快2倍。

使用递归扫描{。{1}} * .tmp文件的10次迭代

c:\windows\temp

GetFiles比CMD目录快一点,两者都比GCI快7倍。

扫描另一个域上的现场服务器以获取应用程序日志文件的10次迭代

.\test.ps1 "c:\windows\temp" "*.tmp" 10 -recurse
GetFiles... 00:00:00.7020180
CMD dir... 00:00:00.7644196
GCI... 00:00:04.7737224

GetFiles比CMD目录快2倍,本身比GCI快10倍。

在另一个域上扫描远程服务器以获取应用程序日志文件的一次迭代,涉及许多文件

.\test.ps1 "\\closeserver\logs\subdir" "appname*.*" 10
GCI... 00:00:06.0796079
GetFiles... 00:00:00.3590359
CMD dir... 00:00:00.6270627

CMD目录是使用许多文件进入远程服务器的最快速度,但GetFiles相当接近。另一方面,GCI慢了几千倍。

两次迭代扫描另一个域上的远程服务器以获取包含许多文件的应用程序日志文件

.\test.ps1 "\\distantserver.company.com\logs\subdir" "appname.2011082*.*"
GCI... 00:11:09.5525579
GetFiles... 00:00:00.4360436
CMD dir... 00:00:00.3340334

随着测试迭代次数的增加,线性增加或多或少。

一次扫描另一个域上的远程服务器以获取应用程序日志文件,文件较少

.\test.ps1 "\\distantserver.company.com\logs\subdir" "appname.20110822*.*" 2
GetFiles... 00:00:01.4976384
CMD dir... 00:00:00.9360240
GCI... 00:22:17.3068616

这里的GCI并不算太糟糕,GetFiles的速度提高了3倍,CMD目录也紧随其后。

<强>结论

.\test.ps1 "\\distantserver.company.com\logs\othersubdir" "appname.2011082*.*" 10 GCI... 00:00:01.9656630 GetFiles... 00:00:00.5304170 CMD dir... 00:00:00.6240200 需要GCI-raw选项,而不会尝试这么做。在此期间,-fast是一个健康的替代方案,偶尔会比GetFiles慢一点,通常更快(由于产生CMD.exe?)。

供参考,这是test.ps1代码。

CMD dir

答案 1 :(得分:15)

Here是一个很好的解释,为什么Get-ChildItem是由Lee Holmes缓慢的。如果您注意到页面底部“Anon 11 Mar 2010 11:11 AM”的评论,他的解决方案可能适合您。

Anon的代码:

# SCOPE: SEARCH A DIRECTORY FOR FILES (W/WILDCARDS IF NECESSARY)
# Usage:
# $directory = "\\SERVER\SHARE"
# $searchterms = "filname[*].ext"
# PS> $Results = Search $directory $searchterms

[reflection.assembly]::loadwithpartialname("Microsoft.VisualBasic") | Out-Null

Function Search {
  # Parameters $Path and $SearchString
  param ([Parameter(Mandatory=$true, ValueFromPipeline = $true)][string]$Path,
  [Parameter(Mandatory=$true)][string]$SearchString
  )
  try {
    #.NET FindInFiles Method to Look for file
    # BENEFITS : Possibly running as background job (haven't looked into it yet)

    [Microsoft.VisualBasic.FileIO.FileSystem]::GetFiles(
    $Path,
    [Microsoft.VisualBasic.FileIO.SearchOption]::SearchAllSubDirectories,
    $SearchString
    )
  } catch { $_ }

}

答案 2 :(得分:2)

我尝试了一些带有大量文件的建议方法(~190.000)。正如Kyle的评论中所提到的,GetFiles在这里并不是很有用,因为它几乎需要永远。

在我的第一次测试中,

cmd dir比Get-ChildItems更好,但看起来,如果使用-Force参数,GCI会加速很多。这样,所需时间与cmd dir大致相同。

P.S。:在我的情况下,由于扩展,我不得不排除大部分文件。这是在gci中使用-Exclude并在其他命令中使用|。因此,仅搜索文件的结果可能略有不同。

答案 3 :(得分:0)

这是一个交互式阅读器,它解析library(dplyr) df1 %>% group_by(ID) %>% mutate(Situation = factor(Situation, levels = c("Other", "Active", "Away")), Situation = levels(droplevels(Situation))[1]) # A tibble: 9 x 2 # Groups: ID [3] # ID Situation # <int> <chr> #1 1 Other #2 1 Other #3 1 Other #4 2 Active #5 2 Active #6 2 Active #7 3 Away #8 3 Away #9 3 Away (可以处理unc路径),并将收集对大多数人来说最重要的3个属性:完整路径,大小,时间戳记

用法类似于df1 <- structure(list(ID = c(1L, 1L, 1L, 2L, 2L, 2L, 3L, 3L, 3L), Situation = c("Active", "Active", "Other", "Active", "Away", "Active", "Away", "Away", "Away")), class = "data.frame", row.names = c(NA, -9L))

并且有一个辅助功能来检查组合大小cmd /c dir

$files_with_details = $faster_get_files.GetFileList($unc_compatible_folder)