5

PowerShell で同時バックグラウンド ジョブを実行するのは非常に簡単ですが、新しい (v3 の) コマンドレット 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 にパイプしようとしましたが、まだ喜びはありません。この特定のコマンドレットがそのようなバグになっている理由がわかりません。

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 を使用する必要はありません。ジョブで実行したいコードを scriptblock 内、つまり中括弧のセットに入れるだけです{...}

于 2013-03-03T05:16:14.287 に答える