I'm trying to get Powershell to validate email addresses using Regex and put email addresses into good and bad csv files. I can get it to skip one line and write to file, but cannot get it to target the email addresses and validate them, then write lines to good and bad files. I can do it in C# and JavaScript, but have never done it in Powershell. I know this can be done, but not sure how.
Here is what I have so far:
Function IsValidEmail {
Param ([string] $In)
# Returns true if In is in valid e-mail format.
[system.Text.RegularExpressions.Regex]::IsMatch($In,
"^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|
(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$");
}
## Now we need to check the original file for invalid and valid emails.**
$list = Get-Content C:\Emails\OriginalEmails\emailAddresses.csv
# This way we also use the foreach loop.
##======= Test to see if the file exists ===========
if (!(Test-Path "C:\Emails\ValidEmails\ValidEmails.csv")) {
New-Item -path C:\Emails\ValidEmails -name ValidEmails.csv -type
"file" # -value "my new text"
Write-Host "Created new file and text content added"
}
else {
## Add-Content -path C:\Share\sample.txt -value "new text content"
Write-Host "File already exists and new text content added"
}
if (!(Test-Path "C:\Emails\InValidEmails\InValidEmails.csv")) {
New-Item -path C:\Emails\InValidEmails -name InValidEmails.csv -type
"file" # -value "my new text"
Write-Host "Created new file and text content added"
}
else {
# Add-Content -path C:\Emails\ValidEmails -value "new text content"
Write-Host "File already exists and new text content added"
}
#$Addresses = Import-Csv "C:\Data\Addresses.csv" -Header
Name, Address, PhoneNumber | Select -Skip 1
$EmailAddressImp = Import-Csv
"C:\Emails\OriginalEmails\emailAddresses.csv" -Header
FirstName, LastName, Email, Address, City, State, ZipCode | Select
FirstName, LastName, Email, Address, City, State, ZipCode -Skip 1
ForEach ($emailAddress in $list) {
if (IsValidEmail($emailAddress)) {
"Valid: {0}" -f $emailAddress
Out-File -Append C:\Emails\ValidEmails\ValidEmails.csv -Encoding UTF8
$EmailAddressImp | Export-Csv "C:\Emails\ValidEmails\ValidEmails.csv"
-NoTypeInformation
}
else {
"Invalid: {0}" -f $emailAddress
Out-File -Append C:\Emails\InValidEmails\InValidEmails.csv -
Encoding UTF8
$EmailAddressImp | Export-Csv
"C:\Emails\InValidEmails\InValidEmails.csv" -NoTypeInformation
}
}
I'm trying to get Powershell to validate email addresses using Regex
I would recommend against this. Accurately validating email addresses using regular expressions can be much more difficult than you might think.
Let's have a look at your regex pattern:
^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$
In it's current form it incorrectly validates [email protected]
.
On the other hand, it doesn't validate unicode-encoded internationalized domain names, like user@☎.com
(yes, that's a valid email address)
Instead of trying to find or construct a perfect email validation regex pattern, I would use the MailAddress
class for validation instead:
function IsValidEmail {
param([string]$EmailAddress)
try {
$null = [mailaddress]$EmailAddress
return $true
}
catch {
return $false
}
}
If the input string is a valid email address, the cast to [mailaddress]
will succeed and the function return $true
- if not, the cast will result in an exception, and it returns $false
.
When exporting the data, I'd consider collecting all the results at once in memory and then writing it to file once, at the end.
If you're using PowerShell version 2 or 3, you can do the same with two passes of Where-Object
:
$EmailAddresses = Import-Csv "C:\Emails\OriginalEmails\emailAddresses.csv" -Header FirstName, LastName, Email, Address, City, State, ZipCode | Select -Skip 1
$valid = $list |Where-Object {IsValidEmail $_.Email}
$invalid = $list |Where-Object {-not(IsValidEmail $_.Email)}
If you're using PowerShell version 4.0 or newer, I'd suggest using the .Where()
extension method in Split
mode:
$EmailAddresses = Import-Csv "C:\Emails\OriginalEmails\emailAddresses.csv" -Header FirstName, LastName, Email, Address, City, State, ZipCode | Select -Skip 1
$valid,$invalid = $list.Where({IsValidEmail $_.Email}, 'Split')
before exporting to file:
if($valid.Count -gt 0){
$valid |Export-Csv "C:\Emails\ValidEmails\ValidEmails.csv" -NoTypeInformation
}
if($invalid.Count -gt 0){
$invalid |Export-Csv "C:\Emails\ValidEmails\InvalidEmails.csv" -NoTypeInformation
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With