I use Outlook 2010 and Powershell 2.0.
I want send a Outlook message, and delay delivery programmatically of a message using Powershell.
How can I create a new Outlook email and immediately defer delivery?
If you try this:
$ol = New-Object -comObject Outlook.Application
$mail = $ol.CreateItem(0)
$mail | Get-Member
you'll get a list of all methods/properties available on the mail object.
One property is DeferredDeliveryTime. You can set it like this:
#Stay in the outbox until this date and time
$mail.DeferredDeliveryTime = "11/2/2013 10:50:00 AM"
Or:
#Wait 10 minutes before sending mail
$date = Get-Date
$date = $date.AddMinutes(10)
$mail.DeferredDeliveryTime = $date
Solution:
$ol = New-Object -comObject Outlook.Application
$ns = $ol.GetNameSpace("MAPI")
# call the save method yo dave the email in the drafts folder
$mail = $ol.CreateItem(0)
$null = $Mail.Recipients.Add("xxxx#serverdomain.es")
$Mail.Subject = "PS1 Script TestMail"
$Mail.Body = " Test Mail "
$date = Get-Date
$date = $date.AddMinutes(2)
$Mail.DeferredDeliveryTime = $date #"2/11/2013 10:50:00 AM"
$Mail.save()
# get it back from drafts and update the body
$drafts = $ns.GetDefaultFolder($olFolderDrafts)
$draft = $drafts.Items | where {$_.subject -eq 'PS1 Script TestMail'}
$draft.body += "`n foo bar"
$draft.save()
$inspector = $draft.GetInspector
$inspector.Display()
# send the message
$draft.Send()
References:
Create Outlook email draft using PowerShell
http://office.microsoft.com/en-us/outlook-help/delay-or-schedule-sending-email-messages-HP010355051.aspx
Update
To change default account:
$Mail.SendUsingAccount = $ol.Session.Accounts | where {$_.DisplayName -eq $FromMail}
References:
http://msmvps.com/blogs/richardsiddaway/archive/2011/08/08/outlook-sending-emails.aspx
Outlook automation - Change Sender Account
Related
For logging tasks I need to send me an email through Outlook. I wrote some code like this:
$outlook = New-Object -ComObject Outlook.Application
$namespace = $outlook.GetNameSpace("MAPI")
$olFolders = "Microsoft.Office.Interop.Outlook.olDefaultFolders" -as [type]
$InboxDef = $namespace.GetDefaultFolder($olFolders::olFolderInBox)
$InboxDef.FullFolderPath -match "^\\\\(.*)\\Inbox$" | Out-Null
$recipient = $matches[1]
$email = $outlook.CreateItem(0)
$email.To = "$recipient"
$email.Subject = "Title"
$email.Body = "Text"
$email.Send()
$Outlook.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($Outlook) | Out-Null
When I subsequently launch the Outlook client I see the email sent twice
The code looks good. One thing which is not clear enough is setting a recipient for the outgoing email:
$InboxDef.FullFolderPath -match "^\\\\(.*)\\Inbox$" | Out-Null
$recipient = $matches[1]
It is not clear what value is used in the code. To make sure the property is set correctly I'd suggest using the Recipients property of the MailItem class instead. The Recipients.Add method creates a new recipient in the Recipients collection. Then don't forget to use the Recipient.Resolve
method which attempts to resolve a Recipient object against the Address Book.
Read more about that in the article which I wrote for the technical blog, see How To: Fill TO,CC and BCC fields in Outlook programmatically.
I'm trying to create a Powershell script that gets the specific part of a text file, read it and then put it into the contents of an email and sends it. This is what I currently have:
$logs = (Get-EventLog system | where {$_.InstanceId -eq 7001 -and
$_.TimeWritten -gt (Get-Date).Adddays(-1)}).TimeWritten | Out-String
#to file
$logs | Out-File ".\Results.txt"
#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 = "SomeMailAddress.com"
$Mail.Subject = "Time"
$Mail.Body = $logs
#send message
$Mail.Send()
#quit and cleanup
$Outlook.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($Outlook) | Out-Null
I'm able to create the text file, output the data, I believe the Get-Content is getting that specific portion of time but I'm not sure how to use Set-Content and put that into the email. Any suggestions/help would be appreciated
The simplest way to send email through PowerShell is by using Send-MailMessge.
Below is how you would send using the Outlook ComOjbect.
Note: If you have to use the outlook comobject, make sure you run PowerShell and outlook the same way with the same account.
Example:
$logs = (Get-EventLog system | where {$_.InstanceId -eq 7001 -and $_.TimeWritten -gt (Get-Date).Adddays(-1)}).TimeWritten | Out-String
#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 = "jrider#yourDomain.com"
$Mail.Subject = "Time"
$Mail.Body = $logs
#send message
$Mail.Send()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($Outlook) | Out-Null
I'm trying to write a PowerShell script which parses a list of email addresses and send a mail to them.
The file is formatted this way:
a.a#domain.com
b.b#domain.com
c.c#domain.com
...
I figured something like:
$recipients = Get-Content -Path MY_FILE.txt
$outlook = New-Object -ComObject Outlook.Application
$mail = $Outlook.CreateItem(0)
$mail.To = $recipients # here's the problem
$mail.Subject = "MY_SUBJECT"
$mail.HTMLBody = "MY_HTML_BODY"
$mail.Send()
My problem, as you can see is: how can I assign the addresses in $recipients to $mail.To?
When in doubt, read the documentation:
MailItem.To Property (Outlook)
Returns or sets a semicolon-delimited String list of display names for the To recipients for the Outlook item.
Read/write.
[...]
Remarks
This property contains the display names only. The To property corresponds to the MAPI property PidTagDisplayTo. The Recipients collection should be used to modify this property.
Emphasis mine.
To send one mail to all recipients change this line:
$mail.To = $recipients
into this:
foreach ($addr in $recipients) {
$mail.Recipients.Add($addr)
}
and the code should do what you want.
If you want to send every address in your file a separate email do it this way:
$recipients = Get-Content -Path MY_FILE.txt
$outlook = New-Object -ComObject Outlook.Application
ForEach ($recipient in $recipients) {
$mail = $Outlook.CreateItem(0)
$mail.To = $recipient
$mail.Subject = "MY_SUBJECT"
$mail.HTMLBody = "MY_HTML_BODY"
$mail.Send()
}
Also make sure you close the COM Object by adding the following to the end of your file:
$outlook.Quit()
[System.Runtime.Interopservices.Marshal]::ReleaseComObject($outlook) | Out-Null
You could try something like this:
$file = "$PSScriptRoot\MY_FILE.txt"
# Add a List of recipients
$to = #()
foreach ($email in (Get-Content $file)) {
$to += "$email;"
}
Write-Host "Complete recipient-list: $to"
$outlook = New-Object -ComObject Outlook.Application
$mail = $Outlook.CreateItem(0)
$mail.To = "$to"
$mail.Subject = "MY_SUBJECT"
$mail.HTMLBody = "MY_HTML_BODY"
$mail.Send()
I'm currently working on a PowerShell script that need to extract all mail messages from a specific mailbox as .eml or .msg files and save them on a backup server. I'm using powershell version 5 with the Exchange 2010 management console module (EWS).
Currently, my script is able to access all messages in the inbox folder with their properties such as Body, Subject, attachments and so on. However, I couldn't find an easy way or method to export the messages (with their attachment(s)). So my question is, does EWS in Exchange 2010 provide a method to extract/save a message from a mailbox?
Here's my script:
add-pssnapin Microsoft.Exchange.Management.PowerShell.E2010
$dllpath = "C:\Program Files\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll"
[void][Reflection.Assembly]::LoadFile($dllpath)
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP1)
$windowsIdentity = [System.Security.Principal.WindowsIdentity]::GetCurrent()
$sidbind = "LDAP://<SID=" + $windowsIdentity.user.Value.ToString() + ">"
$aceuser = [ADSI]$sidbind
$service.AutodiscoverUrl($aceuser.mail.ToString())
$MailboxName = get-mailbox -Identity myMailBox#myWorkPlace.com
$folderidcnt = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox,$MailboxName.PrimarySmtpAddress.ToString())
$rootfolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service, $folderidcnt)
$offset = 0;
$view = new-object Microsoft.Exchange.WebServices.Data.ItemView(10000, $offset)
$response = $service.LoadPropertiesForItems($results, [Microsoft.Exchange.WebServices.Data.PropertySet]::FirstClassProperties)
foreach ($mail in $results){
if ($mail.ToString() -eq "Microsoft.Exchange.WebServices.Data.EmailMessage"{
**"Function to export this message an an .eml or .msg file on a remote shared folder"**
}
}
The last part of your code needs to be:
if ($mail.ToString() -eq "Microsoft.Exchange.WebServices.Data.EmailMessage") {
$mailSubject = $mail.Subject
$mailProps = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.ItemSchema]::MimeContent)
$mail.Load($mailProps)
#TODO: clean up $mailSubject so it's filesystem friendly
$fStream = New-Object System.IO.FileStream("C:\Temp\$mailSubject.eml", [System.IO.FileMode]::Create)
$fStream.Write($mail.MimeContent.Content, 0, $mail.MimeContent.Content.Length)
$fStream.Close()
}
$mailSubject = $mail.Subject grabs the subject, before we load the email (subject is then 'lost').
$mail.Load($mailProps) loads the email & mime content.
The last 3 $fStream lines write the mime content to a stream.
You'll need to add some rules to clean up the subject, or name the email differently, of course.
I have a script that gets all the information from the security log and has the event ID 4740. It then creates an html report from that and emails it. What I want to do is to exit the script if there is no data returned from $event.
# Created by Brad Tostenson 1/13/17
# This script will gather all the events with event ID 4740 (Account Locked Out)
# creates a report in HTML and emails it to the System Admins as the body
# of the email.
# Varaible the sets the reports temporary location
$LockedOut= "c:\temp\LockedOut.html"
# Setup date
$Date = Get-Date
# Sets up the report
$HTML=#"
<title>Account locked out Report</title>
<!--mce:0-->
"#
# Setup variables for the information to go under the headers in the report
$Account_Name = #{n='Account Name';e={$_.ReplacementStrings[-1]}}
$Account_domain = #{n='Account Domain';e={$_.ReplacementStrings[-2]}}
$Caller_Computer_Name = #{n='Caller Computer Name';e={$_.ReplacementStrings[-1]}}
# Pulls the information from the log
$event = Get-EventLog -LogName Security -InstanceId 4740 -after $date.AddHours(-24) |
Select TimeGenerated,ReplacementStrings,"Account Name","Account Domain","Caller Computer Name" |
% {
New-Object PSObject -Property #{
"Account Name" = $_.ReplacementStrings[-7]
"Account Domain" = $_.ReplacementStrings[5]
"Caller Computer Name" = $_.ReplacementStrings[1]
Date = $_.TimeGenerated
}
}
$event | ConvertTo-Html -Property "Account Name","Account Domain","Caller Computer Name",Date -head $HTML -body "<H2> The Following User Accounts Were Locked In Active Directory</H2>"|
Out-File $LockedOut -Append
# Takes the report and adds the information to the body of the email and sends it to the System Admins
$MailBody= Get-Content $LockedOut
$MailSubject= "Account Lock Report"
$SmtpClient = New-Object system.net.mail.smtpClient
$SmtpClient.host = "smtp.ourdomain.com"
$MailMessage = New-Object system.net.mail.mailmessage
$MailMessage.from = "LockedOut#ourdomain.com"
$MailMessage.To.add("email#ourdomain.com")
$MailMessage.Subject = $MailSubject
$MailMessage.IsBodyHtml = 1
$MailMessage.Body = $MailBody
$SmtpClient.Send($MailMessage)
del c:\temp\LockedOut.html
I don't see why $event wouldn't be null if Get-EventLog returns no data, and null has a Boolean value of false. That means you can just do this:
if (!$event) { exit }
Or, if it makes more sense, you can do this:
if ($event) {
$event | ConvertTo-Html -Property "Account Name","Account Domain","Caller Computer Name",Date -head $HTML -body "<H2> The Following User Accounts Were Locked In Active Directory</H2>"|
Out-File $LockedOut -Append
# Takes the report and adds the information to the body of the email and sends it to the System Admins
$MailBody= Get-Content $LockedOut
$MailSubject= "Account Lock Report"
$SmtpClient = New-Object system.net.mail.smtpClient
$SmtpClient.host = "smtp.ourdomain.com"
$MailMessage = New-Object system.net.mail.mailmessage
$MailMessage.from = "LockedOut#ourdomain.com"
$MailMessage.To.add("email#ourdomain.com")
$MailMessage.Subject = $MailSubject
$MailMessage.IsBodyHtml = 1
$MailMessage.Body = $MailBody
$SmtpClient.Send($MailMessage)
del c:\temp\LockedOut.html
}
Also, you might want to look at using the Send-MailMessage cmdlet. It's much simpler that what you're doing.
You also don't technically need the $LockedOut file at all, but I'm guessing you're using that in case the network is down or the email fails for some reason.