Author Posts

January 1, 2012 at 12:00 am

by rob.irvin at 2012-10-18 00:44:04

I am having problems with a simple foreach loop. Here is my code:

$Remote = import-csv -Path "C:\wcsv\local.csv"
$Local = import-csv -Path "C:\wcsv\local.csv"
$diff = compare-Object $Local $Remote -Property name,slot
$userslot = $user.slot

foreach ($user in $diff)
{
if (Test-Path c:\rob\$userslot)
{Write-Output $user.name}
}

My .csv files look like this:
name,slot name,slot
"john","0004" "rob","0006"
"steve","0005" "mike","0007"
"mike","0007"

The "slots" are directories.

When the loop runs, Test-Path only looks for the $appslot directory of the last person listed in $diff. So, if the last person listed in $diff is "Steve – slot 0005" and the directory is not there, but the other user slots are there I get no output. However if Steve's directory – slot 0005 is there it returns ALL the names from $diff. What I want is for the loop to check each row one at a time and if the slot exists it will output the corresponding username. When I check the variable for $user it is always "Steve – slot 0005" or the last person listed in $diff. I'm not very good at scripting but I was under the impression that the $user variable would store each line one at a time. I've been messing with this for a while now and really don't know what I've done wrong. Any advice is much appreciated.

by Klaas at 2012-10-18 01:56:47

Please check carefully if this is really the code you use:
In $Remote and $Local you import two times the same csv?
Your .csv contains two times [name] and [slot] per row? What is the delimiter then? Or is it [name],[slot name] and [slot]?
If you want $userslot to contain your rows one by one, you should include it in the foreach loop; now it will be empty all the time.

by rob.irvin at 2012-10-18 05:31:22

Thanks. Sorry but I made a typo. It should be:

$Remote = import-csv -Path "C:\wcsv\remote.csv"
$Local = import-csv -Path "C:\wcsv\local.csv"
$diff = compare-Object $Local $Remote -Property name,slot
$userslot = $user.slot

foreach ($user in $diff)
{
if (Test-Path c:\rob\$userslot)
{Write-Output $user.name}
}

I didn't copy and paste the script because it had some info from work there so changed it up a bit and made the typo.
Thanks for your quick reply.

by rob.irvin at 2012-10-18 06:22:10

I figured it out. I had to move $userslot = $user.slot into the foreach code block.
I really didn't want to create that variable but when I tried to type C:\rob\$user.slot
Powershell complained. Are there some characters I can add to $user.slot so that it will work in a path?

$Remote = import-csv -Path "C:\wcsv\remote.csv"
$Local = import-csv -Path "C:\wcsv\local.csv"
$diff = compare-Object $Local $Remote -Property name,slot

foreach ($user in $diff)
{$userslot = $user.slot
if (Test-Path c:\rob\$userslot)
{Write-Output $user.name}
}

Thanks again.

by Klaas at 2012-10-18 06:42:53

Include it in the foreach loop, that's what I said.

You can often overcome the '.' notation problem by enclosing an expression in $(): $($user.slot) but it doesn't always work and it's not always good for readability.
I think the way you did it is fine.

by nohandle at 2012-10-18 06:51:51

in this case you can also use
Test-Path ("c:\rob\"+$user.slot)

by rob.irvin at 2012-10-18 07:43:03

[quote="Klaas"]Include it in the foreach loop, that's what I said.

You can often overcome the '.' notation problem by enclosing an expression in $(): $($user.slot) but it doesn't always work and it's not always good for readability.
I think the way you did it is fine.[/quote]

Sorry Klaas. I read it a bit fast this morning and missed that. Then I was staring at it and realized what I had done. I'll be more careful reading next time. Thanks so much.