Jump to content

Get eMails from Exchange inbox powershell to AutoIT?


Recommended Posts

After much searching I finally found a method to get eMails from an Exchange eMail account inbox.  I was hoping for AutoIT or vbscript but I couldn't find any that would read the inbox messages without using Outlook.

I needed this because I'm testing a web-form that generates an eMail sent to a shared mailbox "not what my current outlook is configured for".  so, I needed to connect to a different account, then get the inbox messages, and see if the auto-generated eMail message body contains what I submitted in the form.

 

I found a PowerShell script that was close and modified it to do just what I want, but I'd still like it to run in AutoIT but I'm not sure how to use the Microsoft.Exchange.WebServices.dll

Anybody have some ideas? 



#To Launch!
#	C:\Windows\System32> powershell -ExecutionPolicy ByPass		#This launches PowerShell and allows execution of .ps1 files
#	PS C:\Windows\System32> . "C:\Temp\eMail\getInbox.ps1"		#The period . in front of the .ps1 file forces PS to display results on-screen


# Where is the EWS .DLL file that you are using
# Get the installer from https://www.microsoft.com/en-us/download/details.aspx?id=42022
# We only need 2 dll's from the install and they can be stored anywhere:  "Microsoft.Exchange.WebServices.Auth.dll" & "Microsoft.Exchange.WebServices.dll"
	$EWSdll = "C:\Temp\eMail\Microsoft.Exchange.WebServices.dll"

# Where do you want the output text file to be saved
	$Output = "C:\Temp\eMails.txt"

# replace with your email address
	$email    = "MyemailAddress@work.net"

# only need to populate these if you're impersonating...
	$username = "myemail"
	$password = "Sup3rS3cre+"
	$domain   = "ad.work.net"

# load the assembly : point to the dll in the location you have the .dll file
	[void] [Reflection.Assembly]::LoadFile($EWSdll)

# set ref to exchange, first references 2007, 2nd is 2010 (default)
	#$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
	$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService

# use first option if you want to impersonate, otherwise, grab your own credentials with the 3rd one.  not sure what the 2nd one is for
	$s.Credentials = New-Object Net.NetworkCredential($username, $password, $domain)
	##$s.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
	#$s.UseDefaultCredentials = $true

# discover the url from your email address
	$s.AutodiscoverUrl($email)

# get a handle to the inbox
	$inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)

#create a property set (to let us access the body & other details not available from the FindItems call)
	$psPropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
	$psPropertySet.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text;

	# If you have a set number of items you want to get, use this and insert the # in the ()
	# $items = $inbox.FindItems(5)

	# If you want to retrieve all items (Server limit is usually at 1000) then use this line
	#	Details on the max returned by server:  https://blogs.msdn.microsoft.com/exchangedev/2010/03/12/throttling-policies-and-the-ewsfindcountlimit/
	$items = $inbox.FindItems($inbox.TotalCount)


# Put some counts at the top of the output
	Write-host "Total Inbox count: $($inbox.TotalCount)"
	Write-host "Unread count: $($inbox.UnreadCount)"

	#These two lines, write the output to the specified text file
	Add-Content $Output "Total Inbox count:  $($inbox.TotalCount)"
	Add-Content $Output "Unread count:  $($inbox.UnreadCount)"

	foreach ($item in $items.Items)
	{
	# load the property set to allow us to get to the body
	  $item.load($psPropertySet)

	  # Get the Body text as-is
	  $bod = $item.Body.Text

	#if you only want a short summary of the Body, then comment the above line and un-comment these 4 lines
	   # $bod = $item.Body.Text -replace '\s+', ' '
	   # $bodCutOff = (100,$bod.Length | Measure-Object -Minimum).Minimum
	   # $bod = $bod.Substring(0,$bodCutOff)
	   # $bod = "$bod..."


	  # output the results - first of all the From, Subject, References and Message ID
	  write-host "===================================================================="
	  Write-host "From:  $($item.From.Name)"
	  Write-host "Subject:  $($item.Subject)"
	  Write-host "Body:  $($bod)"
	  write-host "===================================================================="
	  ""

	  # Output the results to the specified Text file
	  Add-Content $Output ""
	  Add-Content $Output "===================================================================="
	  Add-Content $Output "From:  $($item.From.Name)"
	  Add-Content $Output "Subject:  $($item.Subject)"
	  Add-Content $Output "Body:",$($bod)
	  Add-Content $Output "===================================================================="
	  Add-Content $Output ""

	}




#see these URLs for more info
# EWS Stuff
# folder members: https://msdn.microsoft.com/en-us/library/microsoft.exchange.webservices.data.folder_members%28v=exchg.80%29.aspx
# exporting headers: https://www.allabout365.com/2010/10/export-email-headers-exchange-powershell/
# read emails with EWS: https://social.technet.microsoft.com/Forums/en-US/3fbf8348-2945-43aa-a0bc-f3b1d34da27c/read-emails-with-ews?forum=exchangesvrdevelopment

 

Thanks,

Mike

Link to comment
Share on other sites

If you just want to call your powershell from AutoIt. you need to set your Dll full path to $EWSdll. 

 

Probably you could write a Cmdlets or function to to be easy pass parameter  to your powershell script using AutoIt.

Then you can call it using something like this in AutoIt

 

Local $sCommands = $sPSFullPath & ' -ExecutionPolicy ByPass import-module "' & $sPsScriptFullPath & '" ;Your-CmdLets -someparameter1 "'& $sparam1  &'" -someparameter2 "'& $sparam2 & '"'
Local $iPID = RunWait(@ComSpec & " /c " & $sCommands, "", @SW_SHOW)

Saludos

Link to comment
Share on other sites

I think is a little complex convert to row AutoIt due seems to be it does not provide a COM accesible Object (Activex). You could probably could do it using  .NET Common Language Runtime (CLR) Framework. Probably a little easer Running C# or NET code through those libraries but It would be embebed code something like powershell. 

I think your actual code, using powershell is simple,easy and functional.


Saludos

Link to comment
Share on other sites

I have updated the PowerShell script to accept parameters, but it's failing if the Paths contain spaces.  I have tried so many different ways and it keeps failing whenever I try to use a path with a space.

Any ideas on how to get this to work with spaces?

 

This works great!  PowerShell -ExecutionPolicy ByPass -command "C:\Temp\GetMail.ps1" -EWSdll 'C:\Temp\Microsoft.Exchange.WebServices.dll' -Output 'C:\Temp\eMails.txt' -email 'MyemailAddress@work.net' -username 'myemail' -password 'Sup3rS3cre+' -domain 'ad.work.net'

 

This fails with TONS of errors!  PowerShell -ExecutionPolicy ByPass -command "C:\Temp\eMail Test\GetMail.ps1" -EWSdll 'C:\Temp\eMail Test\Microsoft.Exchange.WebServices.dll' -Output 'C:\Temp\eMail Test\eMails.txt' -email 'MyemailAddress@work.net' -username 'myemail' -password 'Sup3rS3cre+' -domain 'ad.work.net'

 

 

param(
	[string]$EWSdll,
	[string]$Output,
	[string]$email,
	[string]$username,
	[string]$password,
	[string]$domain
	)

# load the assembly : point to the EWS dll
	[void] [Reflection.Assembly]::LoadFile($EWSdll)

# set ref to exchange, first references 2007, 2nd is 2010 (default)
	#$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2007_SP1)
	$s = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService

# use first option if you want to impersonate, otherwise, grab your own credentials
	$s.Credentials = New-Object Net.NetworkCredential($username, $password, $domain)
	##$s.Credentials = [System.Net.CredentialCache]::DefaultNetworkCredentials
	#$s.UseDefaultCredentials = $true

# discover the url from your email address
	$s.AutodiscoverUrl($email)

# get a handle to the inbox
	$inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($s,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox)

#create a property set (to let us access the body & other details not available from the FindItems call)
	$psPropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
	$psPropertySet.RequestedBodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::Text;

	# If you have a set number of items you want to get, use this and insert the # in the ()
	# $items = $inbox.FindItems(5)

	# If you want to retrieve all items (Server limit usually at 1000) then use this
	#	Details on the max returned by server:  https://blogs.msdn.microsoft.com/exchangedev/2010/03/12/throttling-policies-and-the-ewsfindcountlimit/
	 $items = $inbox.FindItems($inbox.TotalCount)

# output unread count
	Write-host "Total Inbox count: $($inbox.TotalCount)"
	Write-host "Unread count: $($inbox.UnreadCount)"

	#These two lines, write the output to the specified text file
	Add-Content $Output "Total Inbox count:  $($inbox.TotalCount)"
	Add-Content $Output "Unread count:  $($inbox.UnreadCount)"

	foreach ($item in $items.Items)
	{
	# load the property set to allow us to get to the body
	  $item.load($psPropertySet)

	  # Get the Body text as-is
	  $bod = $item.Body.Text

	#if you only want a short summary of the Body, then comment the above line and un-comment these 4 lines
	   # $bod = $item.Body.Text -replace '\s+', ' '
	   # $bodCutOff = (100,$bod.Length | Measure-Object -Minimum).Minimum
	   # $bod = $bod.Substring(0,$bodCutOff)
	   # $bod = "$bod..."


	  # output the results - first of all the From, Subject, References and Message ID
	  write-host "===================================================================="
	  Write-host "From:  $($item.From.Name)"
	  Write-host "Subject:  $($item.Subject)"
	  Write-host "Body:  ",$($bod)
	  write-host "===================================================================="
	  ""

	  # Output the results to the specified Text file
	  Add-Content $Output ""
	  Add-Content $Output "===================================================================="
	  Add-Content $Output "From:  $($item.From.Name)"
	  Add-Content $Output "Subject:  $($item.Subject)"
	  Add-Content $Output "Body:",$($bod)
	  Add-Content $Output "===================================================================="
	  Add-Content $Output ""

	}




#see these URLs for more info
# EWS Stuff
# folder members: https://msdn.microsoft.com/en-us/library/microsoft.exchange.webservices.data.folder_members%28v=exchg.80%29.aspx
# exporting headers: https://www.allabout365.com/2010/10/export-email-headers-exchange-powershell/
# read emails with EWS: https://social.technet.microsoft.com/Forums/en-US/3fbf8348-2945-43aa-a0bc-f3b1d34da27c/read-emails-with-ews?forum=exchangesvrdevelopment

 

Thanks,

Mike

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

×
×
  • Create New...