about_Remote_Variables

Descripción breve

Explica cómo usar las variables locales y remotas en comandos remotos.

Descripción larga

Puede usar variables en comandos que se ejecutan en equipos remotos. Asigne un valor a la variable y, a continuación, use la variable en lugar del valor.

De forma predeterminada, se supone que las variables de los comandos remotos se definen en la sesión que ejecuta el comando . Las variables definidas en una sesión local deben identificarse como variables locales en el comando.

Uso de variables remotas

PowerShell supone que las variables usadas en los comandos remotos se definen en la sesión en la que se ejecuta el comando.

En este ejemplo, la $ps variable se define en la sesión temporal en la que se ejecuta el Get-WinEvent comando.

Invoke-Command -ComputerName S1 -ScriptBlock {
  $ps = "*PowerShell*"; Get-WinEvent -LogName $ps
}

Cuando el comando se ejecuta en una sesión persistente, PSSession, la variable remota debe definirse en esa sesión.

$s = New-PSSession -ComputerName S1
Invoke-Command -Session $s -ScriptBlock {$ps = "*PowerShell*"}
Invoke-Command -Session $s -ScriptBlock {Get-WinEvent -LogName $ps}

Uso de variables locales

Puede usar variables locales en comandos remotos, pero la variable debe definirse en la sesión local.

A partir de PowerShell 3.0, puede usar el Using modificador de ámbito para identificar una variable local en un comando remoto.

La sintaxis de Using es la siguiente:

$Using:<VariableName>

En el ejemplo siguiente, la $ps variable se crea en la sesión local, pero se usa en la sesión en la que se ejecuta el comando. El modificador de Using ámbito identifica $ps como una variable local.

$ps = "*PowerShell*"
Invoke-Command -ComputerName S1 -ScriptBlock {
  Get-WinEvent -LogName $Using:ps
}

El Using modificador de ámbito se puede usar en una PSSession.

$s = New-PSSession -ComputerName S1
$ps = "*PowerShell*"
Invoke-Command -Session $s -ScriptBlock {Get-WinEvent -LogName $Using:ps}

Una referencia de variable, como $using:var , por ejemplo, se expande al valor de la variable $var desde el contexto del autor de la llamada. No se obtiene acceso al objeto de variable del autor de la llamada. El Using modificador de ámbito no se puede usar para modificar una variable local dentro de PSSession. Por ejemplo, el código siguiente no funciona:

$s = New-PSSession -ComputerName S1
$ps = "*PowerShell*"
Invoke-Command -Session $s -ScriptBlock {$Using:ps = 'Cannot assign new value'}

Para obtener más información sobre Using, vea about_Scopes

Uso de la expansión

La expansión de PowerShell pasa una colección de nombres de parámetros y valores a un comando. Para obtener más información, consulte about_Splatting.

En este ejemplo, la variable de expansión es $Splat una tabla hash que se configura en el equipo local. se Invoke-Command conecta a una sesión remota del equipo. ScriptBlock usa el Using modificador de ámbito con el símbolo At (@) para representar la variable de plataforma.

$Splat = @{ Name = "Win*"; Include = "WinRM" }
Invoke-Command -Session $s -ScriptBlock { Get-Service @Using:Splat }

Otras situaciones en las que se necesita el modificador de ámbito "Using"

Para cualquier script o comando que se ejecute fuera de la sesión, necesita el Using modificador de ámbito para insertar valores de variable desde el ámbito de la sesión que realiza la llamada, de modo que el código fuera de la sesión pueda acceder a ellos. El Using modificador de ámbito se admite en los contextos siguientes:

  • Comandos ejecutados de forma remota, que se inician con Invoke-Command el uso de los parámetros ComputerName, HostName, SSHConnection o Session (sesión remota)
  • Trabajos en segundo plano, iniciados Start-Job (sesión fuera del proceso)
  • Trabajos de subproceso, iniciados a través Start-ThreadJob de o ForEach-Object -Parallel (sesión de subproceso independiente)

En función del contexto, los valores de variable incrustados son copias independientes de los datos en el ámbito del autor de la llamada o referencias a ellos. En sesiones remotas y fuera de proceso, siempre son copias independientes. En las sesiones de subprocesos, se pasan por referencia.

Serialización de valores de variable

Los comandos ejecutados de forma remota y los trabajos en segundo plano se ejecutan fuera de proceso. Las sesiones fuera de proceso usan la serialización y deserialización basada en XML para que los valores de las variables estén disponibles en los límites del proceso. El proceso de serialización convierte objetos en un PSObject que contiene las propiedades de los objetos originales, pero no sus métodos.

Para un conjunto limitado de tipos, la deserialización vuelve a hidratar los objetos al tipo original. El objeto rehidratado es una copia de la instancia de objeto original. Tiene las propiedades y los métodos de tipo. Para los tipos simples, como System.Version, la copia es exacta. En el caso de los tipos complejos, la copia es imperfecta. Por ejemplo, los objetos de certificado rehidratados no incluyen la clave privada.

Las instancias de todos los demás tipos son instancias de PSObject . La propiedad PSTypeNames contiene el nombre de tipo original con el prefijo Deserialized, por ejemplo, Deserialized.System.Data.DataTable.

Uso de variables locales con el parámetro ArgumentList

Puede usar variables locales en un comando remoto definiendo parámetros para el comando remoto y usando el parámetro ArgumentList del Invoke-Command cmdlet para especificar la variable local como valor de parámetro.

  • Use la param palabra clave para definir parámetros para el comando remoto. Los nombres de parámetro son marcadores de posición que no necesitan coincidir con el nombre de la variable local.

  • Use los parámetros definidos por la param palabra clave en el comando .

  • Use el parámetro ArgumentList del Invoke-Command cmdlet para especificar la variable local como valor de parámetro.

Por ejemplo, los siguientes comandos definen la $ps variable en la sesión local y, a continuación, la usan en un comando remoto. El comando usa $log como nombre de parámetro y la variable local, $ps, como su valor.

$ps = "*PowerShell*"
Invoke-Command -ComputerName S1 -ScriptBlock {
  param($log)
  Get-WinEvent -LogName $log
} -ArgumentList $ps

Consulte también