3

first question on here so forgive me if I make any mistakes, I will try to stick to the guidelines.

I am trying to write a PowerShell script that populates two arrays from data I read in via CSV file. I'm using the arrays to cross-reference directory names in order to rename each directory. One array contains the current name of the directory and the other array contains the new name.

This all seems to be working so far. I successfully create and populate the arrays, and using a short input and index lookup to check my work I can search one array for a current name and successfully retrieve the correct new name from the second array. However when I try to implement this code in a foreach loop that runs through every directory name, I can't lookup the array index (it keeps coming back as -1).

I used the code in the first answer found here as my template. Read a Csv file with powershell and capture corresponding data . Here's my modification to the input lookup, which works just fine:

$input = Read-Host -Prompt "Merchant"

if($Merchant -contains $input)
{
    Write-Host "It's there!"
    $find = [array]::IndexOf($Merchant, $input)
    Write-Host Index is $find
}

Here is my foreach loop that attempts to use the Index lookup, but returns -1 every time. However I know it's finding the file because it enters the if statement and prints "It's there!"

foreach($file in Get-ChildItem $targetDirectory)
{
    if($Merchant -contains $file)
    {
        Write-Host "It's there!"
        $find = [array]::IndexOf($Merchant, $file)
        Write-Host Index is $find
    }
}

I can't figure it out. I'm a PowerShell newb so maybe it's a simple syntax problem, but it seems like it should work and I can't find where I'm going wrong.

Community
  • 1
  • 1
jdebr
  • 527
  • 4
  • 10
  • 1
    `[array]::IndexOf($Merchant, $file)` -> `[array]::IndexOf($Merchant, [string]$file)` – user4003407 Aug 07 '15 at 19:53
  • Same issue as http://stackoverflow.com/questions/31857138/object-array-comparison-with-custom-headers/31857705 - has nothing to do with foreach, but with the type (string v fileinfo) – Mathias R. Jessen Aug 07 '15 at 19:57
  • Unless $Merchant is a string array of file names. Just use $file.Name in IndexOf then – Mathias R. Jessen Aug 07 '15 at 20:00
  • Thank you! I had a feeling it was something small I was just overlooking. What is the protocol for closing a question and/or adding rep? – jdebr Aug 07 '15 at 20:46
  • The appropriate commenter would create an answer, which you would mark as accepted. – Eris Aug 07 '15 at 23:38

1 Answers1

3

Your problem seems to be that $Merchant is a collection of file names (of type string), whereas $file is a FileInfo object.

The -contains operator expects $file to be a string, since $Merchant is a string array, and works as you expect (since FileInfo.ToString() just returns the file name).

IndexOf() isn't so forgiving. It recognizes that none of the items in $Merchant are of the type FileInfo, so it never finds $file.

You can either refer directly to the file name:

[array]::IndexOf($Merchant,$file.Name)

or, as @PetSerAl showed, convert $file to a string instead:

[array]::IndexOf($Merchant,[string]$file)
# or 
[array]::IndexOf($Merchant,"$file")
# or 
[array]::IndexOf($Merchant,$file.ToString())

Finally, you can call IndexOf() directly on the array, no need to use the static method:

$Merchant.IndexOf($file.Name)
Community
  • 1
  • 1
Mathias R. Jessen
  • 157,619
  • 12
  • 148
  • 206