It will send email with Approve and Reject
voting option. But i want to send Yes and No
or my own custom options. I've tried with changing verb stream but no luck.
This is my PowerShell code:
$SentTo = "[email protected]"
$username="abc1"
$password="abc1"
$VerbSetting = "" | Select DisableReplyAll,DisableReply,DisableForward,DisableReplyToFolder
$VerbSetting.DisableReplyAll = $false
$VerbSetting.DisableReply = $false
$VerbSetting.DisableForward = $false
$VerbSetting.DisableReplyToFolder = $false
Import-Module -Name 'C:\Program Files\Microsoft\Exchange\Web Services\2.0\Microsoft.Exchange.WebServices.dll'
## Create Exchange Service Object
$service = New-Object Microsoft.Exchange.WebServices.Data.ExchangeService -ArgumentList Exchange2010
$service.Credentials = New-Object Microsoft.Exchange.WebServices.Data.WebCredentials -ArgumentList $username, $password
$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
$uri=[system.URI] "https://web.xyz.com/EWS/Exchange.asmx"
$service.Url = $uri
function Get-VerbStream{
param (
$VerbSettings = "$( throw 'VerbSettings is a mandatory Parameter' )"
)
process{
$Header = "02010600000000000000"
$ReplyToAllHeader = "055265706C790849504D2E4E6F7465074D657373616765025245050000000000000000"
$ReplyToAllFooter = "0000000000000002000000660000000200000001000000"
$ReplyToHeader = "0C5265706C7920746F20416C6C0849504D2E4E6F7465074D657373616765025245050000000000000000"
$ReplyToFooter = "0000000000000002000000670000000300000002000000"
$ForwardHeader = "07466F72776172640849504D2E4E6F7465074D657373616765024657050000000000000000"
$ForwardFooter = "0000000000000002000000680000000400000003000000"
$ReplyToFolderHeader = "0F5265706C7920746F20466F6C6465720849504D2E506F737404506F737400050000000000000000"
$ReplyToFolderFooter = "00000000000000020000006C00000008000000"
$ApproveOption = "0400000007417070726F76650849504D2E4E6F74650007417070726F766500000000000000000001000000020000000200000001000000FFFFFFFF"
$RejectOption= "040000000652656A6563740849504D2E4E6F7465000652656A65637400000000000000000001000000020000000200000002000000FFFFFFFF"
$VoteOptionExtras = "0401055200650070006C00790002520045000C5200650070006C007900200074006F00200041006C006C0002520045000746006F007200770061007200640002460057000F5200650070006C007900200074006F00200046006F006C00640065007200000741007000700072006F00760065000741007000700072006F007600650006520065006A0065006300740006520065006A00650063007400"
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 + $ApproveOption + $RejectOption + $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()
When you use other peoples code make sure to remark in the code where it came from so that anybody looking at it can know the background. The following should work okay if you use it as follows
$Verbs = @()
$Verbs += "Yes"
$Verbs += "No"
$Verbs += "Other Option"
Send-VoteMail -MailboxName [email protected] -To [email protected] -Subject "test Vote" -Verbs $Verbs
module
function Connect-Exchange{
param(
[Parameter(Position=0, Mandatory=$true)] [string]$MailboxName,
[Parameter(Position=1, Mandatory=$true)] [System.Management.Automation.PSCredential]$Credentials,
[Parameter(Position=2, Mandatory=$false)] [string]$url
)
Begin
{
Load-EWSManagedAPI
## Set Exchange Version
$ExchangeVersion = [Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2013
## 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($Credentials.UserName.ToString(),$Credentials.GetNetworkCredential().password.ToString())
$service.Credentials = $creds
#Credentials Option 2
#service.UseDefaultCredentials = $true
#$service.TraceEnabled = $true
## Choose to ignore any SSL Warning issues caused by Self Signed Certificates
Handle-SSL
## 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
if($url){
$uri=[system.URI] $url
$service.Url = $uri
}
else{
$service.AutodiscoverUrl($MailboxName,{$true})
}
Write-host ("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)
if(!$service.URL){
throw "Error connecting to EWS"
}
else
{
return $service
}
}
}
function Load-EWSManagedAPI{
param(
)
Begin
{
## 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
}
}
}
function Handle-SSL{
param(
)
Begin
{
## 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
}
}
function Send-VoteMail {
param(
[Parameter(Position=0, Mandatory=$true)] [string]$MailboxName,
[Parameter(Mandatory=$true)] [System.Management.Automation.PSCredential]$Credentials,
[Parameter(Position=2, Mandatory=$false)] [switch]$useImpersonation,
[Parameter(Position=3, Mandatory=$false)] [string]$url,
[Parameter(Position=4, Mandatory=$false)] [string]$Subject,
[Parameter(Position=5, Mandatory=$false)] [string]$Body,
[Parameter(Position=6, Mandatory=$false)] [string]$To,
[Parameter(Position=7, Mandatory=$false)] [psobject]$Verbs
)
Begin
{
if($url){
$service = Connect-Exchange -MailboxName $MailboxName -Credentials $Credentials -url $url
}
else{
$service = Connect-Exchange -MailboxName $MailboxName -Credentials $Credentials
}
if($useImpersonation.IsPresent){
$service.ImpersonatedUserId = new-object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $MailboxName)
}
$EmailMessage = New-Object Microsoft.Exchange.WebServices.Data.EmailMessage -ArgumentList $service
$VerbStreamProp = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition([Microsoft.Exchange.WebServices.Data.DefaultExtendedPropertySet]::Common,0x8520, [Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Binary)
$VerbSettingValue = get-VerbStream -MessageClass IPM.Note -VerbArray $Verbs
$EmailMessage.Subject = $Subject
#Add Recipients
$EmailMessage.ToRecipients.Add($To)
$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()
}
}
function get-VerbStream {
[CmdletBinding()]
param (
[Parameter(Position = 0, Mandatory = $true)]
[string]
$MessageClass,
[Parameter(Position = 1, Mandatory = $true)]
[psobject]
$VerbArray
)
Begin
{
$vCount = ($VerbArray.length + 4);
$Header = "02010" + $vCount + "00000000000000";
$ReplyToAllHeader = "055265706C790849504D2E4E6F7465074D657373616765025245050000000000000000";
$ReplyToAllFooter = "0000000000000002000000660000000200000001000000";
$ReplyToHeader = "0C5265706C7920746F20416C6C0849504D2E4E6F7465074D657373616765025245050000000000000000";
$ReplyToFooter = "0000000000000002000000670000000300000002000000";
$ForwardHeader = "07466F72776172640849504D2E4E6F7465074D657373616765024657050000000000000000";
$ForwardFooter = "0000000000000002000000680000000400000003000000";
$ReplyToFolderHeader = "0F5265706C7920746F20466F6C6465720849504D2E506F737404506F737400050000000000000000";
$ReplyToFolderFooter = "00000000000000020000006C00000008000000";
$VoteOptionExtras = "0401055200650070006C00790002520045000C5200650070006C007900200074006F00200041006C006C0002520045000746006F007200770061007200640002460057000F5200650070006C007900200074006F00200046006F006C0064006500720000";
$DisableReplyAllVal = "00";
$DisableReplyAllVal = "01";
$DisableReplyVal = "00";
$DisableReplyVal = "01";
$DisableForwardVal = "00";
$DisableForwardVal = "01";
$DisableReplyToFolderVal = "00";
$DisableReplyToFolderVal = "01";
$OptionsVerbs = "";
$VerbValue = $Header + $ReplyToAllHeader + $DisableReplyAllVal + $ReplyToAllFooter + $ReplyToHeader + $DisableReplyVal + $ReplyToFooter + $ForwardHeader + $DisableForwardVal + $ForwardFooter + $ReplyToFolderHeader + $DisableReplyToFolderVal + $ReplyToFolderFooter;
for ($index = 0; $index -lt $VerbArray.length; $index++) {
$VerbValue += GetWordVerb -Word $VerbArray[$index] -Postion ($index + 1) -MessageClass $MessageClass
$VbValA = convertToHexUnicode($VerbArray[$index])
$VbhVal = decimalToHexString($VerbArray[$index].length)
$vbValB = convertToHexUnicode($VerbArray[$index])
$vbPos = decimalToHexString($VerbArray[$index].length)
$OptionsVerbs += $vbPos + $VbValA + $VbhVal + $vbValB
}
$VerbValue += $VoteOptionExtras + $OptionsVerbs;
return $VerbValue;
}
}
function GetWordVerb {
[CmdletBinding()]
param (
[Parameter(Position = 0, Mandatory = $true)]
[string]
$Word,
[Parameter(Position = 1, Mandatory = $true)]
[decimal]
$Postion,
[Parameter(Position = 2, Mandatory = $true)]
[psobject]
$MessageClass
)
Begin
{
$verbstart = "04000000";
$length = decimalToHexString($Word.length);
$HexString = [System.BitConverter]::ToString([System.Text.UnicodeEncoding]::ASCII.GetBytes($Word)).Replace("-","")
$mclength = decimalToHexString($MessageClass.length);
$mcHexString = [System.BitConverter]::ToString([System.Text.UnicodeEncoding]::ASCII.GetBytes($MessageClass)).Replace("-","")
$Option1 = "000000000000000000010000000200000002000000";
$Option2 = "000000FFFFFFFF";
$lo = decimalToHexString -number $Postion
return ($verbstart + $length + $HexString + $mclength + $mcHexString + "00" + $length + $HexString + $Option1 + $lo + $Option2) ;
}
}
function decimalToHexString {
[CmdletBinding()]
param (
[Parameter(Position = 1, Mandatory = $true)]
[Int]
$number
)
Begin{
if ($number -lt 0) {
$number = 0xFFFFFFFF + $number + 1;
}
$numberret = "{0:x}" -f $number
if ($numberret.length -eq 1) {
$numberret = "0" + $numberret;
}
return $numberret;
}
}
function convertToHexUnicode {
[CmdletBinding()]
param (
[Parameter(Position = 1, Mandatory = $true)]
[String]
$str
)
Begin{
$hex = [System.BitConverter]::ToString([System.Text.UnicodeEncoding]::Unicode.GetBytes($str)).Replace("-","")
return $hex;
}
}
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
}