我正在尝试编写一个PowerShell接受管道输入的函数.我想显示一个进度条,使用Write-Progress该管道中每个项目的增量.
例如:
function Write-PipelineProgress {
[Cmdletbinding()]
Param
(
[Parameter(Position=0, Mandatory=$true, ValueFromPipeline=$true, ValueFromPipelineByPropertyName=$true)] `
[object[]] $Input,
[string] $Activity = "Processing items"
)
Begin { Write-Progress -Activity $Activity -Status "Preparing" }
Process {
# how do i determine how much progress we've made?
$percentComplete = ... ?
Write-Progress -Activity $Activity -Status "Working" -PercentComplete $percentComplete
# return current item, so processing can continue
$_
}
End { Write-Progress -Activity $Activity -Status "End" -Completed }
}
Get-ChildItem | Write-PipelineProgress -Activity "Listing files"
Run Code Online (Sandbox Code Playgroud)
我如何确定进度(完成百分比)?
您需要知道管道中的项目数以跟踪进度.
Powershell 3.0可以让您计算管道中的内容.Count,$Input如果正确声明管道参数,则无需执行任何工作,除了访问属性.它还意味着您可以取消begin {} process {} end {}块,只需要一个简单的功能.
早期版本没有该Count属性,因此您首先必须迭代并捕获管道以获取计数然后再次处理,这不是那么有效,我将在稍后展示.
Powershell V2版本:
function Show-ProgressV2{
param (
[Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
[PSObject[]]$InputObject,
[string]$Activity = "Processing items"
)
Begin {$PipeArray = @()}
Process {$PipeArray+=$InputObject}
End {
[int]$TotItems = ($PipeArray).Count
[int]$Count = 0
$PipeArray|foreach {
$_
$Count++
[int]$percentComplete = [int](($Count/$TotItems* 100))
Write-Progress -Activity "$Activity" -PercentComplete "$percentComplete" -Status ("Working - " + $percentComplete + "%")
}
}
}
Run Code Online (Sandbox Code Playgroud)
Powershell V3版本:
function Show-ProgressV3{
[CmdletBinding()]
param (
[Parameter(Mandatory=$true, Position=0, ValueFromPipeline=$true)]
[PSObject[]]$InputObject,
[string]$Activity = "Processing items"
)
[int]$TotItems = $Input.Count
[int]$Count = 0
$Input|foreach {
$_
$Count++
[int]$percentComplete = ($Count/$TotItems* 100)
Write-Progress -Activity $Activity -PercentComplete $percentComplete -Status ("Working - " + $percentComplete + "%")
}
}
Run Code Online (Sandbox Code Playgroud)
效率
比较两者,V3功能大约快5-6倍,具体取决于管道的大小.
考虑以下预过滤文件列表,查找.jpg我家驱动器中的所有文件,选择前200个文件并排序和列出,根据您的评论在管道中使用该功能3次:
$V2 = Measure-Command {Get-ChildItem -Filter *.jpg -Recurse `
| Show-ProgressV2 -Activity "Selecting" `
| Select-Object -First 200 `
| Show-ProgressV2 -Activity "Sorting" `
| Sort-Object -Property FullName `
| Show-ProgressV2 -Activity "Listing" `
| FL}
$V3 = Measure-Command {Get-ChildItem -filter *.jpg -Recurse `
| Show-ProgressV3 -Activity "Selecting" `
| Select-Object -First 200 `
| Show-ProgressV3 -Activity "Sorting" `
| Sort-Object -Property FullName `
| Show-ProgressV3 -Activity "Listing" `
| FL}
$V2
$V3
Run Code Online (Sandbox Code Playgroud)
这给了我以下时间:
PS C:\Users\Graham> C:\Users\Graham\Documents\Stack_ShowProgress_Pipeline.ps1
Days : 0
Hours : 0
Minutes : 0
Seconds : 48
Milliseconds : 360
Ticks : 483607111
TotalDays : 0.000559730452546296
TotalHours : 0.0134335308611111
TotalMinutes : 0.806011851666667
TotalSeconds : 48.3607111
TotalMilliseconds : 48360.7111
Days : 0
Hours : 0
Minutes : 0
Seconds : 8
Milliseconds : 335
Ticks : 83358374
TotalDays : 9.6479599537037E-05
TotalHours : 0.00231551038888889
TotalMinutes : 0.138930623333333
TotalSeconds : 8.3358374
TotalMilliseconds : 8335.8374
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
9347 次 |
| 最近记录: |