当前位置:网站首页 > 更多 > 玩电脑 > 正文

[玩转系统] 关于远程变量

作者:精品下载站 日期:2024-12-14 02:18:57 浏览:14 分类:玩电脑

关于远程变量


简短描述

解释如何在远程命令中使用本地和远程变量。

详细描述

您可以在远程计算机上运行的命令中使用变量。为变量分配一个值,然后使用该变量代替该值。

默认情况下,假定远程命令中的变量是在运行该命令的会话中定义的。在本地会话中定义的变量必须在命令中标识为本地变量。

使用远程变量

PowerShell 假定远程命令中使用的变量是在命令运行的会话中定义的。

在此示例中,$ps 变量是在运行 Get-WinEvent 命令的临时会话中定义的。

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

当命令在持久会话 PSSession 中运行时,必须在该会话中定义远程变量。

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

使用局部变量

您可以在远程命令中使用本地变量,但该变量必须在本地会话中定义。

从 PowerShell 3.0 开始,您可以使用 Using 作用域修饰符来标识远程命令中的本地变量。

Using的语法如下:

$Using:<VariableName>

在以下示例中,$ps 变量是在本地会话中创建的,但在运行命令的会话中使用。 Using 范围修饰符将 $ps 标识为局部变量。

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

Using 范围修饰符可以在 PSSession 中使用。

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

诸如 $using:var 之类的变量引用会扩展为调用者上下文中变量 $var 的值。您无法访问调用者的变量对象。 Using 范围修饰符不能用于修改 PSSession 内的局部变量。例如,以下代码不起作用:

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

有关使用的更多信息,请参阅 about_Scopes

使用泼溅

PowerShell splatting 将参数名称和值的集合传递给命令。有关详细信息,请参阅 about_Splatting。

在此示例中,splatting 变量 $Splat 是在本地计算机上设置的哈希表。 Invoke-Command 连接到远程计算机会话。 ScriptBlock 使用 Using 范围修饰符和 At (@) 符号来表示展开变量。

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

需要“Using”范围修饰符的其他情况

对于在会话外执行的任何脚本或命令,您需要 Using 作用域修饰符来嵌入调用会话作用域中的变量值,以便会话外代码可以访问它们。以下上下文支持 Using 范围修饰符:

  • 远程执行的命令,通过使用 ComputerNameHostNameSSHConnectionSession 参数(远程会话)
  • 后台作业,通过 Start-Job 启动(进程外会话)
  • 线程作业,通过 Start-ThreadJob 或 ForEach-Object -Parallel 启动(单独的线程会话)

根据上下文,嵌入变量值要么是调用者范围内数据的独立副本,要么是对其的引用。在远程和进程外会话中,它们始终是独立的副本。在线程会话中,它们通过引用传递。

变量值的序列化

远程执行的命令和后台作业在进程外运行。进程外会话使用基于 XML 的序列化和反序列化来使变量值跨进程边界可用。序列化过程将对象转换为包含原始对象属性但不包含其方法的PSObject

对于一组有限的类型,反序列化会将对象重新恢复为原始类型。再水化的对象是原始对象实例的副本。它具有类型属性和方法。对于简单类型,例如System.Version,副本是精确的。对于复杂类型,副本是不完美的。例如,重新水化的证书对象不包括私钥。

所有其他类型的实例都是PSObject实例。 PSTypeNames 属性包含以 Deserialized 为前缀的原始类型名称,例如 Deserialized.System.Data.DataTable

使用带有 ArgumentList 参数的局部变量

您可以在远程命令中使用局部变量,方法是为远程命令定义参数,并使用 Invoke-Command cmdlet 的 ArgumentList 参数将局部变量指定为参数值。

  • 使用 param 关键字定义远程命令的参数。参数名称是占位符,不需要与局部变量的名称匹配。

  • 使用命令中 param 关键字定义的参数。

  • 使用 Invoke-Command cmdlet 的 ArgumentList 参数将局部变量指定为参数值。

例如,以下命令在本地会话中定义 $ps 变量,然后在远程命令中使用它。该命令使用 $log 作为参数名称,并使用局部变量 $ps 作为其值。

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

参见

  • about_PSSessions
  • about_Remote
  • about_范围
  • about_Splatting
  • about_变量
  • Invoke-Command
  • ForEach-Object
  • 输入-PSSession
  • 新 PS 会话
  • Start-ThreadJob

您需要 登录账户 后才能发表评论

取消回复欢迎 发表评论:

关灯