我有一個foreach循環,我想表明的進展:時顯示進度環
1..254 | ForEach-Object {Test-Connection -ErrorAction SilentlyContinue -count
1 -TimeToLive 32 "$ipcut.$_"}
#^need to get a progress bar somewhere here^
我已經使用在上面的代碼不同的地方寫進度試過了,似乎並不能得到它工作,因爲它從1-254循環。
我有一個foreach循環,我想表明的進展:時顯示進度環
1..254 | ForEach-Object {Test-Connection -ErrorAction SilentlyContinue -count
1 -TimeToLive 32 "$ipcut.$_"}
#^need to get a progress bar somewhere here^
我已經使用在上面的代碼不同的地方寫進度試過了,似乎並不能得到它工作,因爲它從1-254循環。
這樣的事情?
$ipCut ='192.168.1' ### not included in the original question
$arrTest = 1..254
$all = $arrTest.Count
$i = 0
$arrTest | ForEach-Object {
Write-Progress -PercentComplete (
$i*100/$all) -Activity "PINGs completed: $i/$all" -Status 'Working'
Test-Connection -ErrorAction SilentlyContinue -count 1 -TimeToLive 32 "$ipcut.$_"
$i++
}
的
Write-Progress
cmdlet顯示在描繪一個正在運行的命令 或腳本的狀態在Windows PowerShell命令窗口中的進度條。您可以選擇條形反映的指標以及進度條上方和下方顯示的文字。
編輯:重寫上述代碼作爲一個班輪非常簡單:僅通過分號(;
)分離特定命令,而不是換行:
$arr=1..254; $all=$arr.Count; $i=0; $arr|ForEach-Object{Write-Progress -PercentComplete ($i*100/$all) -Activity "PINGs completed: $i/$all" -Status 'Working'; Test-Connection -ErrorAction SilentlyContinue -count 1 -TimeToLive 32 "$ipcut.$_"; $i++}
或簡單通過硬編碼1..254
的和254
代替$arr
和$all
,分別爲:
$i=0; 1..254|ForEach-Object{Write-Progress -PercentComplete ($i*100/254) -Activity "PINGs completed: $i/254" -Status 'Working'; Test-Connection -ErrorAction SilentlyContinue -count 1 -TimeToLive 32 "$ipcut.$_"; $i++}
這顯然有效,但不是我正在尋找的。我想將寫入過程集成到上面的現有代碼中(請參閱問題)。重新格式化會很好,但我需要它是一個單一的聲明。 – systech
你不能真正增加一個進度條,並保持你的代碼作爲一個單獨的語句,但你可以做到這一點在一行經由分號分隔所需的命令:
1..254 | ForEach-Object -Begin {$i = 0} -Process {Write-Progress -PercentComplete ($i/254*100) -Activity "Tests completed: $i/254" -Status "Testing $ipcut.$_"; Test-Connection -ErrorAction SilentlyContinue -count 1 -TimeToLive 32 "$ipcut.$_"; $i++}
這將使用-Begin
塊在ForEach-Object命令中將計數器$i
初始化爲0.根據註釋,使用這種方法,我們必須硬編碼集合的總數,因爲無法從ForEach-Object循環內以編程方式確定它,因爲每次迭代都會執行與集合中的單個項目。這主要是有問題的,因爲你在數字範圍內滾動,就好像你在一個集合中滾動,我們可以使用該集合的.count
屬性來確定總數。
然而,它也是值得注意的,你不已經在所有使用Write-Progress
顯示進度條。你可以用它來向用戶顯示一條消息(沒有任何移動進度條),它至少仍然表現出進步(只是沒有多大的工作量)。這樣做可以簡化代碼:
1..254 | ForEach-Object {Write-Progress -Activity "Testing $ipcut.$_"; Test-Connection -ErrorAction SilentlyContinue -count 1 -TimeToLive 32 "$ipcut.$_"}
Josef Z.'s helpful answer向您展示了一個可行的解決方案。
你的具體願望簡單地通過插入一個Write-Progress
命令加入到現有的命令的ForEach-Object
腳本塊得到一個進度條是不可能的,但是:
腳本程序塊傳遞給ForEach-Object
沒有事先知道方式有多少物體將通過管道傳遞,這是顯示百分比方面進展的先決條件。
您必須確定迭代次數提前的時間。
如果你想概括這一點,使用功能,如下面的(故意保持簡單):
function Invoke-WithProgress {
param(
[scriptblock] $Process,
[string] $Activity = 'Processing'
)
# Collect the pipeline input ($Input) up front in an array list.
$al = New-Object System.Collections.ArrayList 100 # 100 is the initial capacity
foreach ($o in $Input) { $null = $al.Add($o) }
# Count the number of input objects.
$count = $al.Count; $i = 0
# Process the input objects one by one, with progress display.
$al | ForEach-Object {
Write-Progress -PercentComplete ((++$i)*100/$count) -Activity "$Activity $i/$count..."
. $Process
}
}
再次注意,所有的管道輸入收集前面 。
在你的情況,你會調用它,如下所示:
1..254 | Invoke-WithProgress {
Test-Connection -ErrorAction SilentlyContinue -count 1 -TimeToLive 32 "$ipcut.$_"
}
不知道爲什麼會有人下來票這個問題。它符合標準,並且之前從我以前的搜索中沒有詢問過。 – systech