5

在 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 如此糟糕。

4

1 回答 1

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

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

于 2013-03-03T05:16:14.287 回答