0

I am importing a CSV and recycling that site based on the values in the CSV. The csv is dynamically buildup based on the alerts we receive. When I try the following code I receive an values printed and errors

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 You cannot call a method on a null-valued expression. At line:5 char:5 + $appPool.Recycle() + ~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull

192.168.100.131 testsite2 You cannot call a method on a null-valued expression. At line:5 char:5 + $appPool.Recycle() + ~~~~~~~~~~~~~~~~~~ + CategoryInfo : InvalidOperation: (:) [], RuntimeException + FullyQualifiedErrorId : InvokeMethodOnNull*

You can see that the values are printed but it is failing to get anything into the $appPool.

I have changed it to the following and it is working as expected.

    $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()
    }

I am trying understand what I am doing wrong in the first set of code ?

3
  • Add code to verify that you are really getting back the WMI object that you think you are. Commented Feb 10, 2015 at 16:59
  • Thanks. I did that and I was getting null for $appPool. But the second set of similar code is working. Only difference is I am taking that values in to a array and in the first set I am trying to pass it as I read. I think it is not passing the values of .site or $.IP. Commented Feb 10, 2015 at 17:11
  • I just tested with ForEach-Object also. No, it is not working, the same result. with the foreach also it is printing the values but not going into Get-WmiObject Commented Feb 10, 2015 at 17:19

2 Answers 2

2

I think that this piece of code from your original sample contains your problem:

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

$_.site isn't in scope any more because $_ now represents the current object in the Where-Object "loop". When you printed $_.site as the first line of the foreach loop, $_ still represented the current item in the $RecycleSite list.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks, I understand what you mean. but how can I use the first loop and the second loop in this case. Any idea ?
Your corrected version of the code looks OK. Anywhere you can you should explicitly reference the object you want (ie. $site.IP vs $_.IP). The reason to do that is exactly what your question pointed out, that "$_" represents different objects depending where it gets used.
1

There is a scope issue here for sure. You need to save the variable $_.Site for later use.

$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()

$_ always refers to the object in scope. Saving variables outside of that scope for use is a common practice.

Your ForEach construct is doing just that by saving the assigning the variable in each pass to $site

3 Comments

That's right, which is essentially what he has done by changing to the "foreach($site in $RecycleSites)" loop. But yes, if you want to use the format of the first code snippet, you'd have to do the above.
Many thanks, I just got this after checking the question [link] stackoverflow.com/questions/8237251/… and tested it.
I am unable to make both answers as answer.. So I am keeping the first answer told me about the issue as answer. Thanks

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.