I'm writing a script that can send mails to a certain e-mail address but I'm having some trouble with the sending itself.
The problem is that when I send a mail with the script it takes approximately 1min to send. I can see this because I can see it in my outbox.
But when I create this exact same mail manually in outlook it only takes a matter of seconds to process and send the mail.
My code for creating and sending the mail:
(I use Redemption)
$mItem = $ol.CreateItem(0)
$mail = $routlook.GetRDOObjectFromOutlookObject($mItem)
$mail.To = "<Recipient's Address>"
$mail.Subject = "Some Subject"
$mail.Body = "Some Body"
$mail.Attachments.Add("<Path to Attachment>")
$mail.DeleteAfterSubmit = $True
$mail.Send()
I don't know what the problem is. Could this be due to my code? or perhaps the exchange-server or the Outlook client?
How can I make the mails from the script send faster?
Please help,
Thanks!
You can use send-mailmessage directly in your code without the long way through COM and Outlook.
Assuming an Exchange version of at least 2007, you'd be much better off using the EWS Managed API than Outlook/COM.
Related
I have a function that sends an email (EDIT1: from an ON-PREM mailbox) using delayed delivery, via COM objects. I am trying to write an equivalent function for EWS. I got a working PoC but it has 1 glaring issue: The message sits in the sent items folder, not the outbox, until the defer date arrives, then it sends as expected.
I'm using the SendAndSaveCopy method and I tried specifying the Outbox folder. This did put the message into the Outbox, but when it sends, it doesn't get moved to the Sent Items folder.
$service = New-EwsService # .... assume this works; My RequestedServerVersion is Exchange2013
$EmailMessage = New-Object Microsoft.Exchange.WebServices.Data.EmailMessage -ArgumentList $service
$EmailMessage.Subject = 'outbox test'
$EmailMessage.Body = 'this is a test'
$EmailMessage.ToRecipients.Add('someone#somewhere.com')
$SendOn = (get-date).AddMinutes(5)
$defer = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(
0x3FEF, # 'PR_DEFERRED_SEND_TIME',
[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::SystemTime
)
$EmailMessage.SetExtendedProperty($defer,$SendOn.ToUniversalTime())
# $EmailMessage.SendAndSaveCopy([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Outbox)
$EmailMessage.SendAndSaveCopy()
Another thing I noticed was that if I open the message in Outlook while it's waiting to send, and I look at the delay delivery settings, it's not configured (in the Outlook UI). And if I hit send on that item, it immediately sends. I would assume that the config would be in the message and visible from the UI. (The expected behavior is the message in the Outbox list should be in italics until you open it, then it will return to italics if you hit send, otherwise it won't be italic and won't send when the defer time arrives).
Is there anyone who knows why the folder behavior doesn't match the MS doc?
The message.SendAndSaveCopy() line results in a call to the service. If the call is successful, the email message will be available in the caller’s Outbox folder. After the email message is sent, a copy of the message will be created in the Sent Items folder.
EDIT2: I ended up going with an alternative solution. Instead of queuing messages in the mailbox directly, I am exporting the Send-MailMessage parameter hash to XML, then using the Task Scheduler to execute at a later time, grabbing that object from cache and splatting it on the function call. Works great.
The docs you refer to are very old and the behaviour has changed. In Office 365, the deferred message is saved in Drafts folder until the time of sending, at which point it is sent and then saved to Sent Items.
Note that Outlook Object Model works against Outlook, while EWS works directly with the mailbox on Exchange.
Need to fetch mails from exchange mailbox. For that i need to query a particular string available in body and a particular string body too. I used below query for fetching subjects and body separately .its working fine.
Please help me to combine both filters to get mails from the mailbox.
$filtersubject = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+ContainsSubstring([Microsoft.Exchange.WebServices.Data.EmailMessageSchema]::Subject, $Subject)
$filterbody = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+ContainsSubstring( [Microsoft.Exchange.WebServices.Data.ItemSchema]::Body, $Body)
I'm looking into a script that can access an Outlook folder and read the content of the email. I hope (don't know how yet) to parse the body to extract a URL from it. However, the body of my email and other messages I've tried it on keeps returning empty.
$ol = New-Object -ComObject Outlook.Application
$ns = $ol.GETNAMESPACE("MAPI")
$inbox = $ns.GetDefaultFolder([Microsoft.Office.Interop.Outlook.OlDefaultFolders]::olFolderInbox)
$inbox.Items($x).Body
# returns nothing
Same result for .HTMLBody and .RTFBody.
Possibly related is that SenderName is blank too. Is it possible that have a corporate IT policy that prevents me from seeing my own message metadata? I'm exploring Powershell because they've disabled VBA in Outlook already.
Currently, each day my business needs to send and encrypted email using MS Outlook. The process works, but obviously the whole 'doing it every day thing' sucks. I've tried looking up ways to automate the process which has helped me solve the surrounding processes, but i still can't find anything, or whip up anything myself which will handle the email side. The flow of events are;
Receive
Encrypted email is received
Email is opened and attachment is dragged to UNC share 1 (repeated for each email recieved)
Attachment is picked up and processed by surrounding script
Send
Browse UNC share 2
Copy 1 of x files to a new email
Set subject as full file name
Select email to be signed/encrypted in top ribbon
Send email and repeat for each file in UNC share 2
I can get emails to send with attachment via powerhsell and by using S/MIME, but once I combine the two I get stuck and the script turns to rubble :(
Any help at all would be greatly appreciated
If I'm not mistaken, Powershell can load and use .NET assemblies, correct? (I'm not a powershell user, so my knowledge is limited).
Given that, I would recommend taking a look at using the MimeKit and MailKit libraries.
Check out the MimeKit README for some examples on how to use the S/MIME API's.
MimeKit comes with a WindowsSecureMimeContext which you might be able to use out of the box, but that depends on where your private keys and certificates are stored. If they aren't in the X509Store, then you could use the TemporarySecureMimeContext and simply load the certificate(s) and private key(s) into that and use it.
Got a similar problem and here's my solution so far, still testing:
$Outlook = New-object -ComObject Outlook.Application
$Mail = $Outlook.CreateItem(0)
$Mail.To = "me#company.tld"
$Mail.Subject ="Test"
$Mail.Body ="Test Body"
# 0 = nothing, 1 = encrypt, 2 = sign, 3 = both!
$PR_SECURITY_FLAGS = "http://schemas.microsoft.com/mapi/proptag/0x6E010003"
$Mail.PropertyAccessor.SetProperty($PR_SECURITY_FLAGS, 3)
$Mail.Send()
If Outlook is running, everything works fine. But when I start Outlook afterwards, I will find the created Mail in the Outbox without encryption and not signed.
Without Outlook running, the Code would produce an "InvokeMethodOnNull"-Error. Putting a $Mail.Display() before the SetProperty()-Part would take care of that and the buttons seem to be checked in the opening E-Mail, but the result will be the same: Start Outlook and your mail is in Outbox without encryption and not signed.
One of our departments is requesting to receive a notification whenever an email is sent to a particular inbox. So every time an email is sent to mailbox#mycompany.com, they want an email sent to a distribution list saying "A message has arrived."
Is this possible in Exchange 2007 using a Powershell script?
Sounds to me like this is just a matter of creating a rule in Exchange.
Running through the "Rules Wizard":
Check messages when they arrive
through the specified account (select account associated with mailbox#mycompany.com)
run a script (something that will send out the new "A message has arrived." email)
OR forward/redirect it to people or distribution list
Use a transport rule
$condition = Get-TransportRulePredicate From
$condition.addresses = 'someone#contoso.com'
$action = Get-TransportRuleAction CopyTo
$action.addresses = 'otherperson#contoso.com'
New-TransportRule -Name "Notify New Message Recieved" -Conditions $condition -Actions $action