如何在Invoke命令中修改局部变量



我正试图修改Invoke-Command中的一个变量以退出循环,但我在这方面遇到了困难。

在下面的示例脚本中,我正在连接到一台主机,从正在运行的NIC中获取信息,并将输出保存到一个文件(基线(中。然后在我的下一次迭代中,我将继续获取相同的信息,然后将测试文件和基线文件进行比较。

从另一个shell,我连接到了同一台服务器,并禁用了其中一个NIC,以强制Compare-Object查找差异。

一旦发现差异,我需要退出循环,但是我找不到更新局部变量$test_condition的方法。我尝试了很多东西,从Break、Return、$variable:global$variable:script,但到目前为止都没有成功。

$hostname = "server1"
$test_condition = $false
do {
Invoke-Command -ComputerName $hostname -Credential $credential -ScriptBlock{

$path = Test-Path -LiteralPath C:Temp"network_list_$using:hostname-Baseline.txt"
if ($path -eq $false) {
Get-NetAdapter | Where-Object Status -EQ "Up"  | Out-File -FilePath (New-Item C:Temp"network_list_$using:hostname-Baseline.txt" -Force)
} else {
Get-NetAdapter | Where-Object Status -EQ "Up" | Out-File -FilePath C:Temp"network_list_$using:hostname-Test.txt"
$objects = @{
ReferenceObject = (Get-Content C:Temp"network_list_$using:hostname-Baseline.txt")
DifferenceObject = (Get-Content C:Temp"network_list_$using:hostname-Test.txt")
}
$test_condition = (Compare-Object @objects).SideIndicator -ccontains "<="
$test_condition #this is returning True <-----
}
}
} until ($test_condition -eq $true)

有什么建议吗?我做错了什么?

TIA,ftex

您可以使用$Using:VarName作用域修饰符将变量传递到远程脚本块中,但不能使用典型的$Global:$Script来修改调用作用域中的任何内容。在这种情况下,调用作用域不是父作用域。从技术上讲,代码在远程系统上的新会话中运行,$Global:将引用该会话的全局范围。

例如:

$var = "something"
Invoke-Command -ComputerName MyComuter -ScriptBlock { $Global:var = "else"; $var}

远程会话将输出";否则";。然而,在呼叫会话中返回之后,$var将输出"0";某事";尽管在远程会话中进行了分配,但仍保持不变。

根据@SantiagoSquarzon的评论,将任务放入Do循环中,并进行其他一些修改:

$hostname = "server1"
do {
$test_condition = $false
$test_condition = 
Invoke-Command -ComputerName $hostname -Credential $credential -ScriptBlock{

$path = Test-Path -LiteralPath C:Temp"network_list_$using:hostname-Baseline.txt"
if ($path -eq $false) {
Get-NetAdapter | Where-Object Status -eq "Up"  | Out-File -FilePath (New-Item C:Temp"network_list_$using:hostname-Baseline.txt" -Force)
} else {
Get-NetAdapter | Where-Object Status -eq "Up" | Out-File -FilePath C:Temp"network_list_$using:hostname-Test.txt"
$objects = @{
ReferenceObject = (Get-Content C:Temp"network_list_$using:hostname-Baseline.txt")
DifferenceObject = (Get-Content C:Temp"network_list_$using:hostname-Test.txt")
}

(Compare-Object @objects).SideIndicator -contains "<=" # this is returning True <-----
}
}
} until ($test_condition -eq $true)

我不知道你为什么使用CCD_<"没有任何套管影响。此外,将运营商资本化也是非常不寻常的。

请注意,没有明确的返回或分配。PowerShell将发出比较的布尔结果,该结果将从远程会话返回并最终分配给$test_condition变量。

旁白:

我不知道我们为什么要使用-contains。诚然,在这种情况下它会很好,但它可能会把你带到其他地方。-contains是一个集合包含运算符,并不真正用于测试一个字符串在另一个字符串中的存在。";包含";正如最近的这个问题所表明的那样,这是一个隐含的有吸引力的危险。

总之,-contains的含义、目的和行为很容易混淆。

该CCD_ 16将返回"0";真";然而CCD_;false";即使左字符串确实包含右字符串。

上述问题的答案基本相同。我的附录回答为特定问题以及如何间接应用不同的运算符提供了一些额外的见解。

因此,作为一种实践在这种情况下,将Compare-Object命令封装在数组子表达式运算符中,如:

@( (Compare-Object @objects).SideIndicator ) -contains "<="

鉴于具体情况,我认为这是实现这种松散的最佳实践的最不具侵入性的方式。

最新更新