Powershell
Para manejar PowerShell de manera básica, aquí tienes cómo se aplican los conceptos fundamentales que mencionamos antes:
- Variables y Tipos de Datos:
- Variables: En PowerShell, puedes definir variables usando el símbolo
$
. Ejemplo:$nombre = "Juan"
. - Tipos de Datos: PowerShell maneja varios tipos de datos como cadenas (
"texto"
), enteros (123
), booleanos ($true
o$false
), y más.
- Variables: En PowerShell, puedes definir variables usando el símbolo
- Operadores:
- Aritméticos:
+
,-
,*
,/
. - Comparación:
-eq
(igual),-ne
(no igual),-gt
(mayor que),-lt
(menor que). - Lógicos:
-and
,-or
,-not
.
- Aritméticos:
- Estructuras de Control:
- Condicionales:
if ($condicion) { # código } else { # código }
. - Bucles:
for ($i = 0; $i -lt 10; $i++) { # código }
ywhile ($condicion) { # código }
.
- Condicionales:
- Funciones:
- Definición de funciones:
function NombreFuncion { param($param1, $param2) # código }
. - Ejemplo:
function Saludar { param($nombre) Write-Output "Hola, $nombre" }
.
- Definición de funciones:
- Estructuras de Datos:
- Arreglos:
$array = @(1, 2, 3)
. - HashTables:
$hash = @{clave1="valor1"; clave2="valor2"}
.
- Arreglos:
- Clases y Objetos:
- PowerShell permite la creación de clases y objetos desde la versión 5.0. Ejemplo:
class Persona { [string]$Nombre; [int]$Edad }
.
- PowerShell permite la creación de clases y objetos desde la versión 5.0. Ejemplo:
- Módulos y Librerías:
- Importar módulos:
Import-Module -Name NombreModulo
. - Ejemplo:
Import-Module -Name ActiveDirectory
.
- Importar módulos:
- Manejo de Archivos:
- Leer archivos:
Get-Content -Path "ruta\archivo.txt"
. - Escribir archivos:
Set-Content -Path "ruta\archivo.txt" -Value "Contenido"
.
- Leer archivos:
- Depuración y Manejo de Errores:
- Manejo de errores:
try { # código } catch { # manejo de error }
. - Ejemplo:
try { Get-Item "C:\archivo.txt" } catch { Write-Output "Archivo no encontrado" }
.
- Manejo de errores:
- Documentación y Comentarios:
- Comentarios de una línea:
# Esto es un comentario
. - Comentarios de múltiples líneas:
<# Esto es un comentario de múltiples líneas #>
.
- Comentarios de una línea:
Para manejarte de manera básica en PowerShell, es útil conocer algunos cmdlets fundamentales. Aquí tienes una lista de los principales cmdlets que deberías aprender:
- Get-Help: Proporciona información sobre otros cmdlets y cómo usarlos.
Get-Help Get-Process
- Get-Command: Muestra una lista de todos los cmdlets disponibles.
Get-Command
- Get-Process: Muestra los procesos en ejecución en el sistema.
Get-Process
- Stop-Process: Detiene un proceso en ejecución.
Stop-Process -Name "notepad"
- Get-Service: Muestra los servicios en el sistema.
Get-Service
- Start-Service y Stop-Service: Inicia y detiene servicios respectivamente.
Start-Service -Name "wuauserv" Stop-Service -Name "wuauserv"
- Set-ExecutionPolicy: Cambia la política de ejecución de scripts en PowerShell.
Set-ExecutionPolicy RemoteSigned
- Get-Content: Lee el contenido de un archivo.
Get-Content -Path "C:\ruta\archivo.txt"
- Set-Content: Escribe contenido en un archivo.
Set-Content -Path "C:\ruta\archivo.txt" -Value "Nuevo contenido"
- New-Item: Crea un nuevo archivo o directorio.
New-Item -Path "C:\ruta\nuevoarchivo.txt" -ItemType "file"
- Remove-Item: Elimina archivos o directorios.
Remove-Item -Path "C:\ruta\archivo.txt"
- Get-ChildItem: Lista los archivos y directorios en una ubicación específica.
Get-ChildItem -Path "C:\ruta"
- Copy-Item: Copia archivos o directorios.
Copy-Item -Path "C:\ruta\archivo.txt" -Destination "C:\nueva_ruta\archivo.txt"
- Move-Item: Mueve archivos o directorios.
Move-Item -Path "C:\ruta\archivo.txt" -Destination "C:\nueva_ruta\archivo.txt"
- Rename-Item: Renombra archivos o directorios.
Rename-Item -Path "C:\ruta\archivo.txt" -NewName "nuevo_nombre.txt"
Más Cmdlets Útiles
- Get-EventLog: Obtiene eventos de los registros de eventos.
Get-EventLog -LogName Application
- Get-WmiObject: Obtiene información del Instrumental de Administración de Windows (WMI).
Get-WmiObject -Class Win32_OperatingSystem
- Invoke-Command: Ejecuta comandos en equipos locales o remotos.
Invoke-Command -ComputerName "Servidor01" -ScriptBlock { Get-Process }
- Get-ADUser: Obtiene información de usuarios en Active Directory.
Get-ADUser -Filter *
- Export-Csv: Exporta objetos a un archivo CSV.
Get-Process | Export-Csv -Path "procesos.csv"
- Import-Csv: Importa datos de un archivo CSV.
Import-Csv -Path "datos.csv"
- Send-MailMessage: Envía correos electrónicos.
Send-MailMessage -From "tu@correo.com" -To "destino@correo.com" -Subject "Asunto" -Body "Mensaje" -SmtpServer "smtp.servidor.com"
- Test-Connection: Realiza una prueba de conexión (ping).
Test-Connection -ComputerName "google.com"
- Get-History: Muestra el historial de comandos ejecutados.
Get-History
- Clear-History: Limpia el historial de comandos.
Clear-History
Uso de Tuberías (Pipelines)
Las tuberías en PowerShell permiten pasar la salida de un cmdlet como entrada a otro cmdlet. Esto se hace utilizando el operador |
. Aquí tienes algunos ejemplos:
- Filtrar procesos y ordenarlos:
Get-Process | Where-Object { $_.CPU -gt 100 } | Sort-Object -Property CPU
- Obtener servicios y detener los que están en ejecución:
Get-Service | Where-Object { $_.Status -eq 'Running' } | Stop-Service
- Listar archivos grandes en un directorio y mostrarlos en una tabla:
Get-ChildItem -Path "C:\ruta" | Where-Object { $_.Length -gt 100MB } | Format-Table -Property Name, Length
- Exportar usuarios de Active Directory a un archivo CSV:
Get-ADUser -Filter * | Select-Object Name, EmailAddress | Export-Csv -Path "usuarios.csv"
Variables:
las variables son fundamentales para almacenar y manipular datos. Aquí tienes un resumen de lo más importante sobre las variables en PowerShell:
1. Creación y Uso de Variables
- Declaración: No necesitas declarar una variable antes de usarla. Simplemente asigna un valor usando el signo
$
.$miVariable = "Hola, mundo"
- Tipos de Datos: Las variables pueden almacenar cualquier tipo de dato, como cadenas, enteros, arrays, objetos, etc.
$numero = 42 $lista = @(1, 2, 3, 4, 5)
2. Tipos de Variables
- Variables de Usuario: Son creadas y mantenidas por el usuario. Existen solo mientras la sesión de PowerShell está abierta, a menos que se guarden en el perfil de PowerShell1.
- Variables Automáticas: Son creadas y gestionadas por PowerShell para almacenar el estado del entorno. Ejemplo:
$PSHOME
almacena la ruta de instalación de PowerShell2. - Variables de Preferencia: Almacenan preferencias del usuario para PowerShell. Ejemplo:
$MaximumHistoryCount
determina el número máximo de entradas en el historial de la sesión2.
3. Alcance de las Variables
- Global: Disponible en toda la sesión de PowerShell.
- Local: Disponible solo en el bloque de código actual.
- Script: Disponible en todo el script donde se define.
- Private: Disponible solo en el bloque de código donde se define.
4. Comandos Útiles
- Asignar Valor:
$miVariable = "Nuevo valor"
- Mostrar Valor:
Write-Output $miVariable
- Listar Variables:
Get-Variable
5. Ejemplos Prácticos
- Almacenar Resultados de Comandos:
$procesos = Get-Process $fechaHoy = (Get-Date).DateTime
El alcance de las variables en PowerShell determina dónde y cómo se pueden acceder y modificar las variables. Aquí tienes una explicación más detallada sobre los diferentes tipos de alcance y cómo se pueden modificar:
Tipos de Alcance
- Global: Las variables definidas en el alcance global están disponibles en toda la sesión de PowerShell.
$Global:miVariableGlobal = "Valor Global"
- Local: Las variables locales están disponibles solo en el bloque de código actual, como una función o un script.
function MiFuncion { $miVariableLocal = "Valor Local" Write-Output $miVariableLocal }
- Script: Las variables de script están disponibles en todo el script donde se definen.
$Script:miVariableScript = "Valor de Script"
- Private: Las variables privadas están disponibles solo en el bloque de código donde se definen y no son accesibles desde otros bloques.
$Private:miVariablePrivada = "Valor Privado"
Modificación del Alcance
Para modificar el alcance de una variable, puedes usar los modificadores de alcance (Global
, Local
, Script
, Private
) al definir o acceder a la variable. Aquí tienes algunos ejemplos:
- Crear una variable en el alcance global:
$Global:miVariable = "Valor Global"
- Acceder a una variable de script desde una función:
$Script:miVariable = "Valor de Script" function MostrarVariable { Write-Output $Script:miVariable } MostrarVariable
- Crear una variable privada dentro de una función:
function MiFuncion { $Private:miVariablePrivada = "Valor Privado" Write-Output $Private:miVariablePrivada } MiFuncion
Reglas de Alcance
- Herencia de Alcance: Un ámbito hijo (como una función o un script llamado) hereda las variables del ámbito padre, a menos que se declaren como privadas.
- Modificación de Variables en Diferentes Ámbitos: Puedes modificar una variable en un ámbito específico usando el modificador de alcance adecuado.
$Global:miVariable = "Nuevo Valor Global"
Comandos Útiles
- Listar Variables en un Ámbito Específico:
Get-Variable -Scope Global Get-Variable -Scope Local
- Crear una Variable en un Ámbito Específico:
New-Variable -Scope Global -Name miVariable -Value "Valor"
El manejo adecuado del alcance de las variables es crucial para evitar conflictos y asegurar que tus scripts funcionen como esperas.
Condicionales en PowerShell
Los condicionales son estructuras de control que permiten ejecutar bloques de código basados en ciertas condiciones. En PowerShell, la instrucción más común para esto es if
.
Sintaxis Básica
La sintaxis básica de un condicional if
en PowerShell es la siguiente:
if (condición) {
# Código a ejecutar si la condición es verdadera
}
Ejemplo Básico
Supongamos que queremos verificar si un número es mayor que 10:
$numero = 15
if ($numero -gt 10) {
Write-Output "El número es mayor que 10"
}
En este ejemplo, $numero
es 15, y como 15 es mayor que 10, se ejecutará el bloque de código dentro del if
.
Operadores de Comparación
PowerShell utiliza varios operadores de comparación para evaluar condiciones:
-eq
: Igual a-ne
: No igual a-gt
: Mayor que-lt
: Menor que-ge
: Mayor o igual que-le
: Menor o igual que
Ejemplo con Operadores de Comparación
$edad = 18
if ($edad -ge 18) {
Write-Output "Eres mayor de edad."
} else {
Write-Output "Eres menor de edad."
}
En este caso, si $edad
es mayor o igual a 18, se imprimirá “Eres mayor de edad.” De lo contrario, se imprimirá “Eres menor de edad.”
Condicionales Anidados y Múltiples Condiciones
Puedes anidar condicionales y usar múltiples condiciones con los operadores lógicos -and
, -or
, y -not
.
Ejemplo de Condicionales Anidados
$numero = 25
if ($numero -gt 10) {
if ($numero -lt 30) {
Write-Output "El número está entre 10 y 30"
}
}
Ejemplo con Múltiples Condiciones
$edad = 20
$ciudad = "Madrid"
if ($edad -ge 18 -and $ciudad -eq "Madrid") {
Write-Output "Eres mayor de edad y vives en Madrid."
}
En este ejemplo, ambas condiciones deben ser verdaderas para que se ejecute el bloque de código.
Ejemplo Completo
Aquí tienes un ejemplo más completo que incluye varias estructuras condicionales:
$usuario = "Juan"
$edad = 25
$ciudad = "Barcelona"
if ($usuario -eq "Juan" -and $edad -ge 18) {
if ($ciudad -eq "Madrid") {
Write-Output "Hola Juan, eres mayor de edad y vives en Madrid."
} elseif ($ciudad -eq "Barcelona") {
Write-Output "Hola Juan, eres mayor de edad y vives en Barcelona."
} else {
Write-Output "Hola Juan, eres mayor de edad."
}
} else {
Write-Output "No eres Juan o no eres mayor de edad."
}
Este script verifica el nombre del usuario, su edad y su ciudad, y responde con un mensaje adecuado basado en esas condiciones.
Bucles en PowerShell
Los bucles son estructuras de control que permiten ejecutar un bloque de código varias veces. En PowerShell, hay varios tipos de bucles: while
, do-while
, do-until
, for
, y foreach
.
Bucle while
El bucle while
ejecuta un bloque de código mientras una condición sea verdadera.
$contador = 0
while ($contador -lt 5) {
Write-Output "El contador es $contador"
$contador++
}
En este ejemplo, el bucle se ejecutará mientras $contador
sea menor que 5.
Bucle do-while
El bucle do-while
es similar al while
, pero garantiza que el bloque de código se ejecute al menos una vez.
$contador = 0
do {
Write-Output "El contador es $contador"
$contador++
} while ($contador -lt 5)
Bucle do-until
El bucle do-until
es similar al do-while
, pero se ejecuta hasta que la condición sea verdadera.
$contador = 0
do {
Write-Output "El contador es $contador"
$contador++
} until ($contador -ge 5)
Bucle for
El bucle for
es útil cuando sabes cuántas veces quieres que se ejecute el bloque de código.
for ($i = 0; $i -lt 5; $i++) {
Write-Output "El valor de i es $i"
}
En este ejemplo, el bucle se ejecutará 5 veces, incrementando $i
en cada iteración.
Bucle foreach
El bucle foreach
se utiliza para iterar sobre una colección de elementos.
$numeros = 1..5
foreach ($numero in $numeros) {
Write-Output "El número es $numero"
}
En este ejemplo, el bucle iterará sobre cada número en la colección $numeros
.
Ejemplo Completo
Aquí tienes un ejemplo más completo que utiliza varios tipos de bucles:
# Bucle while
$contador = 0
while ($contador -lt 3) {
Write-Output "While: El contador es $contador"
$contador++
}
# Bucle do-while
$contador = 0
do {
Write-Output "Do-While: El contador es $contador"
$contador++
} while ($contador -lt 3)
# Bucle do-until
$contador = 0
do {
Write-Output "Do-Until: El contador es $contador"
$contador++
} until ($contador -ge 3)
# Bucle for
for ($i = 0; $i -lt 3; $i++) {
Write-Output "For: El valor de i es $i"
}
# Bucle foreach
$colores = @("Rojo", "Verde", "Azul")
foreach ($color in $colores) {
Write-Output "Foreach: El color es $color"
}
Este script muestra cómo usar cada tipo de bucle en PowerShell para realizar tareas repetitivas.
¿Qué es una Función en PowerShell?
Una función en PowerShell es un bloque de código que tiene un nombre y puede ser llamado en cualquier momento para ejecutar ese bloque de código. Las funciones pueden aceptar parámetros de entrada y devolver valores.
Sintaxis Básica
La sintaxis básica para definir una función en PowerShell es la siguiente:
function Nombre-Funcion {
Param (
# Definición de parámetros
)
# Cuerpo de la función
}
Ejemplo Básico
Vamos a crear una función simple que saluda al usuario:
function Saludar-Usuario {
Param (
[string]$Nombre
)
Write-Output "Hola, $Nombre!"
}
# Llamar a la función
Saludar-Usuario -Nombre "Juan"
En este ejemplo, la función Saludar-Usuario
toma un parámetro $Nombre
y imprime un saludo.
Funciones con Múltiples Parámetros
Las funciones pueden aceptar múltiples parámetros. Aquí tienes un ejemplo:
function Sumar-Numeros {
Param (
[int]$Numero1,
[int]$Numero2
)
$Resultado = $Numero1 + $Numero2
Write-Output "La suma de $Numero1 y $Numero2 es $Resultado"
}
# Llamar a la función
Sumar-Numeros -Numero1 5 -Numero2 10
Funciones con Parámetros Opcionales y Valores Predeterminados
Puedes definir parámetros opcionales y establecer valores predeterminados:
function Saludar-Usuario {
Param (
[string]$Nombre = "Usuario"
)
Write-Output "Hola, $Nombre!"
}
# Llamar a la función sin parámetro
Saludar-Usuario
# Llamar a la función con parámetro
Saludar-Usuario -Nombre "Ana"
Funciones Avanzadas
Las funciones avanzadas en PowerShell permiten un mayor control y funcionalidad, como la validación de parámetros y la gestión de errores. Aquí tienes un ejemplo de una función avanzada:
function Obtener-Archivo {
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true)]
[string]$Ruta
)
if (Test-Path $Ruta) {
Get-ChildItem -Path $Ruta
} else {
Write-Error "La ruta especificada no existe."
}
}
# Llamar a la función
Obtener-Archivo -Ruta "C:\MiCarpeta"
Ejemplo Completo
Aquí tienes un ejemplo más completo que combina varios conceptos:
function Procesar-Archivos {
[CmdletBinding()]
Param (
[Parameter(Mandatory=$true)]
[string]$Ruta,
[Parameter(Mandatory=$false)]
[string]$Extension = "*.*"
)
if (Test-Path $Ruta) {
$Archivos = Get-ChildItem -Path $Ruta -Filter $Extension
foreach ($Archivo in $Archivos) {
Write-Output "Procesando archivo: $($Archivo.Name)"
# Aquí puedes agregar más lógica para procesar cada archivo
}
} else {
Write-Error "La ruta especificada no existe."
}
}
# Llamar a la función
Procesar-Archivos -Ruta "C:\MiCarpeta" -Extension "*.txt"
En este ejemplo, la función Procesar-Archivos
toma una ruta y una extensión de archivo como parámetros, verifica si la ruta existe y luego procesa cada archivo que coincide con la extensión especificada.
Estructura de datos
En PowerShell, hay varias estructuras de datos que puedes utilizar para almacenar y manipular información. Las más comunes son las matrices (arrays), las tablas hash (hash tables), y las listas (lists). Vamos a ver cada una de ellas en detalle con ejemplos.
1. Matrices (Arrays)
Una matriz es una colección de elementos del mismo tipo. Puedes crear una matriz utilizando el operador @()
.
Ejemplo Básico
# Crear una matriz de números
$numeros = @(1, 2, 3, 4, 5)
# Acceder a un elemento de la matriz
Write-Output $numeros[0] # Salida: 1
# Recorrer la matriz
foreach ($numero in $numeros) {
Write-Output $numero
}
2. Tablas Hash (Hash Tables)
Una tabla hash es una colección de pares clave-valor. Es útil para almacenar datos que necesitan ser recuperados rápidamente mediante una clave.
Ejemplo Básico
# Crear una tabla hash
$edades = @{
"Juan" = 25
"Ana" = 30
"Pedro" = 35
}
# Acceder a un valor mediante su clave
Write-Output $edades["Juan"] # Salida: 25
# Agregar un nuevo par clave-valor
$edades["Maria"] = 28
# Recorrer la tabla hash
foreach ($nombre in $edades.Keys) {
Write-Output "$nombre tiene $($edades[$nombre]) años"
}
3. Listas (Lists)
Las listas son similares a las matrices, pero ofrecen más flexibilidad. Puedes agregar y eliminar elementos fácilmente.
Ejemplo Básico
# Crear una lista
$lista = New-Object System.Collections.Generic.List[System.Object]
# Agregar elementos a la lista
$lista.Add(1)
$lista.Add("Hola")
$lista.Add($true)
# Acceder a un elemento de la lista
Write-Output $lista[1] # Salida: Hola
# Recorrer la lista
foreach ($elemento in $lista) {
Write-Output $elemento
}
4. Pilas (Stacks) y Colas (Queues)
Las pilas y colas son estructuras de datos que permiten almacenar elementos de manera ordenada. Las pilas siguen el principio LIFO (Last In, First Out) y las colas siguen el principio FIFO (First In, First Out).
Ejemplo de Pila
# Crear una pila
$pila = New-Object System.Collections.Stack
# Agregar elementos a la pila
$pila.Push(1)
$pila.Push(2)
$pila.Push(3)
# Eliminar y obtener el elemento superior de la pila
Write-Output $pila.Pop() # Salida: 3
Ejemplo de Cola
# Crear una cola
$cola = New-Object System.Collections.Queue
# Agregar elementos a la cola
$cola.Enqueue(1)
$cola.Enqueue(2)
$cola.Enqueue(3)
# Eliminar y obtener el primer elemento de la cola
Write-Output $cola.Dequeue() # Salida: 1
5. Diccionarios Ordenados (Ordered Dictionaries)
Los diccionarios ordenados son similares a las tablas hash, pero mantienen el orden de los elementos según se agregan.
Ejemplo Básico
# Crear un diccionario ordenado
$diccionario = [ordered]@{
"Uno" = 1
"Dos" = 2
"Tres" = 3
}
# Acceder a un valor mediante su clave
Write-Output $diccionario["Dos"] # Salida: 2
# Recorrer el diccionario ordenado
foreach ($clave in $diccionario.Keys) {
Write-Output "$clave: $($diccionario[$clave])"
}
Estas son algunas de las estructuras de datos más comunes en PowerShell. Cada una tiene sus propias ventajas y se utiliza en diferentes escenarios según las necesidades del script o programa que estés desarrollando.
En PowerShell, las clases y los objetos se utilizan para aplicar conceptos de programación orientada a objetos. A continuación, te explico cómo se crean y utilizan, con ejemplos para cada paso.
Clases y Objetos
Creación de Clases
Una clase es un plano para crear objetos. Define las propiedades y métodos que los objetos de esa clase tendrán. Aquí tienes un ejemplo básico de cómo definir una clase en PowerShell:
class Persona {
[string]$Nombre
[int]$Edad
Persona([string]$nombre, [int]$edad) {
$this.Nombre = $nombre
$this.Edad = $edad
}
[void]Saludar() {
Write-Output "Hola, mi nombre es $($this.Nombre) y tengo $($this.Edad) años."
}
}
Creación de Objetos
Una vez que tienes una clase, puedes crear objetos (instancias de la clase) utilizando el constructor definido en la clase. Aquí tienes un ejemplo de cómo crear un objeto de la clase Persona
:
$persona1 = [Persona]::new("Juan", 30)
$persona1.Saludar()
Este código creará un objeto persona1
con el nombre “Juan” y la edad de 30 años, y luego llamará al método Saludar
que imprimirá un saludo.
Propiedades y Métodos
Las propiedades son variables que pertenecen a una clase, y los métodos son funciones que pertenecen a una clase. En el ejemplo anterior, Nombre
y Edad
son propiedades, y Saludar
es un método.
Herencia
PowerShell también soporta la herencia, lo que significa que puedes crear una nueva clase basada en una clase existente. Aquí tienes un ejemplo:
class Empleado : Persona {
[string]$Puesto
Empleado([string]$nombre, [int]$edad, [string]$puesto) : base($nombre, $edad) {
$this.Puesto = $puesto
}
[void]MostrarPuesto() {
Write-Output "Soy $($this.Nombre) y trabajo como $($this.Puesto)."
}
}
$empleado1 = [Empleado]::new("Ana", 28, "Desarrolladora")
$empleado1.Saludar()
$empleado1.MostrarPuesto()
En este ejemplo, Empleado
hereda de Persona
, por lo que Empleado
tiene todas las propiedades y métodos de Persona
, además de su propia propiedad Puesto
y el método MostrarPuesto
.
Clases Estáticas
Las clases estáticas son clases que no se pueden instanciar. Se utilizan para agrupar métodos y propiedades que no dependen de una instancia específica. Aquí tienes un ejemplo:
class Utilidades {
static [void]MostrarFecha() {
Write-Output (Get-Date)
}
}
[Utilidades]::MostrarFecha()
En este caso, Utilidades
es una clase estática con un método MostrarFecha
que imprime la fecha actual.
Resumen
- Definir una clase: Utiliza la palabra clave
class
. - Crear un objeto: Utiliza el constructor de la clase con
::new()
. - Propiedades y métodos: Define variables y funciones dentro de la clase.
- Herencia: Utiliza
: base()
para heredar de otra clase. - Clases estáticas: Define métodos y propiedades que no dependen de una instancia.