Exception calling "Send" with "1" argument(s): "Failure sending mail."

Running the following code and getting error listed in Subject line.

I have tried different ports, different email servers, not sure how to proceed here. My email service of choice is Yahoo. Please help!!!:

Define the event logs to extract

$logArray = @(“Application”, “System”, “Security”, “Setup”)
#, “Forwarded Events”

Provide the path to store the log file extraction

$destinationPath = "C:\WindowsEventLogs"

Get the current date in YearMonthDay format

$logDate = Get-Date -Format yyyyMMddHHmm

Initialize an empty array to store log entries

$output = @()

Extract each log file listed in $logArray

foreach ($log in $logArray) {
$destination = Join-Path $destinationPath “$env:COMPUTERNAME-$log-$logDate.evtx”
Write-Host “Extracting the $log file now.”
wevtutil epl $log $destination
}

Send the log file via email

$smtpServer = “smtp.mail.yahoo.com
$smtpPort = 465
$smtpUsername = “"
$smtpPassword = "

$smtp = New-Object System.Net.Mail.SmtpClient($smtpServer, $smtpPort)
$smtp.Credentials = New-Object System.Net.NetworkCredential($smtpUsername, $smtpPassword)
$smtp.EnableSsl = $true

$mail = New-Object System.Net.Mail.MailMessage
$mail.From = “"
$mail.To.Add("
”)
$mail.Subject = “Event Viewer Log Issues”
$mail.Body = “The following are the Errors and Warnings logged from the Event Viewer Over-Night”

$smtp.Send($mail)

Can you please format your code using the “preformatted text” button in the composition window, or put 3 back ticks above and below your code (same thing)?

PowerShell 7.4.3
PS C:\Windows\System32> # Define the event logs to extract
>> $logArray = @("Application", "System", "Security", "Setup")
>> #, "Forwarded Events"
>> # Provide the path to store the log file extraction
>> $destinationPath = "C:\WindowsEventLogs\"
>>
>> # Get the current date in YearMonthDay format
>> $logDate = Get-Date -Format yyyyMMddHHmm
>>
>> # Initialize an empty array to store log entries
>> $output = @()
>>
>> # Extract each log file listed in $logArray
>> foreach ($log in $logArray) {
>>     $destination = Join-Path $destinationPath "$env:COMPUTERNAME-$log-$logDate.evtx"
>>     Write-Host "Extracting the $log file now."
>>     wevtutil epl $log $destination
>> }
>>
>> # Send the log file via email
>> $smtpServer = "smtp.mail.yahoo.com"
>> $smtpPort = 465
>> $smtpUsername = "***************"
>> $smtpPassword = "***************"
>>
>>
>> $smtp = New-Object System.Net.Mail.SmtpClient($smtpServer, $smtpPort)
>> $smtp.Credentials = New-Object System.Net.NetworkCredential($smtpUsername, $smtpPassword)
>> $smtp.EnableSsl = $true
>>
>> $mail = New-Object System.Net.Mail.MailMessage
>> $mail.From = "nal2us2@yahoo.com"
>> $mail.To.Add("nal2us2@yahoo.com")
>> $mail.Subject = "Event Viewer Log Issues"
>> $mail.Body = "The following are the Errors and Warnings logged from the Event Viewer Over-Night"
>>
>> $smtp.Send($mail)
Extracting the Application file now.
Extracting the System file now.
Extracting the Security file now.
Extracting the Setup file now.
MethodInvocationException:
Line |
  37 |  $smtp.Send($mail)
     |  ~~~~~~~~~~~~~~~~~
     | Exception calling "Send" with "1" argument(s): "Failure sending mail."

Done. Can you help me now?

Have you tried elevating the TLS protocol? Might be a problem negotiating the TLS connection.

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12

Where in the code would I insert that TLS Protocol line Matt?

Anywhere before you try to make the connection. At the top is fine.

I tried that and got the exact same message.

Please see the following code:

PowerShell 7.4.3
PS C:\Windows\System32> [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
PS C:\Windows\System32> # Define the event logs to extract
PS C:\Windows\System32> $logArray = @("Application", "System", "Security", "Setup")
PS C:\Windows\System32> #, "Forwarded Events"
PS C:\Windows\System32> # Provide the path to store the log file extraction
PS C:\Windows\System32> $destinationPath = "C:\WindowsEventLogs\"
PS C:\Windows\System32>
PS C:\Windows\System32> # Get the current date in YearMonthDay format
PS C:\Windows\System32> $logDate = Get-Date -Format yyyyMMddHHmm
PS C:\Windows\System32>
PS C:\Windows\System32> # Initialize an empty array to store log entries
PS C:\Windows\System32> $output = @()
PS C:\Windows\System32>
PS C:\Windows\System32> # Extract each log file listed in $logArray
PS C:\Windows\System32> foreach ($log in $logArray) {
>>     $destination = Join-Path $destinationPath "$env:COMPUTERNAME-$log-$logDate.evtx"
>>     Write-Host "Extracting the $log file now."
>>     wevtutil epl $log $destination
>> }
Extracting the Application file now.
Extracting the System file now.
Extracting the Security file now.
Extracting the Setup file now.
PS C:\Windows\System32>
PS C:\Windows\System32> # Send the log file via email
PS C:\Windows\System32> $smtpServer = "smtp.mail.yahoo.com"
PS C:\Windows\System32> $smtpPort = 465
PS C:\Windows\System32> $smtpUsername = "********"
PS C:\Windows\System32> $smtpPassword = "********"
PS C:\Windows\System32>
PS C:\Windows\System32>
PS C:\Windows\System32> $smtp = New-Object System.Net.Mail.SmtpClient($smtpServer, $smtpPort)
PS C:\Windows\System32> $smtp.Credentials = New-Object System.Net.NetworkCredential($smtpUsername, $smtpPassword)
PS C:\Windows\System32> $smtp.EnableSsl = $true
PS C:\Windows\System32>
PS C:\Windows\System32> $mail = New-Object System.Net.Mail.MailMessage
PS C:\Windows\System32> $mail.From = "*********"
PS C:\Windows\System32> $mail.To.Add("*********")
PS C:\Windows\System32> $mail.Subject = "Event Viewer Log Issues"
PS C:\Windows\System32> $mail.Body = "The following are the Errors and Warnings logged from the Event Viewer Over-Night"
PS C:\Windows\System32>
PS C:\Windows\System32> $smtp.Send($mail)
MethodInvocationException: Exception calling "Send" with "1" argument(s): "Failure sending mail."

I’ll do some research on the SMTP problem but right now you’re biggest problem is you just posted your Yahoo password on the internet. Edit your post immediately and take that out, and change your Yahoo password.

EDIT: seeing as how you have mfa turned on for your yahoo account I suspected it was something to do with that. A quick search yielded this page:

You’ll have to log in to your Yahoo account and generate an App password and then re-test using that. The rest of your code seems fine from what I can see and test.

Ultimately I would recommend using a 3rd party service for sending mail instead of a personal account. Something like: https://www.smtp2go.com/

1 Like

Thanks so much for catching that Grey. I thought I “starred” it out but apparently I wasnt paying attention when I posted that. Password changed. God bless you Sir. As far as the rest of the code is concerned still not working. Will test some more today. Thank you

Generated yahoo app specific password.

Email is going through now but its not attaching the logs… just the subject name and message with no log attachments.

I think I need the $attachment option but not sure how to set it up for proper syntax. Any help would be appreciated.

Thank you

Trying to add the following before send but I believe its the wrong syntax:
$mail.Attachments =

Getting a Read only error

What I am trying to do is attach the contents of a folder using the folder path as follows:

$mail.Attachments = "C:\WindowsEventLogs"

getting the following error msg:
InvalidOperation:
Line |
39 | $mail.Attachments = "C:\WindowsEventLogs"
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
| ‘Attachments’ is a ReadOnly property.

pretty sure you can’t just point at a folder and have it assume the contents.
You’re gonna need to specify them manually, and even then I wouldn’t. You’ll probably want to add them to a zip archive first and be wary of the size because SMTP still has a max size limit.

EDIT:
Ok, first off, please make sure you’re always using the “Preformatted Text” button when sharing any kind of code (code from an IDE, shell output, errors, etc). It makes it much easier to read.
Secondly, maybe it’s time to look at using the built-in cmdlet Send-MailMessage. It’s not going to solve your attachments problem but it can be easier to read.
There are a lot of parameters for Send-MailMessage so I suggest building a hashtable and then splatting it. good article on Send-MailMessage

$Credential = Get-Credential -Credential nal2us2@yahoo.com
#then provide your password at the prompt
$SendMail = @{
    From = "nal2us2@yahoo.com"
    To = "nal2us2@yahoo.com"
    Subject = "Event Viewer Log Issues"
    Body = "The following are the Errors and Warnings logged from the Event Viewer Over-Night"
    Priority = "High"
    Attachments = Get-ChildItem "C:\WindowsEventLogs"
    SMTPServer = "smtp.mail.yahoo.com"
    Port = "465"
    Credential = $Credential
    BodyAsHtml = $true
    ErrorAction = "Stop"
}     

Send-MailMessage @SendMail

If you really must leave your password in plain text in your script. then change the top part out for this

$Password = "MyPassword" | ConvertTo-SecureString -AsPlainText -Force
$Credential = [System.Management.Automation.PSCredential]::new("nal2us2@yahoo.com", $Password)

I tested this in my own environment (using different SMTP settings) and it works. Get-ChildItem is providing an array of files to the Attachments parameter, which automatically leverages the ToString() method on them to satisfy the type requirement for the parameter. I end up with an email containing multiple attachments.
Now as long as your files in that directory are small you should be able to get away with doing this (less than 25MB total is the figure to keep in mind).

I cant get this thing to work. Can you show me how to integrate the code you mentioned in your last email with my existing code of:

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# Define the event logs to extract
$logArray = @("Application", "System", "Security", "Setup")
#, "Forwarded Events"
# Provide the path to store the log file extraction
$destinationPath = "C:\WindowsEventLogs\"

# Get the current date in YearMonthDay format
$logDate = Get-Date -Format yyyyMMddHHmm

# Initialize an empty array to store log entries
$output = @()

# Extract each log file listed in $logArray
foreach ($log in $logArray) {
    $destination = Join-Path $destinationPath "$env:COMPUTERNAME-$log-$logDate.evtx"
    Write-Host "Extracting the $log file now."
    wevtutil epl $log $destination
}

# Send the log file via email
$smtpServer = "smtp.mail.yahoo.com"
$smtpPort = 587
$smtpUsername = "nal2us2@yahoo.com"
$smtpPassword = "***"

$smtp = New-Object System.Net.Mail.SmtpClient($smtpServer, $smtpPort)
$smtp.Credentials = New-Object System.Net.NetworkCredential($smtpUsername, $smtpPassword)
$smtp.EnableSsl = $true

$mail = New-Object System.Net.Mail.MailMessage
$mail.From = "nal2us2@yahoo.com"
$mail.To.Add("nal2us2@yahoo.com")
$mail.Subject = "Event Viewer Log Issues"
$mail.Body = "The following are the Errors and Warnings logged from the Event Viewer Over-Night"
$mail.Attachments = "C:\WindowsEventLogs\*.evtx"
$smtp.Send($mail)

I think you ignored what I was saying:

Your code is still using the .NET SmtpClient, which should work, but why do that when Send-MailMessage exists?
Either way, you’re still not feeding “Attachments” an array of strings which is what it requires.
Change this line:

$mail.Attachments = "C:\WindowsEventLogs\*.evtx"

to this:

$mail.Attachments = Get-ChildItem "C:\WindowsEventLogs\*.evtx"

Tried that just now… Same error message.

Ok, stop using the .NET method for sending mail and just use Send-MailMessage.

[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
# Define the event logs to extract
$logArray = @("Application", "System", "Security", "Setup")
#, "Forwarded Events"
# Provide the path to store the log file extraction
$destinationPath = "C:\WindowsEventLogs\"

# Get the current date in YearMonthDay format
$logDate = Get-Date -Format yyyyMMddHHmm

# Initialize an empty array to store log entries
$output = @()

# Extract each log file listed in $logArray
foreach ($log in $logArray) {
    $destination = Join-Path $destinationPath "$env:COMPUTERNAME-$log-$logDate.evtx"
    Write-Host "Extracting the $log file now."
    wevtutil epl $log $destination
}

# Send the log file via email
$Password = "MyPassword" | ConvertTo-SecureString -AsPlainText -Force
$Credential = [System.Management.Automation.PSCredential]::new("nal2us2@yahoo.com", $Password)
$SendMail = @{
    From = "nal2us2@yahoo.com"
    To = "nal2us2@yahoo.com"
    Subject = "Event Viewer Log Issues"
    Body = "The following are the Errors and Warnings logged from the Event Viewer Over-Night"
    Priority = "High"
    Attachments = Get-ChildItem "C:\WindowsEventLogs\*.evtx"
    SMTPServer = "smtp.mail.yahoo.com"
    Port = 587
    Credential = $Credential
    BodyAsHtml = $true
    ErrorAction = "Stop"
}     

Send-MailMessage @SendMail

EDIT:
and the reason why you’re getting this error:

Is because according to the documentation for this .NET class you can’t provide a string as a value for the Attachments property on a MailMessage object. You have to create an Attachment object, and then call the “Add” method on MailMessage to add the object.

$Attachment = [system.net.mail.attachment]::new("C:\WindowsEventLogs\Application.evtx")
$Mail.Attachments.Add($Attachment)

But the “New” method on the Attachment object only accepts a single string for input, so you’d have to loop through all of the attachments you want to add, create them as Attachment objects and add them one at a time to the Attachments property of the MailMessage.

Again, use Send-MailMessage instead and avoid all of this.

1 Like

YOU ARE…

THE POWERSHELL JEDI MASTER!!!

IT WORKS!!!

Now for the final push. I need to modify the code so that it ONLYdisplays the Errors and Warnings from the Windows Event Viewer I have listed.

Thank you so very much for the info you provided thus far!!!

It looks like there are no built in cmdlets that can output an .evtx file. There’s a Get-WMIObject method that a lot of people reference but that’s not available in Powershell 7.4 so I went looking further and found a post on this same forum with another technique:

They use a .NET class to read the logs and it has an ExportLog method. It relies on some XML filtering to get what you want but that’s fairly well documented out there too.
Try using this block of code in your script:

# Extract each log file listed in $logArray
$EventSession = New-Object System.Diagnostics.Eventing.Reader.EventLogSession
foreach ($log in $logArray) {
    $destination = Join-Path $destinationPath "$env:COMPUTERNAME-$log-$logDate.evtx"
    Write-Host "Extracting the $log file now."
    $EventSession.ExportLog($Log,'LogName',"*[System[(Level=2 or Level=3)]]",$Destination)
}

This creates the EventLogSession object for reading/exporting the logs, then in your existing loop we just replace the use of wevtutil with the ExportLog method with the following arguments

$Log = The path from Windows Event Viewer
‘LogName’ = the path type from Windows Event Viewer
“*[System[(Level=2 or Level=3)]]” = string query where level correpsonds to the Event Level
Level 1 = Critical
Level 2 = Error
Level 3 = Warning
etc…
$Destination = the filepath destination for where to export the filtered log to

I tested this on my machine with Powershell 7.4 and it worked. The resulting combined file size went from 60MB (too big for email) to only 4.5MB.