I've you haven't seen this before Gavin Smyth from Microsoft Research put together this cool VSTO plugin to allow you to send an Email from Outlook that will disable the Reply, ReplyAll and Forward Buttons on the Outlook ribbon http://research.microsoft.com/en-us/projects/researchdesktop/noreplyall.aspx and the how to posts about the VSTO http://blogs.msdn.com/b/gsmyth/archive/2011/09/18/noreply-vsto-add-in-wrap-up.aspx .
Note this only works in Outlook (not OWA or ActiveSync etc) but basically what a users would see when they receive a message is
How this works is it sets the PidLidVerbStream Property on a message which is mostly documented in the http://msdn.microsoft.com/en-us/library/ee218541(v=exchg.80).aspx protocol document. I say mostly because the format you get when using the methods from the NoReply Addin is a little different from the format documented which is for Voting buttons but its good enough to work with. The Verbs that this property refers to are the standard Verbs that MAPI implements which are documented in http://msdn.microsoft.com/en-us/library/office/cc815879(v=office.15).aspx .
So to use this same property in an EWS script you can just set it using the Extended Properties, the value you use is a little tricky as only the voteoption format is fully documented. But because this is pretty standard you can cut a past the Hex Values which contains the two streams from this property out of an existing message and then just change the bits that either enables or disable the Verbs for what you want to enable or disable on the Message your sending.
So this is what the following script does is allows you to send a message using EWS and set the options to enable and disable each of these verbs.
In the script I've got the following custom object where you can set the verbs on or off
The rest of the script builds the VerbStream value property based on the setting in the custom object and the rest of the script is a standard EWS script to send a message.
I've put a download of this script here the script itself looks like
Note this only works in Outlook (not OWA or ActiveSync etc) but basically what a users would see when they receive a message is
How this works is it sets the PidLidVerbStream Property on a message which is mostly documented in the http://msdn.microsoft.com/en-us/library/ee218541(v=exchg.80).aspx protocol document. I say mostly because the format you get when using the methods from the NoReply Addin is a little different from the format documented which is for Voting buttons but its good enough to work with. The Verbs that this property refers to are the standard Verbs that MAPI implements which are documented in http://msdn.microsoft.com/en-us/library/office/cc815879(v=office.15).aspx .
So to use this same property in an EWS script you can just set it using the Extended Properties, the value you use is a little tricky as only the voteoption format is fully documented. But because this is pretty standard you can cut a past the Hex Values which contains the two streams from this property out of an existing message and then just change the bits that either enables or disable the Verbs for what you want to enable or disable on the Message your sending.
So this is what the following script does is allows you to send a message using EWS and set the options to enable and disable each of these verbs.
In the script I've got the following custom object where you can set the verbs on or off
- $VerbSetting = "" | Select DisableReplyAll,DisableReply,DisableForward,DisableReplyToFolder
- $VerbSetting.DisableReplyAll = $true
- $VerbSetting.DisableReply = $true
- $VerbSetting.DisableForward = $true
- $VerbSetting.DisableReplyToFolder = $true
The rest of the script builds the VerbStream value property based on the setting in the custom object and the rest of the script is a standard EWS script to send a message.
I've put a download of this script here the script itself looks like
- $MailboxName = $args[0]
- $SentTo = $args[1]
- $VerbSetting = "" | Select DisableReplyAll,DisableReply,DisableForward,DisableReplyToFolder
- $VerbSetting.DisableReplyAll = $true
- $VerbSetting.DisableReply = $true
- $VerbSetting.DisableForward = $true
- $VerbSetting.DisableReplyToFolder = $true
- ## Load Managed API dll
- ###CHECK FOR EWS MANAGED API, IF PRESENT IMPORT THE HIGHEST VERSION EWS DLL, ELSE EXIT
- $EWSDLL = (($(Get-ItemProperty -ErrorAction SilentlyContinue -Path Registry::$(Get-ChildItem -ErrorAction SilentlyContinue -Path 'Registry::HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Exchange\Web Services'|Sort-Object Name -Descending| Select-Object -First 1 -ExpandProperty Name)).'Install Directory') + "Microsoft.Exchange.WebServices.dll")
- if (Test-Path $EWSDLL)
- {
- Import-Module $EWSDLL
- }
- else
- {
- "$(get-date -format yyyyMMddHHmmss):"
- "This script requires the EWS Managed API 1.2 or later."
- "Please download and install the current version of the EWS Managed API from"
- "http://go.microsoft.com/fwlink/?LinkId=255472"
- ""
- "Exiting Script."
- exit
- }
- ## Set Exchange Version
- $ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2
- ## Create Exchange Service Object
- $service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService($ExchangeVersion)
- ## Set Credentials to use two options are availible Option1 to use explict credentials or Option 2 use the Default (logged On) credentials
- #Credentials Option 1 using UPN for the windows Account
- $psCred = Get-Credential
- $creds = New-Object System.Net.NetworkCredential($psCred.UserName.ToString(),$psCred.GetNetworkCredential().password.ToString())
- $service.Credentials = $creds
- #Credentials Option 2
- #service.UseDefaultCredentials = $true
- ## Choose to ignore any SSL Warning issues caused by Self Signed Certificates
- ## Code From http://poshcode.org/624
- ## Create a compilation environment
- $Provider=New-Object Microsoft.CSharp.CSharpCodeProvider
- $Compiler=$Provider.CreateCompiler()
- $Params=New-Object System.CodeDom.Compiler.CompilerParameters
- $Params.GenerateExecutable=$False
- $Params.GenerateInMemory=$True
- $Params.IncludeDebugInformation=$False
- $Params.ReferencedAssemblies.Add("System.DLL") | Out-Null
- $TASource=@'
- namespace Local.ToolkitExtensions.Net.CertificatePolicy{
- public class TrustAll : System.Net.ICertificatePolicy {
- public TrustAll() {
- }
- public bool CheckValidationResult(System.Net.ServicePoint sp,
- System.Security.Cryptography.X509Certificates.X509Certificate cert,
- System.Net.WebRequest req, int problem) {
- return true;
- }
- }
- }
- '@
- $TAResults=$Provider.CompileAssemblyFromSource($Params,$TASource)
- $TAAssembly=$TAResults.CompiledAssembly
- ## We now create an instance of the TrustAll and attach it to the ServicePointManager
- $TrustAll=$TAAssembly.CreateInstance("Local.ToolkitExtensions.Net.CertificatePolicy.TrustAll")
- [System.Net.ServicePointManager]::CertificatePolicy=$TrustAll
- ## end code from http://poshcode.org/624
- ## Set the URL of the CAS (Client Access Server) to use two options are availbe to use Autodiscover to find the CAS URL or Hardcode the CAS to use
- #CAS URL Option 1 Autodiscover
- $service.AutodiscoverUrl($MailboxName,{$true})
- "Using CAS Server : " + $Service.url
- #CAS URL Option 2 Hardcoded
- #$uri=[system.URI] "https://casservername/ews/exchange.asmx"
- #$service.Url = $uri
- ## Optional section for Exchange Impersonation
- #$service.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $MailboxName)
- function Get-VerbStream{
- param (
- $VerbSettings = "$( throw 'VerbSettings is a mandatory Parameter' )"
- )
- process{
- $Header = "02010400000000000000"
- $ReplyToAllHeader = "055265706C790849504D2E4E6F7465074D657373616765025245050000000000000000"
- $ReplyToAllFooter = "0000000000000002000000660000000200000001000000"
- $ReplyToHeader = "0C5265706C7920746F20416C6C0849504D2E4E6F7465074D657373616765025245050000000000000000"
- $ReplyToFooter = "0000000000000002000000670000000300000002000000"
- $ForwardHeader = "07466F72776172640849504D2E4E6F7465074D657373616765024657050000000000000000"
- $ForwardFooter = "0000000000000002000000680000000400000003000000"
- $ReplyToFolderHeader = "0F5265706C7920746F20466F6C6465720849504D2E506F737404506F737400050000000000000000"
- $ReplyToFolderFooter = "00000000000000020000006C00000008000000"
- $VoteOptionExtras = "0401055200650070006C00790002520045000C5200650070006C007900200074006F00200041006C006C0002520045000746006F007200770061007200640002460057000F5200650070006C007900200074006F00200046006F006C0064006500720000"
- if($VerbSetting.DisableReplyAll){
- $DisableReplyAllVal = "00"
- }
- else{
- $DisableReplyAllVal = "01"
- }
- if($VerbSetting.DisableReply){
- $DisableReplyVal = "00"
- }
- else{
- $DisableReplyVal = "01"
- }
- if($VerbSetting.DisableForward){
- $DisableForwardVal = "00"
- }
- else{
- $DisableForwardVal = "01"
- }
- if($VerbSetting.DisableReplyToFolder){
- $DisableReplyToFolderVal = "00"
- }
- else{
- $DisableReplyToFolderVal = "01"
- }
- $VerbValue = $Header + $ReplyToAllHeader + $DisableReplyAllVal + $ReplyToAllFooter + $ReplyToHeader + $DisableReplyVal +$ReplyToFooter + $ForwardHeader + $DisableForwardVal + $ForwardFooter + $ReplyToFolderHeader + $DisableReplyToFolderVal + $ReplyToFolderFooter + $VoteOptionExtras
- return $VerbValue
- }
- }
- function hex2binarray($hexString){
- $i = 0
- [byte[]]$binarray = @()
- while($i -le $hexString.length - 2){
- $strHexBit = ($hexString.substring($i,2))
- $binarray += [byte]([Convert]::ToInt32($strHexBit,16))
- $i = $i + 2
- }
- return ,$binarray
- }
- $VerbStreamProp = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition([Microsoft.Exchange.WebServices.Data.DefaultExtendedPropertySet]::Common,0x8520, [Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Binary)
- $VerbSettingValue = get-VerbStream $VerbSetting
- $EmailMessage = New-Object Microsoft.Exchange.WebServices.Data.EmailMessage -ArgumentList $service
- $EmailMessage.Subject = "Message Subject"
- #Add Recipients
- $EmailMessage.ToRecipients.Add($SentTo)
- $EmailMessage.Body = New-Object Microsoft.Exchange.WebServices.Data.MessageBody
- $EmailMessage.Body.BodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::HTML
- $EmailMessage.Body.Text = "Body"
- $EmailMessage.SetExtendedProperty($VerbStreamProp,(hex2binarray $VerbSettingValue))
- $EmailMessage.SendAndSaveCopy()