Can I use Send-MailMessage cmdlet with a CRT certificate? - powershell

I have this code:
Clear-Host
$file = "c:\Mail-content.txt"
if (test-path $file)
{
$from = "afgarciact#gmail.com"
$to = "<slopez#comfama.com.co>","<carloscu#comfama.com.co>"
$pc = get-content env:computername
$subject = "Test message " + $pc
$smtpserver ="172.16.201.55"
$body = Get-Content $file | Out-String
[System.Net.ServicePointManager]::SecurityProtocol = 'Tls,TLS11,TLS12'
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { return $true }
foreach ($recipient in $to)
{
Write-Host "Sent to $to"
Send-MailMessage -SmtpServer $smtpserver -UseSsl -From $from -To $recipient -Subject $subject -BodyAsHtml $body -Encoding ([System.Text.Encoding]::UTF8)
}
}
else
{
Write-Host "ConfiguraciĆ³n"
}
I want to know if I can use a CRT certificated instead of setting ServerCertificateValidationCallback = TRUE.
This is a test environment.
The CRT certificate was already added to the SMTP server.

Related

Unable to format Powershell foreach output and attach it to email body and subject

I'm scheduling script if windows scheduled task is disabled from the given list then send email to me with Taskname in email subject and Taskinfo in body.
But I am unable to format email body and add disabled task name in to subject.
Please help me to format email body and add disabled task name to subject.
Here is my script-
$tasknamelist= Import-Csv "C:\Documents\task.csv"
foreach ($task in $tasknamelist) {
$service=Get-ScheduledTask -TaskName "$taskname" | select -ExpandProperty State | Out-String
if ($task.State -eq "Disabled") {
$Body ="$service is not running"
}
else {
Write-Host "$Body Task is enabled" | Out-Null
}
} $Body
$From = "xxx#outlook.com"
$To = "xxx#outlook.com"
$Cc = "xxxx#outlook.com"
#$Attachment = "C:\temp\Some random file.txt"
$Subject = ""
$Body = "$Body"
$computer = $env:computername
$SMTPServer = "outlook.office365.com"
$SMTPPort = "587"
Send-MailMessage -From $From -to $To -Cc $Cc -Subject "Task Scheduler is disabled on $computer" `
-Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl `
-Credential $cred
You have declared $body as an empty vaiable after ending foreach loop. The fixed code is:
$tasknamelist = Import-Csv "C:\Documents\task.csv"
foreach ($task in $tasknamelist) {
$service = Get-ScheduledTask -TaskName "$taskname" | select -ExpandProperty State | Out-String
if ($task.State -eq "Disabled") {
$Body = "$service is not running"
}
else {
Write-Host "$Body Task is enabled" | Out-Null
}
}
$From = "xxx#outlook.com"
$To = "xxx#outlook.com"
$Cc = "xxxx#outlook.com"
#$Attachment = "C:\temp\Some random file.txt"
$Subject = ""
$computer = $env:computername
$SMTPServer = "outlook.office365.com"
$SMTPPort = 587
Send-MailMessage -From $From -to $To -Cc $Cc -Subject "Task Scheduler is disabled on $computer" `
-Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl `
-Credential $cred
And you didn't add white space in declaring variable.
$tasknamelist= Import-Csv "C:\Documents\task.csv"
foreach ($task in $tasknamelist)
{
$service=Get-ScheduledTask -TaskName $task
if ($service.State -eq "Disabled")
{
$Body ="$service is not running"
$From = "xxx#outlook.com"
$To = "xxx#outlook.com"
$Cc = "xxxx#outlook.com"
$computer = $env:computername
$Subject = $task + " disabled on " + $computer
$SMTPServer = "outlook.office365.com"
$SMTPPort = "587"
Send-MailMessage -From $From -to $To -Cc $Cc -Subject $Subject -Body $Body -SmtpServer $SMTPServer -port $SMTPPort -UseSsl -Credential $cred
}
else
{
Write-Host "$Body Task is enabled" | Out-Null
}
}

Powershell search for longfile path names and send the owner of a file a mail to do something about it

I am trying to set up a PowerShell script which reads out a UNC path on Windows and searches for longfiles/paths. After it has found the file it needs to send a mail to the owner of the file.
I have found already a script and tweaked it a bit but it doesn't seems to work yet. The following script can find the long file path now but the mail is not working properly.
$limit = 90
$testpath = "C:\test"
$resultpath = "c:\test"
$admins = "moh#test.com"
$from = "moh#test.com"
$smtpserver = "smtp.office365.com"
Get-ChildItem -Path $testpath -Recurse | ?{$_.fullname.length -gt $limit} |
Select-Object fullname,
#{n="owner";e={
$_.GetAccessControl().GetOwner('System.Security.Principal.NTAccount')}},
#{n="namelength"; e={$_.fullname.length}} |
%{
Out-File -FilePath "$resultpath\Longfiles of $($_.owner -replace "\\","-").txt" -Append -InputObject "$($_.namelength) - $($_.fullname)"
}
Get-ChildItem $resultpath -Filter "longfiles of *" | % {
if($_.name -match "Longfiles\sof\s(.+)\.txt"){
$user = $matches[1] -replace "-","\"
$ntacc = New-Object System.Security.Principal.NTAccount($user)
$sid = $ntacc.Translate([System.Security.Principal.SecurityIdentifier])
$aduser = [ADSI]"LDAP://<SID=$sid>"
$email = $aduser.Properties.mail
if($email) {Send-MailMessage -Attachments $_.fullname -Body "Please change the filenames of the files listed in the attached file to shorter!"
-From $from -SmtpServer $smtpserver -Subject "System notice" -To
$email -cc $admins
}
else {
Send-MailMessage -Attachments $_.fullname -Body "email coudn't be sent to owner" `
-From $from -SmtpServer $smtpserver -Subject "System notice" -To $admins
}
}
else {Write-Host "Some error with file $_"}
}
EDIT: This is what i see, after running the script... it is asking me to fill in the fields, while the fields are already filled in in the script such as (From: moh#test.com to moh#test.com)
[]
You issue was because of line breaks in the middle of a command. In some lines, you had a backtick character which escapes the end of the line. But as you found these are really easy to break and that's why it's best practice to use splatting on commands with many parameters.
I also changed your Select-Object calculated properties into a more readable [pscustomobject] since they are hard to format in a readable way, but this does require PS3+.
$limit = 90
$testpath = "C:\test"
$resultpath = "c:\test"
$admins = "moh#test.com"
$from = "moh#test.com"
$smtpserver = "smtp.office365.com"
Get-ChildItem -Path $testpath -Recurse |
Where-Object {$_.fullname.length -gt $limit} |
ForEach-Object {
[PSCustomObject]#{
'fullname' = $_.fullname
'owner' = $_.GetAccessControl().GetOwner('System.Security.Principal.NTAccount')
'namelength' = $_.fullname.length
}
} |
ForEach-Object {
Out-File -FilePath "$resultpath\Longfiles of $($_.owner -replace "\\","-").txt" -Append -InputObject "$($_.namelength) - $($_.fullname)"
}
Get-ChildItem $resultpath -Filter "longfiles of *" | ForEach-Object {
if ($_.name -match "Longfiles\sof\s(.+)\.txt") {
$user = $matches[1] -replace "-", "\"
$ntacc = New-Object System.Security.Principal.NTAccount($user)
$sid = $ntacc.Translate([System.Security.Principal.SecurityIdentifier])
$aduser = [ADSI]"LDAP://<SID=$sid>"
$email = $aduser.Properties.mail
if ($email) {
$mailparams = #{
'Attachments' = $_.fullname
'Body' = "Please change the filenames of the files listed in the attached file to shorter!"
'From' = $from
'SmtpServer' = $smtpserver
'Subject' = "System notice"
'To' = $email
'cc' = $admins
}
Send-MailMessage #mailparams
} else {
$mailparams = #{
'Attachments' = $_.fullname
'Body' = "email coudn't be sent to owner"
'From' = $from
'SmtpServer' = $smtpserver
'Subject' = "System notice"
'To' = $admins
}
Send-MailMessage #mailparams
}
} else {
Write-Host "Some error with file $_"
}
}
Remove the line breaks or escape them with a backtick: `. Your script must actually look like this:
if ($email) {
Send-MailMessage -Attachments $_.fullname -Body "Please change the filenames of the files listed in the attached file to shorter!"
-From $from -SmtpServer $smtpserver -Subject "System notice" -To
$email -cc $admins
}
else {
Send-MailMessage -Attachments $_.fullname -Body "email coudn't be sent to owner" `
-From $from -SmtpServer $smtpserver -Subject "System notice" -To $admins
}
And Powershell doesn't know that the line beginning with -From is part of Send-MailMessage.

Can I use TLS with Send-MailMessage cmdlet?

I am trying to send an email using PowerShell, but need to use TLS. Any way I can do that using Send-MailMessage cmdlet?
This is my code:
$file = "c:\Mail-content.txt"
if (test-path $file)
{
$from = "afgarciact#gmail.com"
$to = "<slopez#comfama.com.co>","<carloscu#comfama.com.co>"
$pc = get-content env:computername
$subject = "Test message " + $pc
$smtpserver ="172.16.201.55"
$body = Get-Content $file | Out-String
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = { return $true }
foreach ($recipient in $to)
{
write-host "Sent to $to"
Send-MailMessage -smtpServer $smtpserver -from $from -to $recipient -subject $subject -bodyAsHtml $body -Encoding ([System.Text.Encoding]::UTF8)
}
}
else
{
write-host "ConfiguraciĆ³n"
}
Thanks a lot!
Make sure your specify the -UseSsl switch:
Send-MailMessage -SmtpServer $smtpserver -UseSsl -From $from -To $recipient -Subject $subject -BodyAsHtml $body -Encoding ([System.Text.Encoding]::UTF8)
If the SMTP server uses a specific port for SMTP over TLS, use the -Port parameter:
Send-MailMessage -SmtpServer $smtpserver -Port 465 -UseSsl -From $from -To $recipient -Subject $subject -BodyAsHtml $body -Encoding ([System.Text.Encoding]::UTF8)
If you want to make sure that TLS is always negotiated (and not SSL 3.0), set the SecurityProtocol property on the ServicePointManager class:
[System.Net.ServicePointManager]::SecurityProtocol = 'Tls,TLS11,TLS12'
I have been fighting this all day. The fix for me ended up being needing to run this in a separate line first, and then I was able to run my Send-MailMessage commands:
[System.Net.ServicePointManager]::SecurityProtocol = 'Tls,TLS11,TLS12'
Thank you for the suggestion!

Sending multi line of body and multiple attachments

I have two different folders containing two text files, the goal is to send both txt files in an email using PowerShell.
The first file is stored in log and the other one in Error. I found a helpful PowerShell script to do so, however I was not sure how to add both attachments in same email and in the body having two lines for each of the attachments. Below is the script, any help is appreciated:
# Date values to find related log file for the day and hour or the run
$y = Get-Date -format yyyy
$m = Get-Date -format MM
$d = Get-Date -format dd
$h = Get-Date -format 05
# Modify the log path
$LogPath = "C:\Program Files\Logs\"
$LogFile = $LogPath + "Log_" + $y + $m + $d + "_" + $h + "*.txt"
$LogFileName = $LogFile | ? {Test-Path $LogFile} | Get-ChildItem | Where-Object { $_ -is [System.IO.FileInfo] }
$LogPath1 = "C:\Program Files\ERROR\"
$LogFile1 = $LogPath1 + "Log_" + $y + $m + $d + "_" + $h + "*.txt"
$LogFileName1 = $LogFile1 | ? {Test-Path $LogFile} | Get-ChildItem | Where-Object { $_ -is [System.IO.FileInfo] }
$MessageBodyNA = "Email from scheduler. No log file found " + $LogFile
$MessageBodyA = "Email from scheduler. File" + $LogFileName + " found and attached"
$MessageBodyNA1 = "Email from scheduler. No log file found " + $LogFile1
$MessageBodyA1 = "Email from scheduler. File(s) " + $LogFileName1 + " found and attached"
$FromAddress = "test#gmail.com"
$ToAddress = "test1#gmail.com"
$Subject = "test"
$SMTPserver = "SMTPServerName.com"
if ( $LogFileName | Where-Object { $_ -is [System.IO.FileInfo] })
{
send-mailmessage -from $FromAddress -to $ToAddress -subject $Subject -body $MessageBodyA -smtpServer $SMTPserver -Attachments $LogFileName
}
else
{
send-mailmessage -from $FromAddress -to $ToAddress -subject $Subject -body $MessageBodyNA -smtpServer $SMTPserver
}
if ( $LogFileName1 | Where-Object { $_ -is [System.IO.FileInfo] })
{
send-mailmessage -from $FromAddress -to $ToAddress -subject $Subject -body $MessageBodyA1 -smtpServer $SMTPserver -Attachments $LogFileName1
}
else
{
send-mailmessage -from $FromAddress -to $ToAddress -subject $Subject -body $MessageBodyNA1 -smtpServer $SMTPserver
}
When in doubt, read the documentation. The -Attachment parameter accepts a string array, so you can attach multiple files like this:
Send-MailMessage -From $FromAddress -To $ToAddress -Subject $Subject `
-Body $MessageBodyA -SmtpServer $SMTPserver `
-Attachments $LogFileName, $logFileName1
A multiline body can easily be created by using a multiline string:
$MessageBody = #"
This is line 1.
This is line 2.
"#
or by concatenating multiple lines:
$line1 = "This is line 1."
$line2 = "This is line 2."
$MessageBody = "$line1`n`n$line2"
This shows how to attach multiple files and multiple lines in mail body (please note that I didn't tested this)
function sendMail{
#SMTP server name and other mail parameters
$smtpServer = "smtp.bethanie.com.au"
$OFS = "`r`n`r`n"
$a = get-date
$SourceDir = "C:\Source\"
$DestDir = "C:\Dest\"
$files = get-childitem $SourceDir | where name -like "*.txt"
$attachments = #()
$msgFrom = "abc#abc.com"
$msgTo = "abc#abc.com"
$msgsubject = "Automated Task(" + $a + " )"
$msgBody = "This is an automated mail" + $OFS + "Check the attached file"
# Attach files of specific types
foreach($file in $files){
$filename = [system.io.path]::GetFileName($file.FullName)
$attachments += $file.fullname
}
Send-MailMessage -to $msgTo -From $msgFrom -SmtpServer $smtpServer -Subject $msgsubject -BodyAsHtml $msgBody -Attachments $attachments
}
#Calling function
sendMail

Attaching to an email in powershell script

I have the following powershell script:
$csv = Import-Csv -Path D:\temp\Audit.csv | Where-Object {$_.PrivateLabelSeqId -eq "602"} | Measure-Object
$Fun = $csv.Count
$mailBody =
#"
There are <b> $Fun </b> available!
"#
Send-MailMessage -Body $mailBody -BodyAsHtml `
-From "mail#mail.com" -To "mailto#mail.com" `
-Subject "Audit - FUN" -Encoding $([System.Text.Encoding]::UTF8) `
-Attachment "D:\temp\Audit.csv" `
-SmtpServer "192.0.0.20"
Yet I do not get any email sent out. Without the attachment however, it seems to work just fine. Any ideas on how to resolve this?
Thanks
I encountered the same problem once, i solved it by using System.Net.Mail instead.
$filenameAndPath = (Resolve-Path .\$file).ToString()
$from = 'mail#mail.com'
$to = "mailto#mail.com" `
$Subject "Audit - FUN" -Encoding $([System.Text.Encoding]::UTF8)
[void][Reflection.Assembly]::LoadWithPartialName('System.Net') | out-null
$message = New-Object System.Net.Mail.MailMessage($from, $to, $subject, $subject)
$attachment = New-Object System.Net.Mail.Attachment($filenameAndPath, 'text/plain')
$message.Attachments.Add($attachment)
$smtpClient = New-Object System.Net.Mail.SmtpClient
$smtpClient.host = '192.0.0.20'
$smtpClient.Send($message)
To read more about System.Net.Mail.Attachement Class
http://msdn.microsoft.com/en-us/library/system.net.mail.attachment.aspx