Leer en inglés

Compartir a través de


about_Remote_Variables

Descripción breve

Explica cómo usar 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 variable $ps se define en la sesión temporal en la que se ejecuta el comando Get-WinEvent.

PowerShell
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.

PowerShell
$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 modificador de ámbito Using para identificar una variable local en un comando remoto.

La sintaxis de Using es la siguiente:

$Using:<VariableName>

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

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

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

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

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

PowerShell
$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 técnica de expansión en 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 de expansión $Splat es una tabla hash configurada en el equipo local. El Invoke-Command se conecta a una sesión remota de un equipo. El ScriptBlock usa el modificador de ámbito Using con el símbolo de arroba (@) para representar la variable expandida.

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

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

Dependiendo del contexto, los valores de las variables incrustadas son copias independientes de los datos en el ámbito del llamador o referencias a estos. En las sesiones remotas y fuera de proceso, siempre son copias independientes. En 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 rehidrata los objetos al tipo original. El objeto rehidratado es una copia de la instancia de objeto original. Posee 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 del tipo 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 cmdlet Invoke-Command para especificar la variable local como valor de parámetro.

  • Use la palabra clave param 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 palabra clave param en el comando .

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

Por ejemplo, los siguientes comandos definen la variable $ps 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.

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

Consulte también