Search code examples
arrayspowershellstring-comparison

Compare Two Arrays, Email Results in PowerShell


I'm attempting to compare two arrays: one contains a list of usernames (dynamic, sometimes more usernames, sometimes less) and the other contains a list of file names (also dynamic). Every file name contains the username along with other text, e.g "Username report [date].xlsx". The goal is to match the elements between Array A and Array B.

Array A is just usernames. Output of Array A, contained in $Username is just: PersonA PersonB PersonC etc...

Array B contains filepaths, but I can narrow it down to just filenames like so $ArrayB.Name (the full path would be $ArrayB.FullName). The naming format for Array B is "Username report [date].xlsx".

Output of Array B, contained within $LatestFiles.Name (for the file name) is: PersonA Report 1-1-21.xlsx PersonB Report 1-1-21.xlsx PersonC Report 1-1-21.xlsx

After matching, the final piece would be if element in Array A matches element in Array B, attach ArrayB.FullName to the corresponding username + "@domain.com".

Unfortunately I can't even get the matching to work properly.

I've tried:

foreach ($elem in $UserName) { if ($LatestFiles.Name -contains $elem) { "there is a match" } }

and

foreach ($elem in $UserName) {
    if($LatestFiles.Name -contains $elem) {
        "There is a match"
    } else {
        "There is no match"
    }
}

and a couple different variations, but I can't get them to output the matches. Any assistance is appreciated.


Solution

  • Short answer to why you can't get matches: -Contains is meant for matching a value against a collection, not a String. You would be better off using -Like for your comparison operator. Or, at the very least, you may be trying to see if the name of the file, and not simply the part of the name that holds the user, is in the collection of user names.

    I sounds like you are not simply comparing the arrays, but the more complicated matter of what you do with the two matching elements.

    $LatestFiles |
        ForEach-Object {
            # first, let's take the formatted file name and make it more usable
            $fileName = $_.BaseName -split ' ' # BaseName over Name so that it strips the extension
            Write-Output @{
                User = $fileName[0]
                Date = $fileName[2]
                File = $_
            }
        } -PipelineVariable FileData |
        # next, only accept valid users
        Where-Object User -In $UserName |
        # note that we don't need the value from $UserName because we already have it in $FileData.User (what we matched)
        ForEach-Object {
            # finally do your thing with it.
            $userWithDomain = "$($FileData.User)@domain.com"
            Write-Output $userWithDomain # or whatever you want
        }