Variables y tipos de datos
Las variables
1. Creación y asignación
La creación de variables en PowerShell es realmente una cosa fácil. A diferencia de los verdaderos lenguajes de programación, PowerShell no es un lenguaje fuertemente tipado, es decir que las variables no necesitan ser declaradas ni inicializadas antes de ser utilizadas. Así basta con asignar con el operador = un valor a una variable y PowerShell se encarga del resto, a saber crearla en memoria y determinar su tipo. Este es el funcionamiento por defecto, pero veremos a continuación que podemos hacer que PowerShell sea mucho menos permisivo.
Ejemplo
$variable = valor de un tipo cualquiera
-
Tecleando $var1 = 12 en la consola PowerShell, creamos una variable con el nombre var1 y le asignamos el valor 12. PowerShell determinará a continuación que se trata de un valor entero y le asignará automáticamente el tipo int (integer).
-
Tecleando $var2 = ’A’ realizamos la misma operación que antes exceptuando esta vez que var2 será de string (cadena) aunque esta no contenga más que un carácter.
Ejemplo
${www.powershell-scripting.com} = 1
Esto asignará el valor 1 a la variable entre las llaves.
2. Determinar...
Las constantes
Las constantes son variables cuyo contenido no debe (y/o no puede) cambiar a lo largo del tiempo.
Aunque es posible contentarse con una simple asignación de la variable, esta técnica no impide una eventual modificación del contenido de la variable. Por ello es preferible utilizar el comando New-Variable así como el parámetro -Option Constant, como en el siguiente ejemplo:
PS > New-Variable -Name PI -Value 3.14 -Option Constant
De esta manera, estamos protegidos del riesgo de modificación del contenido. Para convencernos de ello, probemos a ver qué pasa si asignamos un nuevo valor:
PS > $PI = 4
Cannot overwrite variable PI because it is read-only or constant.
At line:1 char:1
+ $PI=4
+ ~~~~~
+ CategoryInfo : WriteError: (PI:String) [],
SessionStateUnauthorized...
+ FullyQualifiedErrorId : VariableNotWritable
El parámetro -Option también acepta otros valores, como: None, ReadOnly, Constant, Private, AllScope, Unspecified. Estos pueden ser de gran utilidad para especificar la visibilidad de una variable a través de los distintos alcances (ámbitos) de PowerShell.
Tipos de datos
Aunque en general, en los scripts de cada día, nos contentemos con los tipos de datos más básicos que existen, es sin embargo posible utilizar un gran número de ellos. En efecto, como PowerShell obtiene toda su potencia del framework .NET, todos los tipos .NET pueden potencialmente ser accedidos y utilizados.
Por el momento, nos contentaremos con describir los tipos comúnmente utilizados.
Tipo |
Descripción |
Int, Int32, Int64 |
Representa enteros en un rango comprendido entre -2 147 483 648 y 2 147 483 647 incluidos. El tipo de dato int se almacena como un entero de cuatro bytes (32 bits). |
Double |
Representa números con coma tan grandes como 10308 (positivos o negativos), con una precisión de 15 cifras y tan pequeños como 10-323 (64 bits). |
Char |
Representa cualquiera de los 65 536 caracteres Unicode contenidos en dos bytes (16 bits). |
String |
Representa una cadena bajo la forma de vector de caracteres Unicode. |
Boolean |
Representa un valor booleano (true o false). |
Array |
Representa un array que contiene múltiples valores. Un array puede contener datos de diferentes tipos. |
Object, PSObject, PSCustomObject |
Representa un objeto generalmente personalizado. |
Asignación manual de tipos y tipado
Que los incondicionales del « tipado fuerte » estén tranquilos. Existe una alternativa al tipado automático para ser dueño del tipado de las variables. Para ello, debe definir el tipo deseado entre corchetes y poner este último delante de la variable como en el siguiente ejemplo:
PS > [int]$var = 12
Tecleando esto, tiene asegurado que la variable $var será de tipo entero. Pero, ¡no hay ninguna diferencia entre $var = 12 e [int]$var = 12, se preguntará! Cierto es que por el momento el interés es mínimo pero cuando sean grandes «powershellers» y sus scripts empiecen a tomar amplitud, el hecho de declarar sus variables con un tipo determinado hará que su trabajo sea mucho más comprensible para los demás y sobre todo impedirá que un valor de un tipo diferente le sea asignado por error.
Ejemplo
PS > [int]$numero = Read-Host 'Indique un número'
Indique un número: cien
Cannot convert value "cien" to type "System.Int32".
Error: "Input string was not in a correct format."
En este ejemplo, el texto cien no ha sido reconocido como un número entero. El error es por lo tanto detectado por el intérprete de comandos. Si no hubiésemos indicado el tipo [int] delante de la variable $numero, el texto hubiese sido aceptado...
Hacer obligatoria la declaración e inicialización de variables
Una buena práctica sería obligar a declarar todas nuestras variables en un script, una función o un bloque de script. En efecto, ¿a quién no le ha ocurrido buscar un bug en un programa durante horas por culpa de un simple error tipográfico en el nombre de alguna variable?
Aunque este no es el comportamiento por defecto, es posible imponer este modo de funcionamiento gracias al uso del comando Set-StrictMode.
A continuación vemos la sintaxis de este comando:
PS > Get-Command Set-StrictMode -Syntax
Set-StrictMode -Version <Version> [<CommonParameters>]
Set-StrictMode -Off [<CommonParameters>]
El parámetro -Version permite los siguientes valores:
-
1.0:
-
En este modo, cualquier referencia a una variable no inicializada provocará un error (salvo dentro de una cadena de caracteres).
-
2.0:
-
Todo referencia a una variable no inicializada provocará un error (también en el interior de una cadena).
-
Queda prohibida cualquier referencia a una propiedad de un objeto que no exista.
-
Quedan prohibidas las llamadas a funciones que usen la misma sintaxis (firma) que la llamada a métodos.
-
Queda prohibido el uso de variables sin nombres (${}).
-
Latest:
-
Modo más estricto. Este valor permite asegurar que se aplican las restricciones más conservadoras de la última versión...
Variables predefinidas
1. Variables automáticas
PowerShell dispone de dos tipos de variables predefinidas. Las variables automáticas que almacenan información de procesamiento, y las variables de configuración que sirven para definir el comportamiento de PowerShell.
Empecemos por las variables automáticas:
Variable |
Descripción |
$$ |
Variable (de uso poco frecuente) que contiene el último valor del comando escrito en la consola. |
$? |
Variable que contiene true si la última operación ha tenido éxito o false en el caso contrario. |
$^ |
Variable (de uso poco frecuente) que contiene la primera parte de la última línea recibida por el entorno (es decir la primera palabra del último comando tecleado en la consola). |
$_ |
Variable que contiene el objeto actual transmitido mediante una pipe |. |
$AllNodes |
Variable utilizada por DSC. Contiene los datos de configuración que se pasan a través del parámetro -ConfigurationData. |
$Args |
Variable que contiene el array de argumentos pasados a una función o a un script. |
$ConsoleFileName |
Variable que contiene la ruta de acceso al archivo de consola (.psc1) que ha sido utilizado en la última sesión. |
$Error |
Variable de tipo array que contiene todos los errores encontrados desde el inicio de la sesión PowerShell actual (consulte el capítulo Gestión de errores y depuración). |
$Event |
Variable que contiene el evento actual tratado en el bloque de script de un comando de grabación de evento, típicamente como Register-ObjectEvent. |
$EventArgs |
Variable que contiene los argumentos en relación con $Event. Como esta última, $EventArgs se utiliza únicamente en el bloque de scripts de un comando de grabación de evento. |
$EventSubscriber |
Variable que contiene el subscriptor utilizado por $Event. Como esta última, $EventSubscriber se utiliza únicamente en el bloque de scripts de un comando de grabación de evento. |
$ExecutionContext |
Variable que contiene un objeto EngineIntrinsics que representa el contexto de ejecución del símbolo del sistema Windows PowerShell. |
$False |
Variable que contiene el valor false. Esta variable es una constante, y por consiguiente no es posible modificarla. |
$Foreach |
Variable que hace referencia al iterador de un bucle Foreach. |
$Home |
Variable que contiene la ruta (path) de la carpeta home... |
Ámbito de las variables
El ámbito (scope en inglés) determina la visibilidad de las variables (o de las funciones). En esta sección solo mencionaremos brevemente el tema ya que es muy amplio y puede rápidamente volverse complejo. Para obtener explicaciones más detalladas, le recomendamos consultar el tema de la ayuda About_Scopes.
La noción de ámbito es no obstante importante, ya que garantiza una independencia de variables, o por lo menos un modo de funcionamiento que es útil conocer para evitar probables interferencias y otros efectos no deseados.
Imagine por un momento que ejecuta un script y que una vez el script finalizado desea verificar un valor tecleando su nombre en la consola. ¡Uy! No es posible (por defecto, en la consola clásica), ya que la variable no está disponible; dicho esto es simplemente debido al ámbito de la variable.
PowerShell utiliza la noción de ámbito padre y de ámbito hijo. Un ámbito hijo es un ámbito creado en el interior de un ámbito padre. Es decir que cada vez que ejecutemos una función, un script o un bloque de instrucciones, se crea un nuevo ámbito. Y salvo que especifique lo contrario, PowerShell define que se puede leer una variable en su propio ámbito así como en los ámbitos hijos. Pero solo puede ser modificada en el ámbito donde se creó. Además los ámbitos padres no pueden ni leer ni modificar las variables definidas en sus ámbitos hijos.
El siguiente esquema ilustra la accesibilidad de una variable en un ámbito hijo.
Supongamos que una variable $var se inicializa...
Cuantificadores de bytes
Una de las características de PowerShell es su capacidad de utilizar cuantificadores de bytes. Estos últimos permiten manipular múltiplos de bytes sin tener que efectuar ninguna operación particular. Los cuantificadores definidos son los siguientes:
Cuantificador |
Valor |
Descripción |
Ejemplo de uso |
KB |
1024 |
Kilobytes |
2 KB --> 2048 |
MB |
1024² |
Megabytes |
1 MB --> 1048576, 2 MB --> 2097152 |
GB |
10243 |
Gigabytes |
1 GB --> 1073741824, 10 GB --> 10737418240 |
TB |
10244 |
Terabytes |
1 TB --> 1099511627776 |
PB |
10245 |
Petabytes |
1 PB --> 1125899906842624 |
Históricamente, los desarrolladores de scripts siempre hemos resuelto estas dificultades realizando operaciones matemáticas: dividíamos nuestro número de bytes por 1024, lo que nos daba kilobytes. Dividíamos después por 1024 para obtener megabytes, etc. Pero hay que reconocer que es mucho más práctico cuando el intérprete de comandos gestiona esto nativamente.
El uso de cuantificadores está claramente ligado a los cálculos de tamaños, y eso ocurre a menudo cuando trabajamos con la capacidad de un disco o de la memoria, del tamaño de los archivos o de las carpetas, etc.
Tomemos por ejemplo la consulta CIM/WMI siguiente que devuelve la capacidad de memoria de un equipo:
PS > $System = Get-CimInstance -ClassName Win32_ComputerSystem ...