当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 如何在PowerShell中显示进度条?

作者:精品下载站 日期:2024-12-14 21:41:34 浏览:14 分类:玩电脑

如何在PowerShell中显示进度条?


PowerShell 提供了广泛的功能,并允许用户编写可以轻松执行复杂任务的脚本。然而,当涉及到用户体验时,PowerShell 脚本有时会让用户一无所知,不知道任务的进度或状态!运行脚本而不知道需要多长时间才能完成可能会令人沮丧。这就是进度条的用武之地。进度条允许您实时查看脚本的进度,让您估计完成需要多长时间。添加进度条是改善 PowerShell 脚本用户体验的好方法。在本初学者指南中,我们将探索在 PowerShell 中实现进度条和视觉反馈的不同方法。

在 PowerShell 中使用进度条的好处

如果没有进度条,用户无法知道长时间运行的 PowerShell 脚本是否正在取得进展。一个简单的进度条通过显示已完成工作的清晰可视化来解决这个问题。在 PowerShell 中使用进度条非常有用,尤其是在运行长脚本时。以下是一些原因:

1. 实时视觉反馈

进度条提供脚本进度的实时反馈。这种反馈非常有帮助,尤其是在运行长脚本时。它可以让您看到脚本正在运行并取得进展,这可以让人放心。如果没有适当的反馈,用户可能会对任务的进度感到不确定,从而导致沮丧和困惑。

2. 时间估算以跟踪进度

进度条还可以估计脚本完成所需的时间。这个估计非常有帮助,特别是在运行需要很长时间才能完成的脚本时。它允许您相应地计划时间,并确保您不会浪费时间等待脚本完成。

3、改善用户体验

使用进度条还可以改善脚本的用户体验。它提供了进度的可视化表示,这比简单的控制台输出更有吸引力。这可以使您的脚本更加用户友好且更易于使用。

了解 PowerShell 中的 Write-Progress cmdlet

进度条是指示任务或操作进度的图形表示。它通常由一个逐渐填满的条组成,表示任务的完成百分比。进度条广泛应用于软件应用程序中,为用户提供正在进行的流程的可视化表示。在 PowerShell 脚本编写的上下文中,进度条可用于显示长时间运行的操作的进度,例如迭代大型数据集或执行复杂的计算。

Write-Progress 是 PowerShell 中的一个 cmdlet,可让您在控制台中显示进度条。它有几个参数允许您自定义进度条的外观,包括完成百分比、状态消息和活动名称。以下是可与 Write-Progress 一起使用的参数:

基本的写入进度语法如下所示:


Write-Progress 
[-Activity] <String> 
[[-Status] <String>] 
[-PercentComplete <Int32>] 
[-SecondsRemaining <Int32>] 
[-Id <Int32>] 
[-ParentId <Int32>] 
[-Completed] 
[-SourceId <Int32>] 
[-CurrentOperation <String>] 
[<CommonParameters>]

以下是 Write-Progress cmdlet 的重要参数:

Activity

Activity 参数指定进度条的标题。这将显示为文本的第一行。

Status

这有助于在进度条的状态栏中显示活动的当前状态或正在运行的命令的状态

PercentComplete

完成 0% 到 100%

SecondsRemaining

倒计时器

Id

用于更新特定栏的唯一 ID

ParentId

组子进度条

写入进度示例

要使用 Write-Progress 将进度条添加到 PowerShell 脚本,请按照下列步骤操作:

  1. 使用 Write-Progress cmdlet 创建新的进度栏。
  2. 指定参数,例如 -Activity-Status-PercentComplete-SecondsRemaining -CurrentOperation 自定义进度条。
  3. 使用 Write-Progress cmdlet 以及 -PercentComplete 的更新值定期更新进度栏。
  4. 任务完成后,使用 Complete 参数来完成进度条。

要持续更新进度条,我们必须在脚本逻辑中的某些点处放置 Write-Progress 调用,每次都会增加 PercentComplete。以下是使用 Write-Progress cmdlet 显示进度条的 PowerShell 脚本示例:


$Collection = 1..100
ForEach ($Item in $Collection) {
    Write-Progress -PercentComplete ($Item/100*100) -Status "Processing Items" -Activity "Item $item of 100"
    # Your actual script logic here
    Start-Sleep -Milliseconds 50
}

通过向 PowerShell 脚本添加进度条,您可以让用户了解脚本执行的状态,让他们清楚地了解已完成多少工作和还剩多少工作。以下是 PowerShell 命令窗口中的输出:

[玩转系统] 如何在PowerShell中显示进度条?

这是 PowerShell ISE 中的样子:

[玩转系统] 如何在PowerShell中显示进度条?

如何在PowerShell中添加写入进度?

在 PowerShell 中使用 Write-Progress 相对简单。以下是有关如何使用它的分步指南:

第 1 步:定义变量

第一步是定义将在脚本中使用的变量或集合。这些变量将包含您将要处理的数据集的集合。

第二步:启动进度条并执行操作

下一步是使用 Write-Progress cmdlet 启动进度栏并执行目标操作。您需要指定活动名称和状态消息。

步骤 3:更新进度条

当脚本运行并进行时,您应该使用 Write-Progress cmdlet 更新进度栏。指定完成百分比、当前操作和估计剩余时间参数以向用户提供更新。

使用 Write-Progress 的常见方法是在脚本的 For 循环中。


For($i=1; $i -le 100; $i++){

  Write-Progress -Activity "Processing Files" -Status "$i% Complete" -PercentComplete $i
  
  # Perform loop action
  sleep -Milliseconds 100  
}

这将从 1 迭代到 100,每次都会更新进度条当前的完成百分比。您可以更新状态消息以提供有关循环迭代正在运行的更多上下文。

第四步:完成进度条

脚本运行完毕后,您必须使用 Write-Progress cmdlet 来完成进度条。这将确保进度条从控制台中删除。

带倒计时器的进度条

要在进度栏中显示倒计时器,请使用 SecondsRemaining 参数:


Write-Progress -Activity "Installing" -Status "Time Remaining" -SecondsRemaining $timeLeft

随着 $timeLeft 的减少,进度条将直观地倒计时预计剩余时间。这是一个实时示例:


$progressParams = @{
    Activity = "Processing data"
    Status = "In progress"
    PercentComplete = 0
    SecondsRemaining = 60
    CurrentOperation = "Initializing"
}

Write-Progress @progressParams

$data = 1..10000
$index = 1
# Start the countdown timer
$timer = [Diagnostics.Stopwatch]::StartNew()

# Loop through the data and update the progress bar
foreach ($item in $data) {
    # Perform some operation on $item

    # Update the progress bar
    $progressParams.PercentComplete = ($index / $data.Count) * 100
    $progressParams.CurrentOperation = "Processing item $index of $($data.Count)"
    $progressParams.SecondsRemaining = (($timer.Elapsed.TotalSeconds / $index) * ($data.Count - $index)).ToString("F0")
    Write-Progress @progressParams

    $index++
}

# Complete the progress bar
Write-Progress -Completed -Activity "Completed"

它在 PowerShell ISE 中的外观如下:

[玩转系统] 如何在PowerShell中显示进度条?

以下是使用 PowerShell Write-Progress cmdlet 的倒数计时器的更多示例:


Function Start-Countdown {
    param (
        [Parameter(Mandatory=$true)]
        [int]$Seconds
    )

    # Countdown start time
    $StartTime = Get-Date
    $ElapsedTime =0

    # While there are still seconds left
    While ($ElapsedTime -lt $seconds) {
        # Calculate elapsed time
        $ElapsedTime = [math]::Round(((Get-Date) - $StartTime).TotalSeconds,0)
        
        # Update the progress bar
        Write-Progress -Activity "Counting down..." -Status ("Time left: " + ($Seconds - $ElapsedTime) + " seconds") -PercentComplete (($elapsedTime / $Seconds) * 100)
        #$Seconds = $Seconds - $elapsedTime

        # Wait for a second
        Start-Sleep -Seconds 1
    }

    # Once countdown is complete, close the progress bar
    Write-Progress -Activity "Counting down..." -Completed 
}

# Call the function to start a 10-second countdown
Start-Countdown -Seconds 10

这是如何在 While 循环中显示进度条的另一个示例:


# Set total time for countdown timer
$timeRemaining = 20

while($timeRemaining -gt 0){

  # Calculate percentage
  $percentComplete = (($timeRemaining / 60) * 100)

  # Update progress bar
  Write-Progress -Activity "Deployment in progress" -Status "Time remaining: $timeRemaining seconds" -PercentComplete $percentComplete -SecondsRemaining $timeRemaining

  # Decrement timer
  $timeRemaining--

  # Wait 1 second
  Start-Sleep -Seconds 1
}

在 PowerShell ForEach 循环中使用进度条

在 foreach 循环中使用进度条非常有用,尤其是在迭代大量项目时。以下是如何在 foreach 循环中使用进度条的示例:


$Items = 1..10000

Write-Progress -Activity "Processing Items" -Status "Starting" -PercentComplete 0

foreach ($Item in $Items) {
    $PercentComplete = (($Item / $Items.Count) * 100)
    $Status = "Processing Item $($Item)"

    Write-Progress -Activity "Processing Items" -Status $Status -PercentComplete $PercentComplete

    # Do some processing
}

Write-Progress -Activity "Processing Items" -Status "Complete" -PercentComplete 100

使用进度条进行多项操作

对于涉及多个操作的大量脚本,您可以对进度条进行分段:


Write-Progress -Activity "Main Task" -Status "Task 1 of 3" -PercentComplete 33
# Task 1 logic
Start-Sleep -Seconds 1

Write-Progress -Activity "Main Task" -Status "Task 2 of 3" -PercentComplete 66
# Task 2 logic
Start-Sleep -Seconds 1

Write-Progress -Activity "Main Task" -Status "Task 3 of 3" -PercentComplete 100
# Task 3 logic
Start-Sleep -Seconds 1

[玩转系统] 如何在PowerShell中显示进度条?

用于多级操作的嵌套(父子)进度条

当您有多级流程时,父子进度条特别有用。这是使用 Write-Progress 的父子进度条的示例。假设您正在处理多个文件,对于每个文件,您需要完成多项任务:


# Parent loop - processing files
1..5 | ForEach-Object {
    $fileNumber = $_

    # Parent progress
    Write-Progress -Activity "Processing Files" -Status "File $fileNumber of 5" -PercentComplete (($fileNumber / 5) * 100) -id 0

    # Simulate some file-specific tasks in a child loop
    1..10 | ForEach-Object {
        $taskNumber = $_

        # Child progress (nested within the parent)
        Write-Progress -Activity "Performing Task on File $fileNumber" -Status "Task $taskNumber of 10" -PercentComplete (($taskNumber / 10) * 100) -ParentId 0

        # Simulating time taken for each task with sleep
        Start-Sleep -Milliseconds 100
    }
}

# Completing the parent progress bar
Write-Progress -Activity "Processing Files" -Completed -Status "All files processed!"

子进度条的 Write-Progress 中的 -ParentId 参数告诉 PowerShell 该进度条是另一个进度条的子项。 ID 0 通常指的是最近的父写入进度栏。输出:

[玩转系统] 如何在PowerShell中显示进度条?

当您运行上述脚本时,您将看到文件处理的顶级进度条和每个文件上的任务的嵌套进度条。

PowerShell 中的进度条 GUI

对于基于 GUI 的进度条,可以使用 Windows.Forms.ProgressBar .NET 控件。

这是一个示例脚本:


Add-Type -AssemblyName System.Windows.Forms

$progressForm = New-Object System.Windows.Forms.Form
$progressForm.Width = 300
$progressForm.Height = 150
$progressForm.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedSingle
$progressForm.Text = "Processing data..."

$progressBar = New-Object System.Windows.Forms.ProgressBar
$progressBar.Location = New-Object System.Drawing.Point(10, 50)
$progressBar.Size = New-Object System.Drawing.Size(280, 20)
$progressForm.Controls.Add($progressBar)

$progressLabel = New-Object System.Windows.Forms.Label
$progressLabel.Location = New-Object System.Drawing.Point(10, 20)
$progressLabel.Size = New-Object System.Drawing.Size(280, 20)
$progressLabel.Text = "0% Complete"
$progressLabel.TextAlign = [System.Drawing.ContentAlignment]::MiddleCenter
$progressForm.Controls.Add($progressLabel)

$progressForm.Show()

$data = 1..100
$index = 1
# Loop through the data and update the progress bar
foreach ($item in $data) {
    # Perform some operation on $item

    # Update the progress bar
    $progressPercent = ($index / $data.Count) * 100
    $progressBar.Value = $progressPercent
    $progressLabel.Text = "$progressPercent% Complete"
    Start-Sleep -Milliseconds 100
    $index++
}

$progressForm.Close()

这通过设置最小值、最大值和步长值等属性来创建可配置的进度条。然后可以通过增加脚本中的 $ProgressBar.Value 来更新控件。

[玩转系统] 如何在PowerShell中显示进度条?

PowerShell 中写入进度的实际示例

让我们看一下如何在 PowerShell 中使用 Write-Progress 的一些示例:

示例 1:使用进度条复制文件

在此示例中,我们使用 Write-Progress 来显示将文件从一个位置复制到另一个位置的脚本的进度。


$Files = Get-ChildItem -Path "C:\Source"
$Destination = "C:\Destination"

$TotalFiles = $Files.Count
$Count = 0

Write-Progress -Activity "Copying Files" -Status "Starting" -PercentComplete 0

foreach ($File in $Files) {
    $Count++
    $PercentComplete = (($Count / $TotalFiles) * 100)
    $Status = "Copying $($File.Name)"

    Write-Progress -Activity "Copying Files" -Status $Status -PercentComplete $PercentComplete

    Copy-Item $File.FullName $Destination -Force
}

Write-Progress -Activity "Copying Files" -Status "Complete" -PercentComplete 100

示例2:带进度条下载文件

在此示例中,我们使用 Write-Progress 来显示从 Internet 下载文件的脚本的进度。


$Urls = @(
    "https://www.microsoft.com/downloads/SharePointSP1.msi",
    "https://www.microsoft.com/downloads/SharePointSP2.msi",
    "https://www.microsoft.com/downloads/SharePointSP3.msi"
)

# Destination folder
$destinationFolder = "C:\Downloads"

# Ensure the destination folder exists
if (-not (Test-Path $destinationFolder)) {
    New-Item -Path $destinationFolder -ItemType Directory
}

# Download each file
$totalUrls = $urls.Count
for ($i=0; $i -lt $totalUrls; $i++) {
    $url = $urls[$i]
    $fileName = [System.IO.Path]::GetFileName($url)  # Extract file name from URL
    $destinationPath = Join-Path -Path $destinationFolder -ChildPath $fileName

    # Display main progress
    Write-Progress -Activity "Downloading files" -Status ("Downloading " + $fileName) -PercentComplete (($i / $totalUrls) * 100)

    # Download file with sub-progress bar for individual file download
    Invoke-WebRequest -Uri $url -OutFile $destinationPath -Verbose
}

Write-Progress -Activity "Downloading files" -Completed -Status "All files downloaded!"
Write-Host "All files downloaded successfully!" -ForegroundColor Green

在 PowerShell 中使用进度条的最佳实践

在 PowerShell 中使用进度条非常有用,但是您应该遵循一些最佳实践,以确保您的脚本尽可能高效:

  • 仅在必要时使用进度条:虽然进度条很有帮助,但如果过度使用,它们也会减慢脚本的速度。仅在必要时使用进度条。如果任务立即完成或在很短的时间内完成,则显示进度条可能是不必要的,甚至会适得其反,因为它可能会闪烁得太快,用户看不到。
  • 经常更新进度条:经常更新进度条,为用户提供实时反馈。这将确保用户知道脚本正在运行并取得进展。
  • 使用清晰简洁的状态消息:使用 -Activity 和 -Status 参数提供有关正在发生的情况的清晰简洁的信息。使用 -CurrentOperation 参数提供额外的上下文,特别是如果它可以帮助用户理解当前任务。
  • 正确计算百分比:确保准确计算您的 -PercentComplete 值。它的范围应该是 0 到 100,代表完成百分比。
  • 对多级任务使用嵌套进度条:如果您的脚本在任务中包含任务(例如复制多个文件夹,其中每个文件夹包含多个文件),请使用父子进度条。使用 -Id 和 -ParentId 参数可以正确管理和显示嵌套进度条。
  • 完成进度条:使用 -Completed 开关表示任务结束,确保进度条消失或指示完成。另外,在操作开始之前将进度显示为 0%。
  • 使用大数据集测试您的脚本:使用大数据集测试您的脚本,以确保进度条正常工作并且不会减慢脚本速度。

解决 PowerShell 中进度条的常见问题

虽然在 PowerShell 中使用进度栏相对简单,但您可能会遇到一些常见问题。以下是解决这些问题的一些提示:

1.进度条不更新

如果进度条没有更新,请确保足够频繁地更新。检查您的 -PercentComplete 计算。确保它在循环或流程中按预期更新。对于快速处理项目的循环,请考虑使用 Start-Sleep 添加一个小的延迟,以获得视觉清晰度。

如果您经常更新它但它仍然不起作用,请尝试在新的 PowerShell 窗口中运行脚本。

2.进度条不显示

如果未显示进度条,请确保使用 Write-Progress cmdlet 启动它。如果您使用 Write-Progress cmdlet 启动它但它仍然不起作用,请确保您的循环或进程不会太快完成。对于非常快的任务,可能不会出现进度条。

3.进度条减慢脚本速度

如果进度条减慢了脚本的速度,请尝试降低更新频率或仅在必要时更新。如果性能比视觉反馈更重要,请考虑删除进度条或允许用户禁用它。请记住,虽然进度条非常适合提供反馈,但它们会降低脚本的整体性能,特别是如果您在快速循环中过于频繁地更新它们的话。

以下是 Write-Progress cmdlet 的官方 Microsoft 文档参考!

结论和最终想法

在 PowerShell 中使用进度条非常有用,尤其是在运行长脚本时。它提供实时反馈、时间估算和改进的用户体验。通过将进度条合并到 PowerShell 脚本中,您可以为用户提供实时更新、增强信心并改善整体用户体验。在 PowerShell 中使用进度栏时,请务必遵循最佳实践并解决常见问题。进度条提供有关脚本执行时间的宝贵反馈。立即开始使用它们来改进您的所有 PowerShell 脚本!快乐的脚本编写!

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯