基本的なスクリプトのアイデア:こんにちは。特定の実行可能ファイルのファイルサイズを確認し、それらをテキストファイルに保存するために使用するPowerShellスクリプトを作成しました。次回スクリプトを実行するときに、ファイルサイズが異なる場合は、テキストファイル内のファイルサイズが新しいファイルサイズに置き換えられます。
構造:メインスクリプトと、ファイルサイズを確認したい実行可能ファイルごとに多くのスクリプトを含むフォルダーがあります。したがって、フォルダ内のスクリプトは、実行可能ファイルへのリンクを含む文字列を返します。この文字列は、メインスクリプトに送られます。
コード:
$progdir = "C:\script\programms"
$items = Get-ChildItem -filter *.ps1 -Path $progdir
$webclient = New-Object System.Net.WebClient
$filesizes = get-content C:\updatechecker\programms\filesizes
if ($filesizes.length -ne $items.length) {
if ($filesizes.length -eq $null) {
Write-Host ("Building filesize database...") -nonewline
}
else {
Write-Host ("Rebuilding filesize database...") -nonewline
}
clear-content C:\programms\filesizes
for ($i=0; $i -le $items.length-1; $i++) {
$command = "c:\programms\" + $items[$i].name
$link = & $command
$webclient.OpenRead($link) | Out-Null
$filesize = $webclient.ResponseHeaders["Content-Length"]
$filesize >> C:\programms\filesizes
}
echo "Done."
}
else {
...
質問:このforループは、並行して実行したいものです。私はPowerShellを初めて使用するので、これを行う方法についてアドバイスが必要です。見つけたいくつかのことを実装しようとしましたが、正しく機能しませんでした(終了するのに非常に長い時間がかかり、エラーが出力され、filesizesファイルにfilesizesの複数のエントリがありました)。同期の問題だと思います。どういうわけか、重要な部分をロックする必要があります。PowerShellにompparallelのようなものはありませんか?:P
どんな助けでも、これを達成する方法についてのアドバイスをいただければ幸いです:)
編集:
Get-Job | Remove-Job -Force
$progdir = "C:\programms"
$items = Get-ChildItem -filter *.ps1 -Path $progdir
$webclient = New-Object System.Net.WebClient
$filesizes = get-content C:\programms\filesizes
$jobWork = {
param ($MyInput)
$command = "c:\programms\" + $MyInput
$link = & $command
$webclient.OpenRead($link) | Out-Null
$filesize = $webclient.ResponseHeaders["Content-Length"]
$filesize >> C:\programms\filesizes
}
foreach ($item in $items) {
Start-Job -ScriptBlock $jobWork -ArgumentList $item.name | out-null
}
Get-Job | Wait-Job
Get-Job | Receive-Job | Out-GridView | out-null
echo "Done."
編集2:ここで見つけた使用済みコード:http ://ryan.witschger.net/?p = 22
$mutex = new-object -TypeName System.Threading.Mutex -ArgumentList $false, “RandomGlobalMutexName”;
$MaxThreads = 4
$SleepTimer = 500
$jobWork = {
param ($MyInput)
$webclient = New-Object System.Net.WebClient
$command = "c:\programms\" + $MyInput
$link = & $command
$webclient.OpenRead($link) | Out-Null
$result = $mutex.WaitOne();
$file = $webclient.ResponseHeaders["Content-Length"]
$file >> C:\programms\filesizes
$mutex.ReleaseMutex();
}
$progdir = "C:\programms"
$items = Get-ChildItem -filter *.ps1 -Path $progdir
$webclient = New-Object System.Net.WebClient
$filesizes = get-content C:\programms\filesizes
Get-Job | Remove-Job -Force
$i = 0
ForEach ($item in $items){
While ($(Get-Job -state running).count -ge $MaxThreads){
Start-Sleep -Milliseconds $SleepTimer
}
$i++
Start-Job -ScriptBlock $jobWork -ArgumentList $item.name | Out-Null
}