Loops 在For循环期间显示进度
我有一个ForEach循环,我想显示它的进度:Loops 在For循环期间显示进度,loops,powershell,progress,Loops,Powershell,Progress,我有一个ForEach循环,我想显示它的进度: 1..254 | ForEach-Object {Test-Connection -ErrorAction SilentlyContinue -count 1 -TimeToLive 32 "$ipcut.$_"} #^need to get a progress bar somewhere here^ 在上面的代码中,我尝试过在不同的地方使用write progress,但由于它在1-254之间循环,所以似乎无法正常工作。类似这样的内容 $i
1..254 | ForEach-Object {Test-Connection -ErrorAction SilentlyContinue -count
1 -TimeToLive 32 "$ipcut.$_"}
#^need to get a progress bar somewhere here^
在上面的代码中,我尝试过在不同的地方使用write progress,但由于它在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++}
您不能真正添加进度条并将代码保持为单个语句,但您可以通过分号分隔所需的命令,在一行中完成:
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++}
这使用ForEach对象命令中的-Begin
块将计数器$i
初始化为0。根据注释,使用这种方法,我们必须硬编码集合的总数,因为无法从ForEach对象循环中以编程方式确定它,因为每次迭代都处理集合中的单个项。这是一个很大的问题,因为您是在一个数字范围内进行管道传输,如果您是在一个集合中进行管道传输,我们可以使用该集合的.count
属性来确定总数
然而,同样值得注意的是,使用写入进度
时,您根本不需要显示进度条。您可以使用它向用户显示一条消息(没有移动进度条),该消息至少仍然显示进度(只是不显示您完成整个作业的距离)。这样做可以将代码简化为:
1..254 | ForEach-Object {Write-Progress -Activity "Testing $ipcut.$_"; Test-Connection -ErrorAction SilentlyContinue -count 1 -TimeToLive 32 "$ipcut.$_"}
显示了一个可行的解决方案
只需将Write progress
命令插入现有命令的ForEach对象
脚本块,就不可能获得进度条,但是:
传递给ForEach Object
的脚本块无法预先知道将通过管道传递多少对象,这是以百分比表示进度的先决条件
您必须提前确定迭代次数。
如果您想概括这一点,请使用一个函数,如以下(有意保持简单):
再次注意,所有管道输入都是预先收集的
在您的情况下,您可以按如下方式调用它:
1..254 | Invoke-WithProgress {
Test-Connection -ErrorAction SilentlyContinue -count 1 -TimeToLive 32 "$ipcut.$_"
}
1..254 | Invoke-WithProgress {
Test-Connection -ErrorAction SilentlyContinue -count 1 -TimeToLive 32 "$ipcut.$_"
}