Powershell S/MIME - email

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.

Related

PowerShell/EWS Send message with Delayed/Deferred delivery

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.

Mail takes a long time to send

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.

Reading mail data from powershell

I'm trying to read some data from a .pst file using powershell and I can't seem to extract some attributes for mail items, specifically:
recipients, sender, cc, bcc, body
for some reason when I try to access these properties from code it shows up as blank. Most of the other properties show up file (subject, attachments etc...)
I'm using the following code:
$objOutlook = new-object -ComObject Outlook.Application
$ns = $objOutlook.GetNamespace("MAPI")
$ns.AddStore($pst.FullName)
$folders = $ns.Folders
$archiveStore = $ns.Folders[$pst.Name.Replace(".pst","")]
from there I just use Folders and Items recursively to get my mail items.
Any ideas?
This returns the sender for me.
$archiveStore.Items | %{$_.SenderName}
Which property are you using to fetch the recipients,sender,cc,bcc,body?
Where and how do you run a PowerShell script? And what code exactly do you use to fetch the property values?
The fact is that Microsoft does not currently recommend, and does not support, Automation of Microsoft Office applications from any unattended, non-interactive client application or component (including ASP, ASP.NET, DCOM, and NT Services), because Office may exhibit unstable behavior and/or deadlock when Office is run in this environment. See Considerations for server-side Automation of Office for more information.

VBScript to modify email content type

I have incoming email set up for SharePoint 2010, and am sending forms from InfoPath using that method, with SMTP server set up on the SharePoint Server machine. It seems easier than elevating the permissions of an anonymous user with the InfoPath code-behind option. I also tried a custom method of sending the emails but was unable to find a way to send the form data along with the email message using the InfoPath 2010 code-behind option. So, I found another way, using the advice from SharePoint UK's website.
My problem is that while removing the x-mailer header actually solved my problem regarding whole email messages, it did not allow the attached form data to be sent to the library. The message would be imported and then just disappear if I did not have the "Save original e-mail" setting enabled. Inspecting messages in the drop folder I found they had a content type of "multipart/related" and if I edited them with NotePad++ I could change that to "multipart/mixed" and the attached form data would then be imported as desired.
So I went about trying to modify the VB Script to make this happen BUT now nothing happens with the script at all. Clearly I'm doing something wrong with it and VBScript really isn't my area of expertise. Maybe it's just not possible to edit those fields or maybe I need to attack it from a different angle. How can I get my VBScript to edit the content type for these emails?
CODE:
Set shell = CreateObject("WScript.Shell")
shell.LogEvent 4, "starting mail filter"
if instr(iMsg.Fields("urn:schemas:mailheader:content-type"), "related") > 1 then
Dim logMsg = "Mail Type: " & iMsg.Fields("urn:schemas:mailheader:content-type")
Dim tempType = Replace(iMsg.Fields("urn:schemas:mailheader:content-type"), "related", "mixed")
shell.LogEvent 4, iMsg.Fields("urn:schemas:mailheader:content-type")
iMsg.Fields.Delete("urn:schemas:mailheader:content-type")
iMsg.Fields.Item("urn:schemas:mailheader:content-type") = tempType
iMsg.Fields.Update
shell.LogEvent 4, iMsg.Fields("urn:schemas:mailheader:content-type")
end if
shell.LogEvent 4, "end mail filter"
iMsg.DataSource.Save
EventStatus = 0
I looked into this in greater detail and found that the content-type property of an email message is one of the many that is read-only using this particular vbscript library. So, I would have to find some other way of editing the file, and the work involved is more than what it would take to find an alternate solution that skipped email altogether. Therefore, I am abandoning the plan of using email in this case. If you take something away from this, let it be that there are read-only properties for the mail message object in this script.

Using the Microsoft SMTP Server's Dropfolder

I have set up Microsoft SMTP server so it will store all incoming email in a dropfolder.
I want to process, using c#, incoming mail based on the sender, recipient, and subject line. If possible, I also want to create a plain text preview of the email.
So, there are two parts to this problem.
I'm guessing a FileSystemWatcher
would be adequate for providing
notification of incoming mail.
How to parse the headers and body text from the .eml file; is there an existing library or any good documentation on the format?
Thanks for any help.
Yes - thats true
I used this: http://www.lumisoft.ee/lswww/ENG/Products/Mail_Server/mail_index_eng.aspx?type=info
It's a Mailserver written in C# with an API you can use without using the Mailserver
EDIT: Found a code snippet:
LumiSoft.Net.Mime.Mime m = LumiSoft.Net.Mime.Mime.Parse(mailfile);
Console.WriteLine("Read message from: " + m.MainEntity.From);
Console.WriteLine("To: " + m.MainEntity.To[0]);