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