Powershell Script - SendMail [Detailed Errors] - powershell

I'm testing with a PowerShell script (where I'm testing copy and paste over FTPs using WinSCP), and in parallel I'm configuring the following code for sending mail in case of error on any of the put tasks, get....
This is the code:
#echo off
set WINSCP_LOG=C:\Users\Administrator\Desktop\WinSCP.log
rem Run WinSCP script
"C:\Program Files (x86)\WinSCP\WinSCP.com" ^
/log=%WINSCP_LOG% /ini=nul ^
/command ^
"open sftp://example:%%r%%21#he.example.es/ -hostkey=""ssh-rsa 2048 pRzlrJ27Zasd7"09ยก^
"lcd C:\Users\Administrator\Desktop" ^
"cd /ftp-files/O1" ^
"put examplefile.txt" ^
"exit
rem Check WinSCP result and prepare the email message
if %ERRORLEVEL% equ 0 (
set WINSCP_SUBJECT=Success
set WINSCP_MESSAGE=The files were uploaded successfully.
set WINSCP_CODE=0
) else (
set WINSCP_SUBJECT=Error
set WINSCP_MESSAGE=Error uploading files, see attached log.
set WINSCP_CODE=1
)
echo %WINSCP_SUBJECT%
echo %WINSCP_MESSAGE%
rem Send the email message
set SMTP_FROM=no_reply#example.es
set SMTP_TO=bztruster#example.com
set SMTP_SERVER=smtp.office365.com
set SMTP_USERNAME=no_reply#example.es
set SMTP_PASSWORD=Asfaj23##
if exist "%WINSCP_LOG%" set ATTACHMENT=-Attachments '%WINSCP_LOG%'
powershell -ExecutionPolicy Bypass Send-MailMessage ^
-From %SMTP_FROM% -To %SMTP_TO% -Subject '%WINSCP_SUBJECT%' -Body '%WINSCP_MESSAGE%' ^
%ATTACHMENT% -SmtpServer %SMTP_SERVER% -UseSsl ^
-Credential (New-Object System.Management.Automation.PSCredential ^
('%SMTP_USERNAME%', (ConvertTo-SecureString '%SMTP_PASSWORD%' -AsPlainText -Force)))
exit /b %WINSCP_CODE%
Where or how could I get more context on the errors in order to know the reason for the failure within the received mail?
Thanks for your help!

You are sending the wrong parameters to powershell.exe binary. Run the following to understand the parameters accepted and the syntax needed:
powershell.exe /?
For your particular needs, you can use the parameter -Command, e.g:
powershell -ExecutionPolicy Bypass -Command {Send-MailMessage ^
-From %SMTP_FROM% -To %SMTP_TO% -Subject '%WINSCP_SUBJECT%' -Body '%WINSCP_MESSAGE%' ^
%ATTACHMENT% -SmtpServer %SMTP_SERVER% -UseSsl ^
-Credential (New-Object System.Management.Automation.PSCredential ^
('%SMTP_USERNAME%', (ConvertTo-SecureString '%SMTP_PASSWORD%' -AsPlainText -Force)))}

Related

Saving powershell command output into a file

I want to save the following powershell command into a file.ps1 from cmd:
powershell send-mailmessage -to "alerts#address.com" -from "info#address.com" -subject "Virus alert" -body "Cryptolocker variant detected on $env:computername " -smtp "companyname-com.mail.protection.outlook.com"
How can I do that?
try this:
echo <your_command> > file.ps1
echo prints whatever you give it (in this case your command) to the standard output (usually the console) and > redirects the string (your command) from the standard output to the file file.ps1
This can be written to a file by redirecting stdout of the ECHO command.
ECHO>file.ps1 powershell send-mailmessage ^
-to "alerts#address.com" ^
-from "info#address.com" ^
-subject "Virus alert" ^
-body "Cryptolocker variant detected on $env:computername " ^
-smtp "companyname-com.mail.protection.outlook.com"
If you are writing to a .ps1 file, why do you need to start another instance of PowerShell? To run the PowerShell script, leave the powershell command out and just use:
powershell -NoLogo -NoProfile -File file.ps1

$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 "

Send-Mailmessage from command with variable body

Below script should check if files have been created today and send an email to one of our users.
The problem is that I can't send more than one value in the body. I need to remove "File" from body to get the email out. Also there is one email for each file. I would rewrite it to send one mail with all files listed with dates.
#echo off
setlocal enabledelayedexpansion
echo Files changed today %date%
FOR %%A IN (*.*) DO (
set tf=%%~tA
set fd=!tf:~0,10!
if !fd!==%date% (
powershell -ExecutionPolicy ByPass -Command Send-MailMessage ^
-SmtpServer this.server.com ^
-To my#email.com ^
-From noreply#possibly.fake ^
-Subject Updated^
-Body "%%A File"
)
)
So i actually got this working with some heavy googeling (even went to page 3 at one point)
This is my "Check files in folder and send email with whats new and whats old"
#echo off
setlocal enabledelayedexpansion
echo Files changed today %date%
FOR %%A IN (*.*) DO (
set tf=%%~tA
set fd=!tf:~0,10!
if !fd!==%date% (
set "file=!file! <br> %%A !tf!"
)
if NOT !fd!==%date% (
set "old=!old! <br> %%A !tf!"
)
)
set "file=!file!
set "old=!old!
set "today=<b>New today:</b> %file%"
set "older=<b>Older files</b> %old%"
set "body=!today! <br><br> !older!"
powershell -ExecutionPolicy ByPass -Command Send-MailMessage -BodyAsHtml^
-SmtpServer yourserver.com^
-To your#mail.com ^
-From noreply#possibly.fake ^
-Subject Updated^
-Body '!body!'
[Im]pure PowerShell solution without a batch file, save it to a file with .ps1 extension:
$modifiedToday = gci | ?{ $_.LastWriteTime.Date -eq (Get-Date).Date }
Send-MailMessage `
-SmtpServer this.server.com `
-To my#email.com `
-From noreply#possibly.fake `
-Subject Updated `
-Body ($modifiedToday -join "`n")
Impure because it uses abbreviated aliases like gci and ?{ instead of Get-ChildItem and Where-Object as I really don't like the verboseness of officially recommended PowerShell code style. As someone who doesn't mind writing cryptic batch-file code the OP might appreciate that as well.

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)

Send-MailMessage parameter from command prompt

I'm trying to run Send-MailMessage directly from a command window.
C:\>powershell Send-MailMessage -from 'test#test.com' -to "target#test.com" -subject 'test' -smtpServer "srv.server.com" -Attachment c:\Test\log.txt -body "Test message"
This fails with
Send-MailMessage : A positional parameter cannot be found that accepts argument 'from'.
I'm sure it's possible. I just dont know how to pass the arguments correctly.
If you're running this from cmd.exe then you need to check out the PowerShell.exe help:
C:\> poweshell.exe /?
Specifically you should invoke the command like so:
C:\> powershell -command "& {Send-MailMessage -from 'test#test.com' ... }"
Watch out for the quote characters. In general use double quotes around the whole -command parameter value for cmd.exe interpret. Inside the command use single quoted strings unless you need variable expansion inside the string.