Using Exchange Web Services from VBScript: Sending a message with attachment example No ratings yet.

0

With Exchange 2010, CDO and all the other APIs that were commonly used from VBScript (e.g. WebDAV) are no longer supported.  The only scriptable API is EWS.  While it is relatively easy to use EWS using the managed API, this is not possible from VBScript.  However, programming with EWS from VBScript can be done, and isn’t as complex as it may first seem.

To demonstrate, here is an example from a recent case.  The question was how to send an email with attachment from a script, and the only option in this case was to use EWS.  First of all, the process for sending an email with attachment needs to be understood, as with EWS it is a three step process:

1. Create the message and save it to drafts.
2. Add the attachment to the message.
3. Send the complete message

As you can see, to do the above we will need to both send EWS requests and read data from the responses (which we wouldn’t necessarily have to do if we were just sending a basic message).  The easiest way I could think of to implement this was create the EWS requests as template files (XML with replaceable fields), and then implement some functions to make dealing with the templates and SOAP conversations more straight-forward.

The resulting script is below.  I’ve also attached a zip file that contains everything needed to test this example (you’ll have to edit the templates and configuration details in the script to your environment).  It should be quite easy to implement most EWS functionality using this system.

 

'  DISCLAIMER:
'THIS CODE IS SAMPLE CODE. THESE SAMPLES ARE PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND.
'MICROSOFT FURTHER DISCLAIMS ALL IMPLIED WARRANTIES INCLUDING WITHOUT LIMITATION ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR OF FITNESS FOR
'A PARTICULAR PURPOSE. THE ENTIRE RISK ARISING OUT OF THE USE OR PERFORMANCE OF THE SAMPLES REMAINS WITH YOU. IN NO EVENT SHALL
'MICROSOFT OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS PROFITS,
'BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) ARISING OUT OF THE USE OF OR INABILITY TO USE THE
'SAMPLES, EVEN IF MICROSOFT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. BECAUSE SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION
'OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES, THE ABOVE LIMITATION MAY NOT APPLY TO YOU.


' ---------------------------------------------------------
' CONFIGURATION - change as needed
' ---------------------------------------------------------


const TARGETURL="https://ex1.exch2k7.local/ews/exchange.asmx"
const USERNAME="exch2k7\Administrator"
const PASSWORD="root@1"
const ATTACHMENT="c:\vbstest\Attach.zip"
const TEMPLATEPATH="c:\vbstest\"


' ---------------------------------------------------------
' MAIN SCRIPT
' ---------------------------------------------------------

dim oFSO
set oFSO=CreateObject("Scripting.FileSystemObject") ' We use this globally throughout the script

' Create the message (the template creates a message in the Drafts folder)
set CreateItemResponse=SendSOAP(ReadTemplate("CreateMessage.xml"))

' Check we got a Success response
if not IsResponseSuccess(CreateItemResponse, "m:CreateItemResponseMessage") then
	' Message creation failed
	wscript.echo CreateItemResponse.xml
	wscript.quit
end if

' Now we need to read the ItemId and ChangeKey from the response
ItemId=CreateItemResponse.documentElement.getElementsByTagName("t:ItemId").Item(0).Attributes.getNamedItem("Id").Text
ChangeKey=CreateItemResponse.documentElement.getElementsByTagName("t:ItemId").Item(0).Attributes.getNamedItem("ChangeKey").Text

' Now build the SOAP request to add the attachment
CreateAttachmentSOAP=ReadTemplate("CreateAttachment.xml")
CreateAttachmentSOAP=Replace(CreateAttachmentSOAP, "", ItemId)
CreateAttachmentSOAP=Replace(CreateAttachmentSOAP, "", ChangeKey)

set f=oFSO.GetFile(ATTACHMENT)
CreateAttachmentSOAP=Replace(CreateAttachmentSOAP, "", f.Name)
CreateAttachmentSOAP=Replace(CreateAttachmentSOAP, "", ReadFileAsBase64(ATTACHMENT))

' The SOAP request is now ready, so send it (this adds the attachment to the message in the Drafts folder)
set CreateAttachmentResponse=SendSOAP(CreateAttachmentSOAP)

' Check we got a Success response
if not IsResponseSuccess(CreateAttachmentResponse, "m:CreateAttachmentResponseMessage") then
	' Message creation failed
	wscript.echo CreateAttachmentResponse.xml
	wscript.quit
end if

' Read the ItemId and ChangeKey from the response - the ItemId should be the same, but the ChangeKey will be different
ItemId=CreateAttachmentResponse.documentElement.getElementsByTagName("t:AttachmentId").Item(0).Attributes.getNamedItem("RootItemId").Text
ChangeKey=CreateAttachmentResponse.documentElement.getElementsByTagName("t:AttachmentId").Item(0).Attributes.getNamedItem("RootItemChangeKey").Text

' Finally, we need to send the message
SendItemSOAP=ReadTemplate("SendItem.xml")
SendItemSOAP=Replace(SendItemSOAP, "", ItemId)
SendItemSOAP=Replace(SendItemSOAP, "", ChangeKey)
set SendItemResponse=SendSOAP(SendItemSOAP)

' Check we got a Success response
if not IsResponseSuccess(SendItemResponse, "m:SendItemResponseMessage") then
	' Message creation failed
	wscript.echo SendItemResponse.xml
	wscript.quit
end if

wscript.echo "Message was sent successfully."


' ---------------------------------------------------------
' HELPER FUNCTIONS
' ---------------------------------------------------------


function ReadBytes(SourceFile)
	' Read the file into a stream
	set oStream=CreateObject("ADODB.Stream")
	oStream.Open
	oStream.Type=1 ' Binary
	oStream.LoadFromFile(SourceFile)
	ReadBytes=oStream.Read()
end function

function ReadFileAsBase64(SourceFile)
	' Read a file and return the contents Base64 encoded
	FileBinary=ReadBytes(SourceFile)
	set oXML=CreateObject("MSXML2.DOMDocument")
	set oNode=oXML.CreateElement("base64")
	oNode.DataType="bin.base64"
	oNode.NodeTypedValue=FileBinary
	ReadFileAsBase64=oNode.Text
end function


function SendSOAP(SOAP)
	' Send the SOAP request, and return the response
	
	set oXMLHTTP=CreateObject("MSXML2.XMLHTTP")
	set oXML=CreateObject("MSXML2.DOMDocument")
	
	' Send the request
	oXMLHTTP.Open "POST", TARGETURL, false, USERNAME, PASSWORD
	oXMLHTTP.SetRequestHeader "Content-Type", "text/xml"
	oXMLHTTP.Send SOAP
	
	if oXMLHTTP.Status="200" then
		' Get response
		if oXML.LoadXML(oXMLHTTP.ResponseText) then
			set SendSOAP=oXML
		end if
	else
		wscript.echo "Response status: " & oXMLHTTP.Status
	end if
end function

function ReadTemplate(ByVal TemplateFile)
	' Read the given template and return it
	
	if not oFSO.FileExists(TemplateFile) then TemplateFile=TEMPLATEPATH & TemplateFile
	set oTS=oFSO.OpenTextFile(TemplateFile)
	sTemplate=""
	while not oTS.AtEndOfStream
		sTemplate=sTemplate & oTS.ReadLine
	wend
	oTS.Close
	ReadTemplate=sTemplate
end function

function IsResponseSuccess(Response, ResponseMessageTag)
	on error resume next
	IsResponseSuccess=true
	if Response.documentElement.getElementsByTagName(ResponseMessageTag).Item(0).Attributes.getNamedItem("ResponseClass").Text<>"Success" then
		if Err.Number<>0 then
			wscript.echo "Error reading response: " & Err.Description
		end if
		IsResponseSuccess=false
	end if
	on error goto 0
end function

Send message with attachment.zip

0

Please rate this

Leave a Reply

Your email address will not be published. Required fields are marked *