在PowerShell中显示高级进度条

如果你需要编写一些PowerShell脚本,尤其在处理一些相对复杂的任务时,你可能希望添加进度条的功能,以便随时可以了解进展情况。

Write-Progress 这个命令可以帮助你完成简单的需求,请参考官方文档即可,但下图一个示例,它会同时进行多个任务,并且能每个任务独立更新进度。.

在PowerShell中显示高级进度条

范例代码如下,请在PowerShell 7.x 以上版本运行测试。

using namespace System.Collections
function Test-Progress {        $files = Get-ChildItem `    | Select-Object -Property BaseName `    | Where-Object { $_.BaseName.length -gt 0 } `    | Select-Object -First 10
    $origin = @{}    $index = 1    $files | ForEach-Object { $origin.($_.BaseName) = @{            Id              = $index++            Activity        = "{0,30}" -f $_.BaseName            Status          = "Pending..."            PercentComplete = 1             # 这里设置为0的话,有点问题,那个进度条看起来是100%        } }
    $sync = [hashtable]::Synchronized($origin)
    $job = $files | ForEach-Object -AsJob -Parallel {        $copySync = $using:sync        $process = $copySync.($_.BaseName)                1..100 | ForEach-Object {            $process.Status = "Processing... $_ "            Start-Sleep -Milliseconds `                (Get-Random -Maximum 300 -Minimum 100)                            $process.PercentComplete = $_        }
        $process.Status = "Done"    }
    while ($job.State -eq 'Running') {        $sync.Keys | Foreach-Object {            if (![string]::IsNullOrEmpty($sync.$_.keys)) {                $param = $sync.$_                 Write-Progress @param            }        }        Start-Sleep -Seconds 0.1    }}

如果要做多线程脚本,建议用Powershell 7.0以上版本,它的Foreach-Object已经直接支持Parallel的方式。如果在早期版本,也是能够实现的,但需要多写很多额外的代码。