Nota
El acceso a esta página requiere autorización. Puede intentar iniciar sesión o cambiar directorios.
El acceso a esta página requiere autorización. Puede intentar cambiar los directorios.
Escritura de scripts
Al pasar de escribir líneas de comando de PowerShell a escribir scripts, puede parecer más complicado de lo que realmente es. Un script no es más que los mismos comandos o similares que se ejecutan de forma interactiva en la consola de PowerShell, excepto que los guarda como un archivo .ps1
. Hay algunas construcciones de scripting que puede usar, como un bucle foreach
en lugar del cmdlet ForEach-Object
. Las diferencias pueden resultar confusas para principiantes al considerar que foreach
es una palabra clave de lenguaje y un alias para el cmdlet ForEach-Object
.
Bucle
Uno de los mejores aspectos de PowerShell es su escalabilidad. Una vez que aprenda a realizar una tarea para un solo elemento, aplicar la misma acción a cientos de elementos es casi tan sencillo. Recorra los elementos mediante uno de los distintos tipos de bucles en PowerShell.
ForEach-Object
ForEach-Object
es un cmdlet para iterar los elementos de una canalización como, por ejemplo, con las secuencias de una frase de PowerShell.
ForEach-Object
transmite los objetos a través de la canalización.
Aunque el parámetro del módulo de Get-Command
acepta varios valores de cadena, solo los acepta por entrada de canalización por nombre de propiedad. En el siguiente escenario, si desea pasar dos valores de cadena a Get-Command
para su uso con el parámetro del Módulo, debe usar el cmdlet ForEach-Object
.
'ActiveDirectory', 'SQLServer' |
ForEach-Object {Get-Command -Module $_} |
Group-Object -Property ModuleName -NoElement |
Sort-Object -Property Count -Descending
Count Name
----- ----
147 ActiveDirectory
82 SqlServer
En el ejemplo anterior, $_
es el objeto actual. A partir de la versión 3.0 de PowerShell, se puede usar $PSItem
en lugar de $_
. La mayoría de los usuarios experimentados de PowerShell prefieren usar $_
, ya que es compatible con versiones anteriores y requiere menos que teclear.
Al usar la palabra clave foreach
, debe almacenar los elementos en la memoria antes de recorrerlos en iteración, lo que podría ser difícil si no sabe con cuántos elementos está trabajando.
$ComputerName = 'DC01', 'WEB01'
foreach ($Computer in $ComputerName) {
Get-ADComputer -Identity $Computer
}
DistinguishedName : CN=DC01,OU=Domain Controllers,DC=mikefrobbins,DC=com
DNSHostName : dc01.mikefrobbins.com
Enabled : True
Name : DC01
ObjectClass : computer
ObjectGUID : c38da20c-a484-469d-ba4c-bab3fb71ae8e
SamAccountName : DC01$
SID : S-1-5-21-2989741381-570885089-3319121794-1001
UserPrincipalName :
DistinguishedName : CN=WEB01,CN=Computers,DC=mikefrobbins,DC=com
DNSHostName : web01.mikefrobbins.com
Enabled : True
Name : WEB01
ObjectClass : computer
ObjectGUID : 33aa530e-1e31-40d8-8c78-76a18b673c33
SamAccountName : WEB01$
SID : S-1-5-21-2989741381-570885089-3319121794-1107
UserPrincipalName :
Muchas veces se necesita un bucle como foreach
o ForEach-Object
. De lo contrario, recibirá un mensaje de error.
Get-ADComputer -Identity 'DC01', 'WEB01'
Get-ADComputer : Cannot convert 'System.Object[]' to the type
'Microsoft.ActiveDirectory.Management.ADComputer' required by parameter
'Identity'. Specified method is not supported.
At line:1 char:26
+ Get-ADComputer -Identity 'DC01', 'WEB01'
+ ~~~~~~~~~~~~~~~
+ CategoryInfo : InvalidArgument: (:) [Get-ADComputer], Parame
terBindingException
+ FullyQualifiedErrorId : CannotConvertArgument,Microsoft.ActiveDirecto
ry.Management.Commands.GetADComputer
Otras veces, puede obtener los mismos resultados al eliminar el bucle. Consulte la ayuda del cmdlet para comprender las opciones.
'DC01', 'WEB01' | Get-ADComputer
DistinguishedName : CN=DC01,OU=Domain Controllers,DC=mikefrobbins,DC=com
DNSHostName : dc01.mikefrobbins.com
Enabled : True
Name : DC01
ObjectClass : computer
ObjectGUID : c38da20c-a484-469d-ba4c-bab3fb71ae8e
SamAccountName : DC01$
SID : S-1-5-21-2989741381-570885089-3319121794-1001
UserPrincipalName :
DistinguishedName : CN=WEB01,CN=Computers,DC=mikefrobbins,DC=com
DNSHostName : web01.mikefrobbins.com
Enabled : True
Name : WEB01
ObjectClass : computer
ObjectGUID : 33aa530e-1e31-40d8-8c78-76a18b673c33
SamAccountName : WEB01$
SID : S-1-5-21-2989741381-570885089-3319121794-1107
UserPrincipalName :
Como puede ver en los ejemplos anteriores, el parámetro Identity para Get-ADComputer
solo acepta un valor único cuando se proporciona a través de la entrada de parámetros. Sin embargo, mediante la canalización, puede enviar varios valores al comando porque los valores se procesan de uno en uno.
Para
Un bucle for
recorre en iteración mientras se cumple una condición especificada. No uso el bucle for
a menudo, pero tiene usos.
for ($i = 1; $i -lt 5; $i++) {
Write-Output "Sleeping for $i seconds"
Start-Sleep -Seconds $i
}
Sleeping for 1 seconds
Sleeping for 2 seconds
Sleeping for 3 seconds
Sleeping for 4 seconds
En el ejemplo anterior, el bucle recorre en iteración cuatro veces empezando por el número uno y continuando siempre que la variable de contador $i
sea inferior a 5. Se duerme durante un total de 10 segundos.
Qué hacer
Hay dos bucles do
diferentes en PowerShell: do until
y do while
.
do until
se ejecuta hasta que la condición especificada es falsa.
El ejemplo siguiente es un juego de números que continúa hasta que el valor que adivina es igual al mismo número que el cmdlet Get-Random
generado.
$number = Get-Random -Minimum 1 -Maximum 10
do {
$guess = Read-Host -Prompt "What's your guess?"
if ($guess -lt $number) {
Write-Output 'Too low!'
} elseif ($guess -gt $number) {
Write-Output 'Too high!'
}
}
until ($guess -eq $number)
What's your guess?: 1
Too low!
What's your guess?: 2
Too low!
What's your guess?: 3
Do While
es lo contrario. Se ejecuta siempre que la condición especificada se evalúe como true.
$number = Get-Random -Minimum 1 -Maximum 10
do {
$guess = Read-Host -Prompt "What's your guess?"
if ($guess -lt $number) {
Write-Output 'Too low!'
} elseif ($guess -gt $number) {
Write-Output 'Too high!'
}
}
while ($guess -ne $number)
What's your guess?: 1
Too low!
What's your guess?: 2
Too low!
What's your guess?: 3
Too low!
What's your guess?: 4
Se logran los mismos resultados con un bucle Do While
invirtiendo la condición de prueba en no es igual a.
Los bucles do
se ejecutan siempre al menos una vez porque la condición se evalúa al final del bucle.
Mientras
Al igual que el bucle do while
, se ejecuta un bucle while
siempre que la condición especificada sea verdadera. Sin embargo, la diferencia es que un bucle while
evalúa la condición en la parte superior del bucle antes de que se ejecute cualquier código. Por lo tanto, no se ejecuta si la condición se evalúa como false.
En el ejemplo siguiente se calcula el día de Acción de Gracias en los Estados Unidos. Siempre está el cuarto jueves de noviembre. El bucle comienza con el día 22 de noviembre y agrega un día, mientras que el día de la semana no es igual al jueves. Si el 22 es un jueves, el bucle no se ejecuta en absoluto.
$date = Get-Date -Date 'November 22'
while ($date.DayOfWeek -ne 'Thursday') {
$date = $date.AddDays(1)
}
Write-Output $date
Thursday, November 23, 2017 12:00:00 AM
break, continue y return
La palabra clave break
está diseñada para salir de un bucle y a menudo se usa con la instrucción switch
. En el ejemplo siguiente, break
hace que el bucle finalice después de la primera iteración.
for ($i = 1; $i -lt 5; $i++) {
Write-Output "Sleeping for $i seconds"
Start-Sleep -Seconds $i
break
}
Sleeping for 1 seconds
La palabra clave continue
está diseñada para ir directamente a la siguiente iteración de un bucle.
En el ejemplo siguiente se generan los números 1, 2, 4 y 5. Omite el número 3 y continúa con la siguiente iteración del bucle. De forma similar a break
, continue
sale del bucle, salvo que solo lo hace en la iteración actual. La ejecución continúa con la siguiente iteración en lugar de interrumpir el bucle por completo y detenerlo.
while ($i -lt 5) {
$i += 1
if ($i -eq 3) {
continue
}
Write-Output $i
}
1
2
4
5
La palabra clave return
está diseñada para salir del ámbito existente.
Observe en el ejemplo siguiente que return
genera el primer resultado y, a continuación, sale del bucle.
$number = 1..10
foreach ($n in $number) {
if ($n -ge 4) {
return $n
}
}
4
Se puede encontrar una explicación más detallada de la declaración de resultado en uno de mis artículos de blog: La palabra clave return de PowerShell.
Resumen
En este capítulo, ha obtenido información sobre los distintos tipos de bucles que existen en PowerShell.
Revisión
- ¿Cuál es la diferencia entre el cmdlet
ForEach-Object
y la instrucciónforeach
? - ¿Cuál es la principal ventaja de usar un bucle
while
en lugar de un bucledo while
odo until
? - ¿Cómo difieren las instrucciones
break
ycontinue
?