在PowerShell v3中运行并行的Invoke-WebRequest作业

Loc*_*eds 5 powershell download background-process cmdlet powershell-3.0

在PowerShell中同时运行后台后台作业非常简单,但我似乎无法使其与新(在v3中)cmdlet Invoke-WebRequest一起使用。

我有数千个文件正在通过PowerShell脚本下载。效果很好,但是连续进行需要几天的时间:

for($f=0;$f -lt $urlList.Count;$f++)
{
    $remote = $urlList[$f] + $fileList[$f]
    $local = 'C:\folder\' + $fileList[$f]
    Invoke-WebRequest $remote -Method Get -OutFile $local -UserAgent FireFox
}
Run Code Online (Sandbox Code Playgroud)

我已经尝试过利用“ AsJob”方法进行多次尝试,但是它们要么出错,要么完全正常,但是没有保存任何本地文件。这是后者的一个示例:

for($f=0;$f -lt $urlList.Count;$f++)
{
    $remote = $urlList[$f] + $fileList[$f]
    $local = 'C:\folder\' + $fileList[$f]
    $command = "Invoke-WebRequest $remote -Method Get -OutFile $local -UserAgent FireFox"
    Start-Job {Invoke-Expression -Command $command}
}
Get-Job|Wait-Job
Run Code Online (Sandbox Code Playgroud)

输出示例:

Id     Name            PSJobTypeName   State         HasMoreData     Location             Command                  
--     ----            -------------   -----         -----------     --------             -------                  
339    Job339          BackgroundJob   Running       True            localhost            Invoke-Expression -Com...
341    Job341          BackgroundJob   Running       True            localhost            Invoke-Expression -Com...
343    Job343          BackgroundJob   Running       True            localhost            Invoke-Expression -Com...
339    Job355          BackgroundJob   Completed     True            localhost            Invoke-Expression -Com...
341    Job357          BackgroundJob   Completed     True            localhost            Invoke-Expression -Com...
343    Job359          BackgroundJob   Completed     True            localhost            Invoke-Expression -Com...
Run Code Online (Sandbox Code Playgroud)

奇怪的是,上面的作业完成的速度几乎和下载关联文件所需的速度一样……因此,数据似乎在某个地方运行-只是没有到达我的保存位置。我假设它要存入内存,但是没有保存就被转储了。尝试添加和删除“ PassThru”选项,但是无论哪种方式都得到相同的结果。还尝试将其传送到Out-File,仍然没有乐趣。不知道为什么这个特定的cmdlet如此令人讨厌。

Kei*_*ill 7

您需要以它们实际进入作业的方式传递参数。在 V3 中,您可以使用 $using: 语法来执行此操作:

for($f=0;$f -lt $urlList.Count;$f++)
{
    $remote = $urlList[$f] + $fileList[$f]
    $local = 'C:\folder\' + $fileList[$f]
    Start-Job {Invoke-WebRequest $using:remote -Method Get -OutFile $using:local -UserAgent FireFox}
}
Get-Job|Wait-Job
Run Code Online (Sandbox Code Playgroud)

顺便说一句,您不需要使用 Invoke-Expression。只需将要在作业中运行的代码放入脚本块(即一组花括号)中即可{...}

  • 我在 $using 上找到了以下信息:[link](http://blogs.msdn.com/b/powershell/archive/2012/06/14/new-v3-language-features.aspx) (2认同)