如果你需要编写一些PowerShell脚本,尤其在处理一些相对复杂的任务时,你可能希望添加进度条的功能,以便随时可以了解进展情况。
Write-Progress 这个命令可以帮助你完成简单的需求,请参考官方文档即可,但下图一个示例,它会同时进行多个任务,并且能每个任务独立更新进度。
范例代码如下,请在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的方式。如果在早期版本,也是能够实现的,但需要多写很多额外的代码。