How to make attachment in Send-MailMessage optional? - powershell

I amd using Send-MailMessage in my script
Send-MailMessage -From 'User01 <user01#fabrikam.com>' -To 'User02 <user02#fabrikam.com>', 'User03 <user03#fabrikam.com>' -Subject 'Sending the Attachment' -Body 'Forgot to send the attachment. Sending now.' -Attachments .\data.csv -Priority High -DeliveryNotificationOption OnSuccess, OnFailure -SmtpServer 'smtp.fabrikam.com'
it works great, except sometimes when a log file fails to get created, thus no attachment, Send-MailMessage fails to send an email because attachment is not there.
how can i keep the -attachment switch as part of Send-MailMessage and still send email even if somehow the attachment fails?
something like this: -Attachments (mandatory=$false)$attachment

Although I agree with avic that using splatting is the way to go with cmdlets like Send-MailMessage that use a lot of parameters, there may also be another way, keeping your format sort-of intact.
The -Attachments parameter is of type string[] (an array of file names) and what's more, it can be piped to the Send-MailMessage cmdlet. As long as it is an array, the cmdlet seems fine with it, even if the array is empty.
You could use that to change the command you have to this:
# see if the file to attach is there and if not make $attachments an empty array
if (Test-Path -Path '.\data.csv' -PathType Leaf) { $attachments = #('.\data.csv') } else { $attachments = #() }
# pipe the attachments array to the cmdlet
$attachments | Send-MailMessage -From 'User01 <user01#fabrikam.com>' -To 'User02 <user02#fabrikam.com>', 'User03 <user03#fabrikam.com>' -Subject 'Sending the Attachment' -Body 'Forgot to send the attachment. Sending now.' -Priority High -DeliveryNotificationOption OnSuccess, OnFailure -SmtpServer 'smtp.fabrikam.com'
As said, personally I would prefer using splatting for this..

Related

run the powershell script so it checks and mails the faults

I am running an office 365 database of a lot of members, each in one of a bunch of groups. I used to check the groups and users by hand but there are too many members now to be able to do that efficiently. now I have found a powershell script somewhere on github but it looks as if it just does checking and displaying in powershell.
Is there a way to have a script compare the users and groups and if a user is in a group he does not belong in send a mail to the admin mail in the domain?
if this makes any sense...
You can use this piece of code to send an email in powershell.
$smtpServer = "mailserver.com"
$From = "from#mailserver.com"
$To = "to#example.com"
$Subject = "example"
$body = "test"
send-mailmessage -to $To -from $From -subject $Subject -SmtpServer $smtpServer -Body $body -BodyAsHtml -Port 25

$Env:ComputerName doesnt work with powershell Send-MailMessage in batch file

After a lot of errors and edits I got the Send-MailMessage to work through a command prompt. Below iteration sends out the emails perfect.
powershell Send-MailMessage -From " `<user#domain>`" -To " `<user#domain.com>`" -Subject 'Some subject goes here' -Body 'Some body with alert regarding Host: $env:computername. List of deleted files is attached.' -Attachments 'C:\somefile.txt' -Priority High -dno onSuccess, onFailure -SmtpServer 'smtp.domain.com'
However, this does not fetch the computername in the body. I have tried running this command in powershell directly and it works with the computername variable in body.
To get it to simply send out mails, I have already tried doing
powershell -command "command" or powershell -command "{command} or
powershell -command "& {command}" and so on and it doesnt even send
out emails.
As I am now successful sending out emails, I need to have the Computername inside the body text.
Use double quotes around the argument value to have variables contained expanded.
I.e.:
-Body "Some body with alert regarding Host: **$env:computername**. ..."
Relevant reading.
Your command line in the question and your own answer relies on the fact that powershell currently has the default (position 0) argument -Command,
but as this changes from PowerShell 6.0.0beta3 on to -File
you should explicitly use at least -C as the shortest
abbreviviation for -Command.
to speed up execution I'd use the additionl parameters -NoProfile or short -NoP and -NonInteractive or -NonI
to stop cmd from trying to interpret any parameters/arguments you should double quote them all - and escape any necessary inner double quotes with a backslash \" while also replacing double quotes with single ones if ever possible.
So I'd suggest:
powershell -NoP -NonI -C "Send-MailMessage -From \"SomeWeb-Prod#domain.com\" -To \"fromuser#domain.com\" -Subject 'Some notification for SomeWeb-Prod' -Body 'Some Alert for Host: %computername% with IP: %NetworkIP% at %time%. details in attached file.' -Attachments 'C:\somefile.txt' -Priority High -dno onFailure -SmtpServer 'smtp.domain.com'"
Or, (as you partly discovered yourself):
powershell -NoP -NonI -C "Send-MailMessage -From 'SomeWeb-Prod#domain.com' -To 'fromuser#domain.com' -Subject 'Some notification for SomeWeb-Prod' -Body 'Some Alert for Host: %computername% with IP: %NetworkIP% at %time%. details in attached file.' -Attachments 'C:\somefile.txt' -Priority High -dno onFailure -SmtpServer 'smtp.domain.com'"
"$env:computername" doesnot work for me. It simply prints it as $env:computername
%computername% worked.
Here's what's working for me right now.
powershell Send-MailMessage -From " `<user#domain.com>`" -To " `<user#domain.com>`" -Subject 'Some subject goes here' -Body 'Some body with alert regarding Host: %computername%. Some file is attached.' -Attachments 'C:\somefile.txt' -Priority High -dno onSuccess, onFailure -SmtpServer 'smtp.domain.com'
Update:
The above command worked on Win7 fine, but gave errors on server 2012. Finally this is what worked on win 2012
powershell "Send-MailMessage -From "SomeWeb-Prod#domain.com" -To "fromuser#domain.com" -Subject 'Some notification for SomeWeb-Prod' -Body 'Some Alert for Host: %computername% with IP: %NetworkIP% at %time%. details in attached file.' -Attachments 'C:\somefile.txt' -Priority High -dno onFailure -SmtpServer 'smtp.domain.com'"
It works for me, by using double quotes around variables.
I am using batch script to call powershell Send-MailMessage
Batch Script:send_email.bat
C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe -windowstyle hidden -command 'E:\path\send_email.ps1
Pwershell Script send_email.ps1
Send-MailMessage -From "noreply#$env:computername" -To '<target_email#example.com>' -Subject 'Blah Blah' -SmtpServer 'smtp.domain.com' -Attachments 'E:\path\file.log' -BODY "Blah Blah on Host: $env:computername "

Not receiving email sent using powershell command

Send-MailMessage -SmtpServer "smtp.com.au" -From "me#me.com" -To "you#you.com" -Subject "Testing" -Attachments "\\Test\archive.zip" -Body "attached"
I am using the above command to email a zip file but i don't see anything in the To (you#you.com) mailbox.
The command runs successfully without any errors.
I think the problem is in your function call. You miss a lot of parameters. Take a look on my working gmail example:
$password = ConvertTo-SecureString "123456789" -AsPlainText -Force
$emailCredentials = New-Object pscredential ("from#gmail.com", $password)
try {
Send-MailMessage -From "from#gmail.com" -To "to#to.com" -Subject "subject" -Body "body" -SmtpServer "smtp.gmail.com" -Port 587 -Credential $emailCredentials -Encoding UTF8 -UseSsl -ErrorAction Stop
}
catch {
echo $error[0]
}
There is no -Credential parameter in your call, and I'm almost sure, that's the problem. Also your smtp server may have this protocol on different port, this is what -Port is for. And finally -UseSsl, if smtp server is encrypting mails, then without this switch, your emails will be not send. -Encoding UTF8 is just for regional chars.
Check your $error[0], it may tell you, where the problem is. Check what is happening on your -From email. On gmail you can see sometimes auto-repiles, with error description.
I'm sorry for not giving you simple solution, but I don't have enough informations, to find it.
Ok guys i have an update:
My command mentioned above is working absolutely fine. IT team has told me that we had issues with our SMTP the other day (When i had reported this issue) the emails eventually did come in (too late). I have tested the same this morning and it seems to be fine so a big thanks to all for your support.
I have got another question but i will post it separately.

Not able to fetch recipients from a text file send-mailMessage Powershell

This is ridiculous.
I am trying to send mail in powershell using the below command
$users= get-content "somepath/sometxt.txt"
Send-MailMessage -To $users -from $fromemail -SmtpServer $smtp
The sometxt.txt contains recipients as below :-
The above code works smoothly when I run on one computer. It takes the users from the sometxt.txt file and sends the mail.
But when I ran the same code on another computer.
It said
parameter -to with aruguement $users is empty or null.
I don't have a screenshot of the error as it is on my office network.
Crazy part being, that when I write host $users just before the sendmail command it gives me the names confirming that it is not null/empty as below:-
$users= get-content "somepath/sometxt.txt"
write-host $users
Send-MailMessage -To $users -from $fromemail -SmtpServer $smtp
Result:-
user1#domain1.com user2#domain2.com send-mailmessage falied as -to
parameter with $users aruguement is null or empty
How can this be null or empty if it is printing the contents of the file ??
Could anyone help figure out why this is happening . Also let me know an alternative to fix this and send the mail out.

Email credentials when using send-mailmessage command

I have searched through many many forums and they do explain how to do this but the technical language is just too difficult to understand as I'm very new to powershell. I would like this explained to me step by step (baby steps). I would like to run this powershell command in a batch file (.bat). I have a batch file that does robocopy backups weekly and I want the batch file to send me a email when the backup is complete. The only issue I have is the credentials, I get a pop-up box asking for the user name and password. When I eneter this information the email will send successfully. Here is what I have;
Using: powershell V2.0 Windows 7 Ultimate
Powershell -command send-mailmessage -to emailadress#provider.com -from emailaddress#provider.com -smtp smtp.broadband.provider.com -usessl -subject 'backup complete'
$from = "example#mail.com"
$to = "example#mail.com"
$smtp = "smtpAddress.com"
$sub = "hi"
$body = "test mail"
$secpasswd = ConvertTo-SecureString "yourpassword" -AsPlainText -Force
$mycreds = New-Object System.Management.Automation.PSCredential($from, $secpasswd)
Send-MailMessage -To $to -From $from -Subject $sub -Body $body -Credential $mycreds -SmtpServer $smtp -DeliveryNotificationOption Never -BodyAsHtml
You could pass the credential object in your same command - which would avoid the popup:
Powershell -Command 'Send-MailMessage -to "emailadress#provider.com" -from "emailaddress#provider.com" -smtp "smtp.broadband.provider.com" -usessl -subject "backup complete" -credential (new-object System.Net.NetworkCredential("user","pass","domain"))'
I'd recommend storing the username/password in a somewhat more safer format, but this should do your trick.
I'm not sure you can do SMTP authentication using the send-mailmessage command. But, you can send a message through an SMTP server that requires authentication using the Net.Mail.SmtpClient object and the System.Net.Mail.MailMessage object. See How to pass credentials to the Send-MailMessage command for sending emails for a good example.
look at the last exemple of send-mailmessage helppage
you will see you can pass credential whith the parameter -credential domain01\admin01
look here Using PowerShell credentials without being prompted for a password if you dont want any prompt (save your cred in a text file)