Añadir una barra de progreso en PowerShell : guía paso a paso
Table of Contents
I. Introducción
En este tutorial, aprenderemos a añadir una barra de progreso a un script PowerShell. La barra de progreso le permitirá seguir el progreso de ejecución de un script PowerShell, lo que resulta muy útil cuando el script tiene que procesar un gran número de elementos. Casi podríamos decir que mejorará la experiencia del usuario al mostrar información sobre el progreso.
II. El cmdlet Write-Progress en PowerShell
PowerShell incluye el cmdlet"Write-Progress" para crear barras de progreso personalizadas en los scripts. Para utilizar este cmdlet, configuraremos varios de sus parámetros:
- -PorcentComplete : especifica el porcentaje de finalización de la tarea, lo que implica realizar un cálculo para devolver información precisa.
- -Actividad : muestra la tarea actual, con información más detallada.
- -Estado : indica la tarea actual.
Por lo tanto, tenemos dos parámetros para gestionar la información mostrada en pantalla, así como un parámetro para calcular el porcentaje de progreso. Este último parámetro es importante, ya que afecta directamente a la barra de progreso visible en la pantalla.
Existen otros parámetros para el cmdlet"Write-Progress". Además de este tutorial, puede consultar la página de ayuda en el sitio web de Microsoft:
III. Creación de la primera barra de progreso
Para familiarizarnos con el principio de la barra de progreso, empezaremos con un ejemplo muy básico para poner en práctica el cmdlet "Write-Progress".
En este ejemplo, tenemos un bucle "for" que se ejecuta 10 veces, con una pausa de 1 segundo entre cada iteración (esto simula una tarea). Esto nos permite temporizar y ver fácilmente el progreso del procesamiento. El cálculo "($i/10*100)" se utiliza para calcular un porcentaje consistente.
for ($i = 1 ; $i -le 10 ; $i++) {
Write-Progress -Activity "Treatment in progress" -Status "$($i/10*100)% done" -PercentComplete ($i/10*100)
Start-Sleep -Seconds 1
}
Este trozo de código da el siguiente resultado (haz clic en la imagen para ver la animación):

Podemos ver que existe una coherencia real entre el porcentaje indicado y el progreso de la tarea. Esta es la principal dificultad a la hora de crear una barra de progreso.
IV. Seguimiento de una tarea con Write-Progress
Podemos utilizar una barra de progreso para seguir el progreso de una tarea, sin indicar un porcentaje de progreso (aunque éste se calculará por coherencia). En su lugar, indicaremos el número total de elementos por procesar y el número de elementos ya procesados.
El ejemplo siguiente se utiliza para consultar una lista de identificadores definidos en una matriz (variable "ListeDesIdentifiants") mediante un bucle "Foreach". Podríamos utilizar esta lista para crear cuentas de usuario, etc. Lo importante aquí es ver la mecánica de la barra de progreso.
Aquí está el código completo:
# List of logins
$ListeDesIdentifiants = @("florian.burnel","guy.mauve","gerard.mensoif","jeanmichel.diledefrance")
# Total number of logins to process
$ListeDesIdentifiantsCount = $ListeDesIdentifiants.Count
# Processed logins counter
$NbIdentifiantsTraites = 1
# Process each login with a loop
foreach($Identifiant in $ListeDesIdentifiants) {
Write-Progress -PercentComplete ($NbIdentifiantsTraites/$ListeDesIdentifiantsCount*100) -Status "Creating current accounts" -Activity "Processed logins : $NbIdentifiantsTraites of $ListeDesIdentifiantsCount"
# Actions for each account
# New-LocalUser...
# New-ADUser...
Start-Sleep -Seconds 1
# Increment the number of accounts processed
$NbIdentifiantsTraites++
}
Manejamos dos valores importantes para calcular la progresión:
- El número total de elementos a procesar, almacenado en la variable "ListIdentifiersCount" y recuperado mediante la propiedad "Count".
- El número de elementos ya procesados, para controlar el progreso. Este valor se almacena en la variable "NbIdentifiersProcessed". Se incrementa en 1 cada vez que se itera el bucle.
Este es el resultado (haz clic en la imagen para ver la animación):

Por último, he aquí otro ejemplo en el que seguimos la descarga de varios archivos utilizando la barra de progreso para mostrar el nombre del archivo que se está descargando. Aquí, se utiliza un bucle "For" para navegar por la lista de archivos, pero podríamos utilizar un bucle "Foreach".
# List of files to download
$ListeDesFichiers = @("Archive1.zip", "Archive2.zip", "Document1.zip")
for ($i = 0 ; $i -lt $ListeDesFichiers.Length ; $i++) {
$Fichier = $ListeDesFichiers[$i]
Write-Progress -Activity "Files download" -Status "Download $Fichier " -PercentComplete (($i + 1) / $ListeDesFichiers.Length * 100)
# Download action (simulated here)
# Invoke-WebRequest...
Start-Sleep -Seconds 1
}
Write-Host "File download complete!"
He aquí el resultado en imágenes (haga clic en la imagen para ver la animación):

V. Gestión del progreso con hitos fijos
El cálculo del porcentaje no es obligatorio si simplemente desea seguir el progreso de sus scripts basándose en hitos definidos estáticamente. Si tiene un script que realiza acciones en 4 etapas principales y simplemente desea saber en qué etapa se encuentra, puede utilizar el cmdlet "Write-Progress".
Write-Progress -Activity "Task n°1 : <description>" -Status "Task 1 on 4" -PercentComplete 25
# Operation to perform... (pause for 1 second)
Start-Sleep -Seconds 1
Write-Progress -Activity "Task n°2 : <description>" -Status "Task 2 on 4" -PercentComplete 50
# Operation to perform... (pause for 1 second)
Start-Sleep -Seconds 1
Write-Progress -Activity "Task n°3 : <description>" -Status "Task 3 on 4" -PercentComplete 75
# Operation to perform... (pause for 1 second)
Start-Sleep -Seconds 1
Write-Progress -Activity "Task n°4 : <description>" -Status "Task 4 on 4" -PercentComplete 100
# Operation to perform... (pause for 1 second)
Start-Sleep -Seconds 1
Obtenemos el siguiente resultado (haga clic en la imagen para ver la animación):

VI. Gestión de una interrupción en curso
Podemos personalizar los mensajes mostrados modificando el valor de los parámetros "-Activity" y "-Status" en el cmdlet "Write-Progress". Esto puede ser útil para gestionar una interrupción en el procesamiento y notificárselo al usuario.
He aquí un ejemplo en el que simulamos una interrupción de la tarea al 50%, antes de reanudarla 2 segundos más tarde. Así, en la práctica, la barra de progreso mostrará un mensaje de interrupción antes de reanudar la tarea e informar al usuario. Esta técnica puede ser útil para informar al usuario de pausas o esperas durante el procesamiento.
for ($i = 1; $i -le 100; $i++) {
if ($i -eq 50) {
Write-Progress -Activity "Interruption" -Status "50% of job interrupted" -PercentComplete $i
Start-Sleep -Seconds 2
Write-Progress -Activity "Resume" -Status "Resuming the task" -PercentComplete $i
} else {
Write-Progress -Activity "Treatment in progress" -Status "$i% done" -PercentComplete $i
}
Start-Sleep -Milliseconds 50
}
VII. Conclusión
Acabamos de ver cómo utilizar el cmdlet "Write-Progress" para crear barras de progreso con PowerShell. Hay varios escenarios posibles, dependiendo de sus necesidades y escenarios de uso. Pero una barra de progreso es siempre un buen toque al ejecutar un script PowerShell, así como proporcionar un seguimiento preciso (y valioso).
Es posible ir más allá declarando varias barras de progreso para gestionar el progreso global y el progreso de una subtarea. Esto significa utilizar "Write-Progress" dos veces y jugar con el parámetro "-PercentComplete" para calcular el porcentaje de la subtarea. También podríamos utilizar el parámetro "-Segundos Restantes" para especificar el número de segundos que faltan para el final del procesamiento, pero también en este caso esto implica cálculos (en particular, basándose en el tiempo medio de ejecución de los elementos anteriores para obtener una estimación).