0

I'm attempting to compare a string-based variable against a .csv based list to determine if the string exists. What I neglected to take into account is the possibility that the variable may be a sub-string of one of the item lists.

Prior to the piece of code below I've prompted the user to enter a first name and last name and then using that information provided, the following action is performed to generate an 8 character username and then check against the list to see if that username is available or already taken.

$LastName = $objTextBoxLN.text 
$LastName = (Get-Culture).textinfo.totitlecase($LastName)

$UN = $objTextBoxLN.text.Substring(0,[System.Math]::Min(7, $objTextBoxLN.text.Length)).ToLower()+$objTextBoxFN.text.Substring(0,1).ToLower()
Write-Host "Searching for Username Conflicts"
Write-Host 

IF(select-string -Path "c:\Folder_X\userlist.csv" -pattern $UN)
    {
    $UN = $objTextBoxLN.text.Substring(0,[System.Math]::Min(6, $objTextBoxLN.text.Length))+$objTextBoxFN.text.Substring(0,2)
    Write-Host "Conflict found!  Username" $UN.ToLower() "generated using 6 characters from last name plus 2 characters from first name (Option 2)" 
    Write-Host 
ELSE
    {
    Write-Host "No Conflicts Found.  Username" $UN "generated using 7 characters from last name plus 1 character from first name (Option 1)"
    Write-Host
    }

So if on the Userlist.csv we have a list of usernames:

  • smithj
  • whitew
  • whitewi

etc ...

And the end-user enters "Harry Smit" it will generate a username of "smith" and then the IF statement will find "smith" on the list, inside the current username "smithj" and update the username to "smithhi" but this is not the behavior I was hoping to achieve, I would like it to find that the username "smith" doesn't exist and return the original username.

Appreciate any help anyone can offer, hopefully theres a simple solution.

Tom Fuller
  • 5,291
  • 7
  • 33
  • 42
VernonW
  • 91
  • 8

2 Answers2

0

Since there's one on each line, you can use the regex line begin and end anchors to force an exact match.

$UN = $objTextBoxLN.text.Substring(0,[System.Math]::Min(7, $objTextBoxLN.text.Length)).ToLower()+$objTextBoxFN.text.Substring(0,1).ToLower()

$UN = '^\s*{0}\s*$"' -f $UN
mjolinor
  • 66,130
  • 7
  • 114
  • 135
  • The .csv file is the result of an out-file statement on an sql query, it didn't generate any quotation marks on the file items but I've added a replace line to the extract – VernonW Mar 04 '16 at 00:42
  • Are there commas or any other field delimiters you can use as anchors? – mjolinor Mar 04 '16 at 01:09
  • Nothing I can see. As far as I can tell the only separator is the fact that each item is on its own line. – VernonW Mar 04 '16 at 01:34
  • Okay, That means you should be able to use line start and end anchors. I updated the answer to use line start and end anchors, and checks for leading and trailing whitespace. – mjolinor Mar 04 '16 at 01:50
0

I would recommend getting a more sane output from the query. If you can get a clean field separator, you can use import-csv and really only inspect the column you're interested in.

import-csv "c:\Folder_X\userlist.csv" -delimiter ' ' -Header @('un','f','l')

un       f       l
--       -       -
"smithj" (John   Smith)
"whitew" (Walter White)
"smith"  (Harry  Smit)

If you really can't change your input...
The select-string is capable of matching a regular expression. Build the username you're scanning for into a regex that matches the field formatting of the input you have.

select-string -Path "c:\Folder_X\userlist.csv" -Pattern "^$UN\b"

This, for instance, looks for usernames anchored at the beginning of the line, and with a word-boundary immediately following.

kb0
  • 522
  • 3
  • 8
  • I apologize, my initial post was very misleading the .csv file only consist of a single column containing usernames, Using "^$UN\b" seems to have solved it too. – VernonW Mar 04 '16 at 02:16