Send a file to an email address using a bat file without exposing the email info?

35,528

If you need to send an email—even with an attachment—by having a PowerShell script with the logic that builds and sends the email, you can execute it via a batch script passing sensitive values in as arguments rather than hard-coding sensitive values into the script logic.

The PowerShell script logic can accept arguments such as the Gmail local mailbox username, the password to authenticate to send email, and anything else you don't want hard-coded in the script.

  • PowerShell Args

    Within a script or function you can refer to unnamed arguments using the $args array, for example passing all the arguments through to a cmdlet. You can also refer to specific arguments by their position:

    "First argument is " + $Args[0]"

    "Second argument is " + $Args[1]"

You can also put logic in the batch script so it too has arguments you can pass sensitive values to it at execution time, and use argument placeholders rather than hard-coding sensitive values.

  • Batch Args

    You can get the value of any argument using a % followed by it's numerical position on the command line. The first item passed is always %1 the second item is always %2 and so on

    %* in a batch script refers to all the arguments (e.g. %1 %2 %3 %4 %5 ...%255) only arguments %1 to %9 can be referenced by number.

This way if the scripts are opened, the sensitive values you need to protect will not be exposed or hard-coded into the script logic for anyone to see who may have read access to the script.


Important Note: There's a section at the bottom of each PowerShell script example name Batch Execute Script that has the logic to use from the batch script to execute or whatever so you will use pass the username, password, and/or attachment full path as the appropriate arguments to the batch script i.e. sendemail.bat "<GmailAccountName>" "<GmailPassword>" "<FullPathAttachment>"

PowerShell Script (no attachment)

$Username      = $args[0]
$EmailPassword = $args[1]

$Username = $Username
$EmailTo = "[email protected]" 
$EmailFrom = "[email protected]"
$Subject = "Email Subject"
$Body = "Email Body"
$SMTPServer = "smtp.gmail.com" 
$SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom, $EmailTo, $Subject, $Body)
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) 
$SMTPClient.EnableSsl = $true 
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential($Username, $EmailPassword); 
$SMTPClient.Send($SMTPMessage)

Batch Execute Script

SET GmailAccount=%~1
SET GmailPassword=%~2
SET PowerShellDir=C:\Windows\System32\WindowsPowerShell\v1.0
CD /D "%PowerShellDir%"
Powershell -ExecutionPolicy Bypass -Command "& 'C:\Scripts\SendEmail.ps1' '%GmailAccount%' '%GmailPassword%'"

PowerShell Script (with attachment)

$Username      = $args[0]
$EmailPassword = $args[1]
$Attachment    = $args[2]

$Username = $Username
$EmailTo = "[email protected]" 
$EmailFrom = "[email protected]"
$Subject = "Email Subject"
$Body = "Email Body"
$SMTPServer = "smtp.gmail.com" 
$SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom, $EmailTo, $Subject, $Body)
$Attachment = New-Object System.Net.Mail.Attachment($Attachment)
$SMTPMessage.Attachments.Add($Attachment)
$SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587) 
$SMTPClient.EnableSsl = $true 
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential($Username, $EmailPassword); 
$SMTPClient.Send($SMTPMessage)

Batch Execute Script

SET GmailAccount=%~1
SET GmailPassword=%~2
SET Attachment=%~3
SET PowerShellDir=C:\Windows\System32\WindowsPowerShell\v1.0
CD /D "%PowerShellDir%" 
Powershell -ExecutionPolicy Bypass -Command "& 'C:\Scripts\SendEmail.ps1' '%GmailAccount%' '%GmailPassword%' '%Attachment%'"

Batch Script (dynamic)

Here's an all-in-one dynamic batch script that you just pass the Gmail account username, the Gmail account password, and the full path to the attachment.

@ECHO OFF

SET GmailAccount=%~1
SET GmailPassword=%~2
SET Attachment=%~3

CALL :PowerShell
CD /D "%PowerShellDir%"
Powershell -ExecutionPolicy Bypass -Command "& '%PSScript%' '%GmailAccount%' '%GmailPassword%' '%Attachment%'"
EXIT

:PowerShell
SET PowerShellDir=C:\Windows\System32\WindowsPowerShell\v1.0
SET PSScript=%temp%\~tmpSendeMail.ps1
IF EXIST "%PSScript%" DEL /Q /F "%PSScript%"

ECHO $Username      = $args[0]>> "%PSScript%"
ECHO $EmailPassword = $args[1]>> "%PSScript%"
ECHO $Attachment    = $args[2]>> "%PSScript%"
ECHO                          >> "%PSScript%"
ECHO $Username    = $Username                 >> "%PSScript%"
ECHO $EmailTo     = "[email protected]" >> "%PSScript%"
ECHO $EmailFrom   = "[email protected]" >> "%PSScript%"
ECHO $Subject     = "Email Subject"           >> "%PSScript%"
ECHO $Body        = "Email Body"              >> "%PSScript%"
ECHO $SMTPServer  = "smtp.gmail.com"          >> "%PSScript%"
ECHO $SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom, $EmailTo, $Subject, $Body) >> "%PSScript%"
ECHO $Attachment  = New-Object System.Net.Mail.Attachment($Attachment)                            >> "%PSScript%"
ECHO $SMTPMessage.Attachments.Add($Attachment)                                                    >> "%PSScript%"
ECHO $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)                               >> "%PSScript%"
ECHO $SMTPClient.EnableSsl = $true                                                                >> "%PSScript%"
ECHO $SMTPClient.Credentials = New-Object System.Net.NetworkCredential($Username, $EmailPassword) >> "%PSScript%"
ECHO $SMTPClient.Send($SMTPMessage)                                                               >> "%PSScript%"
GOTO :EOF

You execute the batch script like so. . .

 sendemail.bat "<GmailAccountName>" "<GmailPassword>" "<FullPathAttachment>"

enter image description here


Batch Script (static and self-deleting)

This script will have the hard-coded values set in the variables of GmailAccount=, GmailPassword=, and Attachment= but once executed, it will delete [itself] the script entirely via "%~FN0" where the 0 is the script itself. This means that you will want to be sure you copy this script and then run the copy only from the machine(s) you'll execute where you don't want this information exposed.

@ECHO OFF

SET GmailAccount=<GmailAccountName>
SET GmailPassword=<GmailPassword>
SET Attachment=<FullAttachmentPath>

CALL :PowerShell
CD /D "%PowerShellDir%"
Powershell -ExecutionPolicy Bypass -Command "& '%PSScript%' '%GmailAccount%' '%GmailPassword%' '%Attachment%'"
IF EXIST "%~FN0" DEL /Q /F "%~FN0"
EXIT

:PowerShell
SET PowerShellDir=C:\Windows\System32\WindowsPowerShell\v1.0
SET PSScript=%temp%\~tmpSendeMail.ps1
IF EXIST "%PSScript%" DEL /Q /F "%PSScript%"

ECHO $Username      = $args[0]>> "%PSScript%"
ECHO $EmailPassword = $args[1]>> "%PSScript%"
ECHO $Attachment    = $args[2]>> "%PSScript%"
ECHO                          >> "%PSScript%"
ECHO $Username    = $Username                 >> "%PSScript%"
ECHO $EmailTo     = "[email protected]" >> "%PSScript%"
ECHO $EmailFrom   = "[email protected]" >> "%PSScript%"
ECHO $Subject     = "Email Subject"           >> "%PSScript%"
ECHO $Body        = "Email Body"              >> "%PSScript%"
ECHO $SMTPServer  = "smtp.gmail.com"          >> "%PSScript%"
ECHO $SMTPMessage = New-Object System.Net.Mail.MailMessage($EmailFrom, $EmailTo, $Subject, $Body) >> "%PSScript%"
ECHO $Attachment  = New-Object System.Net.Mail.Attachment($Attachment)                            >> "%PSScript%"
ECHO $SMTPMessage.Attachments.Add($Attachment)                                                    >> "%PSScript%"
ECHO $SMTPClient = New-Object Net.Mail.SmtpClient($SmtpServer, 587)                               >> "%PSScript%"
ECHO $SMTPClient.EnableSsl = $true                                                                >> "%PSScript%"
ECHO $SMTPClient.Credentials = New-Object System.Net.NetworkCredential($Username, $EmailPassword) >> "%PSScript%"
ECHO $SMTPClient.Send($SMTPMessage)                                                               >> "%PSScript%"
GOTO :EOF

Further Resources

Share:
35,528

Related videos on Youtube

mina nageh
Author by

mina nageh

Updated on September 18, 2022

Comments

  • mina nageh
    mina nageh over 1 year

    I want to send a file to my Gmail account via a bat file and encrypt my email info in that bat file so that if someone opens the bat file they cannot get the email information from it.

    Logic such as:

    1. check if the internet is working properly

      • if ok send the file and then remove the bat file
    2. check if the internet is working properly

      • if no Schedule it to do it later or add it to the start up

      • when done remove it from the Schedule or the start up !

    • K7AAY
      K7AAY over 5 years
      To send an email through Gmail without using a web browser, you need an SMTP based email client like Outlook or Mozilla Thunderbird. Do you have one installed? If so, which?
    • mina nageh
      mina nageh over 5 years
      "Do you have one installed?". No i don't ... . is there any alternative email service that is ready to go (portable) like it doesn't need any additional soft installed?!
    • fixer1234
      fixer1234 over 5 years
      @PimpJuiceIT, close voters' perception of "too broad" is influenced by the presence of a good, simple answer that demonstrates that it isn't so broad. Go for it.
    • Vomit IT - Chunky Mess Style
      Vomit IT - Chunky Mess Style over 5 years
      @fixer1234 .... So much for "simple" answer now, right!!
    • fixer1234
      fixer1234 over 5 years
      @PimpJuiceIT, yeah, nobody in his right mind would answer a question that requires developing an app to solve the problem, so it's good that you demonstrated a trivial solution. I had to vote to reopen to ensure that this doesn't get deleted. Maybe it will even attract another answer. BTW your answer is a bit brief. You might want to beef it up by adding the meat from the bare links at the end. ONLY KIDDING!
    • mina nageh
      mina nageh over 5 years
      @pimp juice IT Hi... Sorry for asking more than it's Required..... Is there an quick way/method/article to encrypt the password and the username instead of using it One command line like creat another bat file that Decode the password and the username then use them to run the Batch Script (dynamic) ..... Again sorry for asking too much.... I may start another thread if you prefer.
    • mina nageh
      mina nageh over 5 years
      ok i am not In a hurry......take your time 😁 thanks,
    • mina nageh
      mina nageh over 5 years
      Yes what is it!!
    • Vomit IT - Chunky Mess Style
      Vomit IT - Chunky Mess Style over 5 years
      Mina - Just submit another question and ask for that based off the below logic as what you are using, so how can you do this with this logic here or something similar, etc.
    • mina nageh
      mina nageh over 5 years
  • Paul Jones
    Paul Jones almost 5 years
    I'm using the Batch Script (static and self-deleting) from this answer, and I'm able to send an attachment as a CSV and also have the same CSV file be read raw as the body of the email so the user can see the content on their phone with out opening the CSV file but has the option to open the attachment in Excel. The only thing I can't figure out how to do is ADD additional recipients. I've tried using a recipients string [string[]]$recipients = it seems to error out with this script. I've tried just adding to the existing line. `ECHO $EmailTo = "[email protected]", "emailaddress2@domai
  • Thalys
    Thalys almost 5 years
    erf. post was too long for a comment i.stack.imgur.com/Fx4Oh.png original post with some edits for reference
  • Vomit IT - Chunky Mess Style
    Vomit IT - Chunky Mess Style almost 5 years
    @PaulJones ... I'll need to check and test to confirm but I think it is as simple as one of these two examples.... 1..... $EmailTo = "[email protected],[email protected],[email protected]" or perhaps with a semicolon separator as 2.....$EmailTo = "[email protected];[email protected];[email protected]"... Try one of those two and let me know. If that doesn't work, I'll have to check later on a machine I have this logic running.