-1

I need to send an email through outlook that already has all the details filled in (eg. subject, body, etc), except it has to be done through some sort of script. This can be any script that works on Windows 10.

Essentially, all I need the script to do is 'click' send on the email. Is there anyway to do this, or is this impossible. The preferable script types are .bat, .cmd, and .vbs. I don't want to use any 3rd party software.

This is what I currently have in my batch file, again I just need the script to send the email:

cd C:\Program Files (x86)\Microsoft Office\root\Office16 & start outlook.exe /c ipm.note /m "someone@gmail.com?subject=subject here"

I will be filling out the body of the email by another script, which I have managed to do. If you have any ideas about alternative options, still reply, it might be useful.

Here is an image of what I need to be sent by a script file:

Thanks in advance.

Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
  • Why not just use `powershell` to send the email which you can even run from a `btach-file` then you really only need one script without GUI interactions.. See the answer of mine [here](https://stackoverflow.com/questions/58373405/how-to-send-email-to-distribution-list-in-outlook-using-task-scheduler) as an exmaple. – Gerhard Apr 10 '22 at 11:11
  • When I try your script (the one with the added attachment), and have filled out all the details as desired, the output is this: cmdlet Send-MailMessage at command pipeline position 1 Supply values for the following parameters: From: Have I done something wrong? – Agent 3 6 9 Apr 10 '22 at 12:51
  • It says that you have not defined paramaters. So you must have done something wrong. – Gerhard Apr 10 '22 at 13:38

1 Answers1

1

Powershell is a scripting environment for Microsoft Windows. Scripts are saved as plain text files with the .ps1 extension. You can create a file in Windows Powershell ISE or a text editor. Here is the sample script which can be used to get the job done:

#create COM object named Outlook
$Outlook = New-Object -ComObject Outlook.Application

#create Outlook MailItem named Mail using CreateItem() method
$Mail = $Outlook.CreateItem(0)

#add properties as desired
$Mail.To = "recipient@test.com"
$Mail.Subject = "subject" 
$Mail.HTMLBody = "testing"

#send message
$Mail.Send()

#quit and cleanup
$Outlook.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($Outlook) | Out-Null

But in the real world the code can be more complex:

Add-Type -assembly "Microsoft.Office.Interop.Outlook"
add-type -assembly "System.Runtime.Interopservices"
try
{
    $outlook = [Runtime.Interopservices.Marshal]::GetActiveObject('Outlook.Application')
    $outlookWasAlreadyRunning = $true
}
catch
{
    try
    {
        $Outlook = New-Object -comobject Outlook.Application
        $outlookWasAlreadyRunning = $false
    }
    catch
    {
        write-host "You must exit Outlook first."
        exit
    }
}
$namespace = $Outlook.GetNameSpace("MAPI")

See Outlook Email Automation with PowerShell for more information.


Note, you could run a powershell script from a batch file or command prompt (cmd.exe):

powershell -noexit -File "C:\my_path\MYSCRIPT.ps1"

This is a method which Microsoft does when we right click on a ps1 script and click on "Run with PowerShell" :

"C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe" "-Command" "if((Get-ExecutionPolicy ) -ne 'AllSigned') { Set-ExecutionPolicy -Scope Process Bypass }; & 'C:\Users\USERNAME\Desktop\MYSCRIPT.ps1'"
Eugene Astafiev
  • 47,483
  • 3
  • 24
  • 45
  • Unfortunately, the shortcut-menu command provided by Microsoft that you quote breaks with paths that have embedded `'` chars.; when it works, it does not keep the session open and it prompts for confirmation to override the execution policy (unless it is set to `AllSigned`, in which case no override is attempted). – mklement0 Apr 10 '22 at 13:32
  • Re Windows PowerShell ISE: It is [no longer actively developed](https://docs.microsoft.com/en-us/powershell/scripting/components/ise/introducing-the-windows-powershell-ise#support) and [there are reasons not to use it](https://stackoverflow.com/a/57134096/45375) (bottom section), notably not being able to run PowerShell (Core) 6+. The actively developed, cross-platform editor that offers the best PowerShell development experience is [Visual Studio Code](https://code.visualstudio.com/) with its [PowerShell extension](https://marketplace.visualstudio.com/items?itemName=ms-vscode.PowerShell). – mklement0 Apr 10 '22 at 13:33
  • 1
    @mklement0 thank you for the suggestion. I am not a PowerShell expert, but can help with automating Office applications. The Outlook object model is the same for all kind of applications. – Eugene Astafiev Apr 11 '22 at 10:40
  • See [Systematically Releasing Objects](https://learn.microsoft.com/en-us/previous-versions/office/developer/office-2007/bb623945(v=office.12)?redirectedfrom=MSDN) for more information on that. – Eugene Astafiev Apr 11 '22 at 12:27
  • 1
    Releasing the main object is not enough, agree. – Eugene Astafiev Apr 11 '22 at 14:08
  • Indeed; perhaps my original comment was a bit ambiguous, so I've removed it. Let me attempt a summary in the next comment, with [this answer](https://stackoverflow.com/a/55423449/45375) telling the story in more detail. Unless I'm missing something, the implication is that your first code snippet is missing `[System.Runtime.Interopservices.Marshal]::ReleaseComObject($Mail)` – mklement0 Apr 11 '22 at 14:44
  • Releasing references to COM objects for out-of-process COM servers such as `Outlook.Application` requires calling their `.Quit()` method first. However, the process doesn't exit until all references to the application object _as well as to elements of its document model_ have been released. While you _can_ call `[Runtime.InteropServices.Marshal]::ReleaseComObject()` on every reference, it is simpler to execute all COM operations in a _child scope_ (`& { ... }`) so that when its variables go out of scope, releasing happens automatically. You can speed up release by calling `[GC]::Collect()`. – mklement0 Apr 11 '22 at 14:45
  • Using your first example, how would the script be modified so that an attachment could be added to the email? I'm guessing it would be along the lines of ```$Mail.Attachment = "C:\mypath\test.txt"``` – Agent 3 6 9 Apr 12 '22 at 04:41