Powershell 中的 Foreach 和数组变量
Foreach and array variables in powershell
我正在导入 CSV 并根据 CSV 中的值回收该网站。 csv 是根据我们收到的警报动态构建的。
当我尝试以下代码时,我收到了打印的值和错误
import-csv d:\emscripts\recy\recycle.txt -Header "site","IP","Log" | foreach {
$_.IP
$_.site
$appPool = Get-WmiObject -Authentication PacketPrivacy -Impersonation Impersonate -ComputerName $_.IP -namespace "root/MicrosoftIISv2" -class IIsApplicationPool | Where-Object {$_.Name -eq "W3SVC/AppPools/$($_.site)" }
$appPool.Recycle()
}
*192.168.100.182
测试点1
您不能对空值表达式调用方法。
在 line:5 char:5
+ $appPool.Recycle()
+ ~~~~~~~~~~~~~~~~~~
+ 类别信息:InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull
192.168.100.131
测试点2
您不能对空值表达式调用方法。
在 line:5 char:5
+ $appPool.Recycle()
+ ~~~~~~~~~~~~~~~~~~
+ 类别信息:InvalidOperation: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvokeMethodOnNull*
您可以看到打印了值,但无法将任何内容放入 $appPool。
我已将其更改为以下内容,它按预期工作。
$RecyleSites = import-csv recycle.txt -Header "site","IP","Log"
foreach ($site in $RecyleSites) {
$site.IP
$site.site
$appPool = Get-WmiObject -Authentication PacketPrivacy -Impersonation Impersonate -ComputerName $site.IP -namespace "root/MicrosoftIISv2" -class IIsApplicationPool | Where-Object {$_.Name -eq "W3SVC/AppPools/$($site.site)" }
$appPool.Recycle()
}
我想了解我在第一组代码中做错了什么?
我认为您原始示例中的这段代码包含您的问题:
Where-Object {$_.Name -eq "W3SVC/AppPools/$($_.site)
$_.site
不再在范围内,因为 $_
现在代表 Where-Object
"loop" 中的当前对象。当您将 $_.site
打印为 foreach 循环的第一行时,$_
仍然表示 $RecycleSite
列表中的当前项。
这里肯定存在范围问题。您需要保存变量 $_.Site
以备后用。
$site = $_.site
$appPool = Get-WmiObject -Authentication PacketPrivacy -Impersonation Impersonate -ComputerName $_.IP -namespace "root/MicrosoftIISv2" -class IIsApplicationPool |
Where-Object {$_.Name -eq "W3SVC/AppPools/$site" }
$appPool.Recycle()
$_
总是引用 scope 中的对象。保存该范围之外的变量以供使用是一种常见做法。
你的 ForEach
构造就是通过在每次传递中保存分配变量来做到这一点 $site
我正在导入 CSV 并根据 CSV 中的值回收该网站。 csv 是根据我们收到的警报动态构建的。 当我尝试以下代码时,我收到了打印的值和错误
import-csv d:\emscripts\recy\recycle.txt -Header "site","IP","Log" | foreach {
$_.IP
$_.site
$appPool = Get-WmiObject -Authentication PacketPrivacy -Impersonation Impersonate -ComputerName $_.IP -namespace "root/MicrosoftIISv2" -class IIsApplicationPool | Where-Object {$_.Name -eq "W3SVC/AppPools/$($_.site)" }
$appPool.Recycle()
}
*192.168.100.182 测试点1 您不能对空值表达式调用方法。 在 line:5 char:5 + $appPool.Recycle() + ~~~~~~~~~~~~~~~~~~ + 类别信息:InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull
192.168.100.131 测试点2 您不能对空值表达式调用方法。 在 line:5 char:5 + $appPool.Recycle() + ~~~~~~~~~~~~~~~~~~ + 类别信息:InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull*
您可以看到打印了值,但无法将任何内容放入 $appPool。
我已将其更改为以下内容,它按预期工作。
$RecyleSites = import-csv recycle.txt -Header "site","IP","Log"
foreach ($site in $RecyleSites) {
$site.IP
$site.site
$appPool = Get-WmiObject -Authentication PacketPrivacy -Impersonation Impersonate -ComputerName $site.IP -namespace "root/MicrosoftIISv2" -class IIsApplicationPool | Where-Object {$_.Name -eq "W3SVC/AppPools/$($site.site)" }
$appPool.Recycle()
}
我想了解我在第一组代码中做错了什么?
我认为您原始示例中的这段代码包含您的问题:
Where-Object {$_.Name -eq "W3SVC/AppPools/$($_.site)
$_.site
不再在范围内,因为 $_
现在代表 Where-Object
"loop" 中的当前对象。当您将 $_.site
打印为 foreach 循环的第一行时,$_
仍然表示 $RecycleSite
列表中的当前项。
这里肯定存在范围问题。您需要保存变量 $_.Site
以备后用。
$site = $_.site
$appPool = Get-WmiObject -Authentication PacketPrivacy -Impersonation Impersonate -ComputerName $_.IP -namespace "root/MicrosoftIISv2" -class IIsApplicationPool |
Where-Object {$_.Name -eq "W3SVC/AppPools/$site" }
$appPool.Recycle()
$_
总是引用 scope 中的对象。保存该范围之外的变量以供使用是一种常见做法。
你的 ForEach
构造就是通过在每次传递中保存分配变量来做到这一点 $site