PowerShell Invoke-命令严重的性能问题

时间:2017-09-19 20:11:22

标签: powershell scripting remote-access

我很高兴有效地在远程系统上运行脚本。在本地运行时,命令需要20秒。使用Invoke-Command运行时,该命令需要10或15分钟 - 即使“远程”计算机是我的本地计算机。

有人可以向我解释这两个命令之间的区别以及为什么Invoke-Command需要更长的时间吗?

在MACHINE上本地运行:get-childitem C:\ -Filter *.pst -Recurse -Force -ErrorAction SilentlyContinue

在\ MACHINE上远程运行(行为相同,而MACHINE是我的本地机器或远程机器:invoke-command -ComputerName MACHINE -ScriptBlock {get-childitem C:\ -Filter *.pst -Recurse -Force -ErrorAction SilentlyContinue}

注意:该命令返回5个文件对象

编辑:我认为部分问题可能是重新分析点。在本地运行时get-childitem(和DIR /a-l)不要遵循交接点。当远程运行时,即使我使用-attributes !ReparsePoint开关)

也可以

EDIT2:但是,如果我运行命令invoke-command -ComputerName MACHINE -ScriptBlock {get-childitem C:\ -Attributes !ReparsePoint -Force -ErrorAction SilentlyContinue},我看不到连接点(即文档和设置)。因此,很明显DIR /a-lget-childitem -attributes !ReparsePoint都不会阻止它递归到重新分析点。相反,它似乎只过滤实际的条目本身。

非常感谢!

4 个答案:

答案 0 :(得分:0)

如果它是一个大型目录结构,并且您只需要文件的完整路径名,则应该能够通过使用旧dir命令而不是Get-ChildItem来大大提高速度:

invoke-command -ComputerName MACHINE -ScriptBlock {cmd /c dir c:\*.pst /s /b /a-d /a-l}

答案 1 :(得分:0)

问题似乎是重新分析点。出于某种原因,当本地运行命令时,拒绝访问重新分析点(如Documents and Settings)。远程运行命令后,DIRGet-ChildItem都将递归到重新分析点。

使用-Attributes !ReparsePoint的{​​{1}}和get-childitem的{​​{1}}开关并不能阻止这种情况发生。相反,看起来这些开关只会阻止重新分析点出现在文件列表输出中,但它不会阻止命令递归到这些文件夹。

相反,我必须编写一个递归脚本并自己进行目录递归。我的机器上的速度有点慢。而不是在本地大约20秒,它花了大约1分钟。远程接近2分钟。

以下是我使用的代码: 编辑:由于PowerShell 2.0,PowerShell远程处理和原始代码的内存使用的所有问题,我不得不更新我的代码,如下所示。

/a-l

答案 2 :(得分:0)

尝试使用远程会话:

$yourLoginName = 'loginname'
$server        = 'tagetserver'
$t = New-PSSession $server -Authentication CredSSP -Credential (Get-Credential $yourLoginName)
cls
"$(get-date) - Start"
$r = Invoke-Command -Session $t -ScriptBlock{[System.IO.Directory]::EnumerateFiles('c:\','*.pst','AllDirectories')}
"$(get-date) - Finish"

答案 3 :(得分:0)

我遇到了同样的问题。 很明显,Powershell通过PSRemoting传输数组存在问题。

它演示了这个小实验(更新):

$session = New-PSSession localhost

$arrayLen = 1024000
Measure-Command{
  Invoke-Command -Session $session -ScriptBlock {
    Write-Host ("Preparing test array {0} elements length..." -f $using:arrayLen)
    $global:result = [Byte[]]::new($using:arrayLen)
    [System.Random]::new().NextBytes($result)
  }
} |% {Write-Host ("Completed in {0} sec`n" -f $_.TotalSeconds)}

Measure-Command{
  Invoke-Command -Session $session -ScriptBlock {
    Write-Host ("Transfer array ({0})" -f $using:arrayLen)
    return $result
  } | Out-Null
} |% {Write-Host ("Completed in {0} sec`n" -f $_.TotalSeconds)}

Measure-Command{
  Invoke-Command -Session $session -ScriptBlock {
    Write-Host ("Transfer same array nested in a single object")
    return @{array = $result}
  } 
} |% {Write-Host ("Completed in {0} sec`n" -f $_.TotalSeconds)}

我的输出(以ms为单位的时间):

Preparing test array 1024000 elements length...
Completed in 0.0211385 sec

Transfer array (1024000)
Completed in 48.0192142 sec

Transfer same array nested in a single object
Completed in 0.0990711 sec

如您所见,阵列传输的时间超过一分钟。 尽管尺寸

,但单个物体在几秒钟内就会被转移