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

时间:2013-03-03 04:54:56

标签: powershell background-process powershell-v3.0 downloading cmdlet

在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
}

我已经多次尝试利用'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

输出示例:

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...

奇怪的是,上面的工作完成的速度和下载相关文件的速度大致相同......所以似乎数据正在某处 - 而不是我的保存位置。我认为它会记忆但被丢弃却没有被保存。试图添加和删除'PassThru'选项,但无论如何都得到相同的结果。还尝试将它管道输出到Out-File,仍然没有乐趣。不确定为什么这个特定的cmdlet会成为这样的错误。

1 个答案:

答案 0 :(得分:4)

您需要以实际进入作业的方式传递参数。在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

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