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 ejecute 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 Using modificador de á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}

Referencia de variable como $using:var expande al valor de variable $var desde el contexto del autor de la llamada. No obtiene acceso al objeto 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, consulte about_Scopes

Uso de la expansión

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

En este ejemplo, la variable $Splat de expansión es una tabla hash configurada 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 placa.

$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 de llamada, para que el código fuera de la sesión pueda acceder a ellos. El Using modificador de ámbito se admite en los siguientes contextos:

  • Comandos ejecutados de forma remota, que se inician con Invoke-Command el uso de los parámetros ComputerName, HostName, SSH Conectar ion o Session (sesión remota)
  • Trabajos en segundo plano, iniciados con 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)

Dependiendo del contexto, los valores de las variables incrustadas son copias independientes de los datos en el ámbito del autor de la llamada o las referencias a ellos. En las sesiones remotas y fuera de proceso, siempre son copias independientes. En las sesiones de subproceso, 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 métodos de tipo. Para tipos simples, como System.Version, la copia es exacta. En el caso de 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 deserializado, por ejemplo, Deserialized.System.Data.DataTable

Uso de variables locales con el parámetro ArgumentList

Puede usar variables locales en un comando remoto mediante la definición de parámetros para el comando remoto y el uso del 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, , $pscomo su valor.

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

Consulte también