2015-02-10 33 views
0

我正在导入CSV并根据CSV中的值回收该站点。 csv根据我们收到的警报动态组建。 当我尝试下面的代码我收到打印的价值观和错误Powershell中的Foreach和数组变量

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 Testsite1 你不能调用一个空值表达式的方法。 在线:5字符:5 + $ appPool.Recycle() + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + FullyQualifiedErrorId:InvokeMethodOnNull

192.168.100.131 testsite2 您无法在空值表达式上调用方法。 在线:5字符:5 + $ appPool.Recycle() + ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + 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() 
    } 

我想明白我在第一组代码中做错了什么?

+0

添加代码来验证你真的找回,你以为你是WMI对象只是这样做。 – EBGreen 2015-02-10 16:59:00

+0

谢谢。我做到了这一点,我得到了$ appPool的空值。但第二组类似的代码正在工作。唯一不同的是,我正在将这些值传递给一个数组,并且在我读取的第一组数据集中尝试传递它。我认为它没有传递_.site或$ _。IP的值。 – Sunil 2015-02-10 17:11:12

+0

我刚刚使用ForEach-Object进行了测试。不,它不工作,结果相同。与foreach也是它打印的价值,但不会进入Get-WmiObject – Sunil 2015-02-10 17:19:21

回答

2

我认为这段代码从原来的样品中含有您的问题:

Where-Object {$_.Name -eq "W3SVC/AppPools/$($_.site) 

$_.site不在范围内了,因为现在$_代表在Where-Object“循环”当前对象。当您将$_.site作为foreach循环的第一行打印时,$_仍表示$RecycleSite列表中的当前项目。

+0

谢谢,我明白你的意思。但在这种情况下,我如何使用第一个循环和第二个循环。任何想法 ? – Sunil 2015-02-10 17:47:23

+0

您的修正版本的代码看起来不错。任何地方你都可以明确地引用你想要的对象(即。$ site.IP vs $ _。IP)。做这件事的原因正是你的问题所指出的,“$ _”代表不同的对象,取决于它的使用位置。 – 2015-02-10 17:51:39

1

确实存在范围问题。您需要保存变量$_.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

+0

这是正确的,这基本上是他通过更改为“foreach($ RecycleSites $ site)”循环所做的。但是,是的,如果您想使用第一个代码片段的格式,则必须执行上述操作。 – 2015-02-10 17:53:29

+0

非常感谢,我刚刚检查了这个问题后得到这个[链接] http://stackoverflow.com/questions/8237251/how-can-i-access-a-higher-level-pipeline-variable-from-a-nested - 管道并进行测试。 – Sunil 2015-02-10 17:59:19

+0

我无法将两个答案都作为答案。所以我保持第一个答案告诉我有关该问题的答案。谢谢 – Sunil 2015-02-10 18:00:58