Home Windows Cápsula PowerShell – Uso de variables y constantes en PowerShell

Cápsula PowerShell – Uso de variables y constantes en PowerShell

by José Luis Sánchez Borque

Hoy en día no se entiende una buena administración de sistemas sin el uso de Scripts. Sus ventajas con muchas, entre las que destacan:

  • Automatización de tareas
  • Simplificación de comandos
  • Estandarización de procesos

Veamos un pequeño ejemplo con la siguiente orden, un simple listado de la carpeta c:\windows, mayores de 1000000 bytes, y ordenados por nombre.

Get-ChildItem c:\windows | Where-Object {$_.Length -gt 1000000} | Sort-Object -Property name  

Directorio: C:\windows

Mode           LastWriteTime    Length  Name
------         -------------    ------  ---- 
-a----     12/07/2017   7:55   4674872  explorer.exe
--r---     22/09/2016   8:55   2839520  RtlExUpd.dll

Aún usando la tecla TAB, la orden requiere teclear mucho, e incluso el tema se complica si queremos listar varios directorios. Podemos simplificarlo creando un pequeño script al que le pasaremos por línea de comandos los directorios a listar:

ejemplo1.ps1

foreach ($i in $args) { Get-ChildItem $i | Where-Object {$_.Length -gt 1000000} | Sort-Object -Property name}

Ahora podemos pasar como parámetros los directorios a listar:

PS C:\users\usuario\Documents> .\ejemplo1.ps1 c:\vmware c:\windows

Directorio: C:\vmware

Mode        LastWriteTime        Length  Name 
----        -------------        ------  ---- 
-a----   17/09/2017 14:46   15387918336  BT5R3-GNOME-32.vmdk

Directorio: C:\windows

Mode        LastWriteTime         Length  Name 
----        -------------         ------  ---- 
-a----    12/07/2017 7:55        4674872  explorer.exe 
--r---    22/09/2016 8:55        2839520  RtlExUpd.dll

Un tema MUY IMPORTANTE ES ACTIVAR EL SOPORTE PARA SCRIPTS. Por defecto desactivado. Podemos encontrarnos con el siguiente Error:

ejemplo.ps1 cannot be loaded because the execution of scripts is disabled on this system.

PowerShell tiene cuatro posibles directivas.

  • Restricted – No se pueden ejecutar scripts. Windows PowerShell solo lo podemos utilizar en modo interactivo mode.
  • AllSigned – Solo scripts firmados por una entidad de confianza pueden ser ejecutados.
  • RemoteSigned – Los scripts descargados deben ser firmados por una entidad de confianza antes de ser ejecutados.
  • Unrestricted – No hay restricciones. Podemos ejecutar cualquier script

Podemos conocer y cambiar el estado de las directivas con el uso de los cmdlets Get-ExecutionPolicy y Set-ExecutionPolicy.

PS C:\users\usuario\Documents> Get-ExecutionPolicy
Restricted

PS C:\users\usuario\Documents> Set-ExecutionPolicy unrestricted

PS C:\users\usuario\Documents> Get-ExecutionPolicy
Unrestricted

No olvidemos ejecutar estos cmdlets conla cuenta de administrador

Uso de Variables

Por defecto, cuando trabajamos con powershell no es necesario declarar las variables antes de utilizarlas. Al usar una variables para almacenar un datos, se declara automáticamente.  Todas las variables van precedidas por el símbolo del dólar ($).

Hay un número de variables especiales, con un significado y uso especial. Las podemos encontrar en la siguiente.

$$ Contains the last token in the last line received by the session.
$? Contains the execution status of the last operation. Equivalent to %errorlevel% in the CMD shell. See also $LastExitCode below.
It contains TRUE if the last operation succeeded and FALSE if it failed. ReadOnly, AllScope
$^ Contains the first token in the last line received by the session.
$_ Contains the current object in the pipeline object. You can use this variable in commands that perform an action on every object or on selected objects in a pipeline.
$Allnodes This variable is available inside of a DSC configuration document when configuration data has been passed into it by using the -ConfigurationData parameter.
$Args Contains an array of the undeclared parameters and/or parameter values that are passed to a function, script, or script block. When you create a function, you can declare the parameters by using the param keyword or by adding a comma-separated list of parameters in parentheses after the function name.
$ConsoleFileName Contains the path of the console file (.psc1) that was most recently used in the session. This variable is populated when you start PowerShell with the PSConsoleFile parameter or when you use the Export-Console cmdlet to export snap-in names to a console file.

When you use the Export-Console cmdlet without parameters, it automatically updates the console file that was most recently used in the session. You can use this automatic variable to determine which file will be updated.ReadOnly, AllScope

$Error Contains an array of error objects that represent the most recent errors. Constant
The most recent error is the first error object in the array ($Error[0]).
$Event Contains a PSEventArgs object that represents the event that is being processed. This variable is populated only within the Action block of an event registration command, such as Register-ObjectEvent. The value of this variable is the same object that the Get-Event cmdlet returns. Therefore, you can use the properties of the $Event variable, such as $Event.TimeGenerated , in an Action script block.
$EventArgs Contains an object that represents the first event argument that derives from EventArgs of the event that is being processed. This variable is populated only within the Action block of an event registration command. The value of this variable can also be found in the SourceEventArgs property of the PSEventArgs (System.Management.Automation.PSEventArgs) object that Get-Event returns.
$EventSubscriber Contains a PSEventSubscriber object that represents the event subscriber of the event that is being processed. This variable is populated only within the Action block of an event registration command. The value of this variable is the same object that the Get-EventSubscriber cmdlet returns.
$ExecutionContext Contains an EngineIntrinsics object that represents the execution context of the Windows PowerShell host. You can use this variable to find the execution objects that are available to cmdlets. Constant, AllScope
$False Contains FALSE. You can use this variable to represent FALSE in commands and scripts instead of using the string “false”. The string can be interpreted as TRUE if it is converted to a non-empty string or to a non-zero integer. Constant, AllScope
$ForEach Contains the enumerator of a ForEach-Object loop. You can use the properties and methods of enumerators on the value of the $ForEach variable. This variable exists only while the For loop is running. It is deleted when the loop is completed.
$Home Contains the full path of the user’s home directory. ReadOnly, AllScope This variable is the equivalent of the %HomeDrive%%HomePath% environment variables, typically C:\Users\<user>
$Host Contains an object that represents the current host application for Windows PowerShell. You can use this variable to represent the current host in commands or to display or change the properties of the host, such as $Host.version or $Host.CurrentCulture, or $host.ui.rawui.setbackgroundcolor(“Red”). Constant, AllScope
$Input An enumerator that contains the input that is passed to a function. The $Input variable is case-sensitive and is available only in functions and in script blocks. (Script blocks are essentially unnamed functions.) In the Process block of a function, the $Input variable contains the object that is currently in the pipeline. When the Process block is completed, the value of $Input is NULL. If the function does not have a Process block, the value of $Input is available to the End block, and it contains all the input to the function.
$LastExitCode Contains the exit code of the last Windows-based program that was run.
$Matches The $Matches variable works with the -match and -not match operators. When you submit scalar input to the -match or -notmatch operator, and either one detects a match, they return a Boolean value and populate the $Matches automatic variable with a hash table of any string values that were matched. For more information about the -match operator, see about_comparison_operators.
$MyInvocation Contains an object with information about the current command, such as a script, function, or script block. You can use the information in the object, such as the path and file name of the script ($myinvocation.mycommand.path) or the name of a function ($myinvocation.mycommand.name) to identify the current command. See also $PSScriptRoot
$NestedPromptLevel Contains the current prompt level. A value of 0 indicates the original prompt level. The value is incremented when you enter a nested level and decremented when you exit it. For example, Windows PowerShell presents a nested command prompt when you use the $Host.EnterNestedPrompt method. Windows PowerShell also presents a nested command prompt when you reach a breakpoint in the Windows PowerShell debugger. When you enter a nested prompt, Windows PowerShell pauses the current command, saves the execution context, and increments the value of the $NestedPromptLevel variable. To create additional nested command prompts (up to 128 levels) or to return to the original command prompt, complete the command, or type “exit”. The $NestedPromptLevel variable helps you track the prompt level. You can create an alternative Windows PowerShell command prompt that includes this value so that it is always visible.
$NULL Contains a NULL or empty value. A scalar value that contains nothing.
$OFS $OFS is a special variable that stores a string that you want to use as an output field separator. Use this variable when you are converting an array to a string. By default, the value of $OFS is ” “, but you can change the value of $OFS in your session, by typing $OFS=”value“. If you are expecting the default value of ” ” in your script, module, or configuration output, be careful that the $OFS default value has not been changed elsewhere in your code.
$PID Contains the process identifier (PID) of the process that is hosting the current Windows PowerShell session. Constant, AllScope
If you stop this process, you will brute force kill the PowerShell host that is executing the script.
$Profile Contains the full path of the Windows PowerShell profile for the current user and the current host application. You can use this variable to represent the profile in commands. For example, you can use it in a command to determine whether a profile has been created: test-path $profile Or, you can use it in a command to create a profile: new-item -type file -path $pshome -force You can also use it in a command to open the profile in Notepad: notepad $profile
$PSBoundParameters Contains a dictionary of the active parameters and their current values. This variable has a value only in a scope where parameters are declared, such as a script or function. You can use it to display or change the current values of parameters or to pass parameter values to another script or function. For example: function test { param($a, $b) # Display the parameters in dictionary format. $psboundparameters # Call the Test1 function with $a and $b. test1 @psboundparameters }
$PsCmdlet Contains an object that represents the cmdlet or advanced function that is being run. You can use the properties and methods of the object in your cmdlet or function code to respond to the conditions of use. For example, the ParameterSetName property contains the name of the parameter set that is being used, and the ShouldProcess method adds the WhatIf and Confirm parameters to the cmdlet dynamically. For more information about the $PSCmdlet automatic variable, see about_Functions_Advanced.
$PSCommandPath Contains the full path and file name of the script that is being run. This variable is valid in all scripts.
$PsCulture Contains the name of the culture currently in use in the operating system. The culture determines the display format of items such as numbers, currrency, and dates. This is the value of the System.Globalization.CultureInfo.CurrentCulture.Name property of the system. To get the System.Globalization.CultureInfo object for the system, use Get-Culture. ReadOnly, AllScope
$PSDebugContext While debugging, this variable contains information about the debugging environment. Otherwise, it contains a NULL value. As a result, you can use it to indicate whether the debugger has control. When populated, it contains a PsDebugContext object that has Breakpoints and InvocationInfo properties. The InvocationInfo property has several useful properties, including the Location property. The Location property indicates the path of the script that is being debugged.
$PsHome Contains the full path of the installation directory for Windows PowerShell, Constant, AllScope
Typically, %windir%\System32\WindowsPowerShell\v1.0
You can use this variable in the paths of Windows PowerShell files. For example, the following command searches the conceptual Help topics for the word “variable”: select-string -pattern variable -path $pshome\*.txt
$PSitem Represents the current input object, this is exactly the same as $_ it just provides an alternative name to make your pipeline code easier to read. Available in PowerShell 3.0 and greater.
$PSScriptRoot Contains the directory from which the script module is being executed. This variable allows scripts to use the module path to access other resources. In PowerShell 3.0+ this is available everywhere, not just in modules.
$PSSenderInfo Contains information about the user who started the PSSession, including the user identity and the time zone of the originating computer. This variable is available only in PSSessions.
The $PSSenderInfo variable includes a user-configurable property, ApplicationArguments, which, by default, contains only the $PSVersionTable from the originating session. To add data to the ApplicationArguments property, use the ApplicationArguments parameter of the New-PSSessionOption cmdlet.
$PsUICulture Contains the name of the user interface (UI) culture that is currently in use in the operating system. The UI culture determines which text strings are used for user interface elements, such as menus and messages. This is the value of the System.Globalization.CultureInfo.CurrentUICulture.Name property of the system. To get the System.Globalization.CultureInfo object for the system, use Get-UICulture. ReadOnly, AllScope
$PsVersionTable Contains a read-only hash table (Constant, AllScope) that displays details about the version of PowerShell that is running in the current session. The table includes the following items:

  CLRVersion          The version of the common language runtime (CLR)
  BuildVersion        The build number of the current version
  PSVersion           The Windows PowerShell version number
  WSManStackVersion      The version number of the WS-Management stack
  PSCompatibleVersions   Versions of PowerShell that are compatible with the current version.
  SerializationVersion   The version of the serialization method
  PSRemotingProtocolVersion  The version of the PowerShell remote management protocol
$Pwd Contains a path object that represents the full path of the current directory.
$Sender Contains the object that generated this event. This variable is populated only within the Action block of an event registration command. The value of this variable can also be found in the Sender property of the PSEventArgs (System.Management.Automation.PSEventArgs) object that Get-Event returns.
$ShellID Contains the identifier of the current shell. Constant, AllScope
$SourceArgs Contains objects that represent the event arguments of the event that is being processed. This variable is populated only within the Action block of an event registration command. The value of this variable can also be found in the SourceArgs property of the PSEventArgs (System.Management.Automation.PSEventArgs) object that Get-Event returns.
$SourceEventArgs Contains an object that represents the first event argument that derives from EventArgs of the event that is being processed. This variable is populated only within the Action block of an event registration command. The value of this variable can also be found in the SourceArgs property of the PSEventArgs (System.Management.Automation.PSEventArgs) object that Get-Event returns.
$StackTrace Contains a stack trace for the most recent error.
$This In a script block that defines a script property or script method, the $This variable refers to the object that is being extended.
$True Contains TRUE. You can use this variable to represent TRUE in commands and scripts. Constant, AllScope

Por ejemplo veamos el contenido de la variable $host

PS C:\Windows\system32> Write-Output $host

Name                      : Windows PowerShell ISE Host
Version                   : 5.1.14393.1770
InstanceId              : 07758c48-065a-4e3a-97af-553f9a232393
UI                             : System.Management.Automation.Internal.Host.InternalHostUserInterface
CurrentCulture      : es-ES
CurrentUICulture  : es-ES
PrivateData            : Microsoft.PowerShell.Host.ISE.ISEOptions
DebuggerEnabled : True
IsRunspacePushed : False
Runspace                 : System.Management.Automation.Runspaces.LocalRunspace

Veamos un ejemplo donde utilizamos variables de tipo String para consultar unos valores de la clase del registro HKCU:[\Software\Microsoft\Windows\CurrentVersion\Explorer]

ejemplo2.ps1

$strUserPath = "\Software\Microsoft\Windows\CurrentVersion\Explorer" 
$strUserName = "usuario" 
$strPath = "\Volatile Environment" 
$strName = "LOGONSERVER","HOMEPATH", "APPDATA","HOMEDRIVE" 
Set-Location HKCU:\ 
Get-ItemProperty -path $strUserPath 
foreach ($i in $strName) {Get-ItemProperty -path $strPath -name $i | Format-List $i}

Al ejecutarlo obtendremos la información

PS HKCU:\> C:\Users\usuario\Documents\ejemplo1.ps1

ExplorerStartupTraceRecorded : 1
ShellState : {36, 0, 0, 0...}
UserSignedIn : 1
SIDUpdatedOnLibraries : 1
LocalKnownFoldersMigrated : 1
TelemetrySalt : 2
GlobalAssocChangedCounter : 144
AppReadinessLogonComplete : 1
FirstRunTelemetryComplete : 1
Browse For Folder Width : 318
Browse For Folder Height : 346
SlowContextMenuEntries : {93, 84, 169, 162...}
link : {21, 0, 0, 0}
PSPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsof
 t\Windows\CurrentVersion\Explorer
PSParentPath : Microsoft.PowerShell.Core\Registry::HKEY_CURRENT_USER\Software\Microsof
 t\Windows\CurrentVersion
PSChildName : Explorer
PSDrive : HKCU
PSProvider : Microsoft.PowerShell.Core\Registry


LOGONSERVER : \\DESKTOP-UUCU9J8

HOMEPATH : \Users\usuario

APPDATA : C:\Users\usuario\AppData\Roaming

HOMEDRIVE : C:

Uso de constantes

El uso de constantes en PowerShell es similar al uso de variables, pero condos importantes excepciones:

  1. Su valor nunca cambia y no pueden ser borradas
  2. Han de ser creadas con el cmdlet Set-Variable

ejemplo3.ps1

$anyComputer = "localhost", "loopback"
Set-Variable -name IntDriveType -value 3 -option constant
foreach ($strPC in $anyComputer){"Hard driver on: " + $strPC Get-WmiObject -class win32_logicaldisk -computername $strPC |  where {$_.drivetype -eq $intDriveType}}

El resultado es el siguiente:

Hard driver on: localhost

DeviceID : C:
DriveType : 3
ProviderName : 
FreeSpace : 83923345408
Size : 249461469184
VolumeName :

DeviceID : D:
DriveType : 3
ProviderName : 
FreeSpace : 96105889792
Size : 239921524736
VolumeName : DATOS

Hard driver on: loopback
DeviceID : C:
DriveType : 3
ProviderName : 
FreeSpace : 83923345408
Size : 249461469184
VolumeName :

DeviceID : D:
DriveType : 3
ProviderName : 
FreeSpace : 96105889792
Size : 239921524736
VolumeName : DATOS

En el siguiente capítulo veremos:

  1. Tipos de variables y usos de arrays en powershell

  2. Estructuras iterativas y toma de decisiones

  3. Uso de módulos y funciones

Hasta pronto.

You may also like

Leave a Comment