I am currently trying to send an email through powershell with a populated mileage field in order for outlook to pick up on.
The email goes through fine but I am unable to get a value through for the 'Mileage' Field.
$SMTPName = ''
$EmailMessage = new-object Net.Mail.MailMessage
$SMTPServer = new-object Net.Mail.SmtpClient($SMTPName)
$EmailMessage.Headers.Add("Mileage", "HB")
$EmailMessage.From = ''
$EmailMessage.To.Add('')
$EmailMessage.Subject = $sub
$EmailMessage.Body = $body
$EmailMessage.Priority = [System.Net.Mail.MailPriority]::High
$SMTPServer.Send($EmailMessage)
Mileage is a MAPI property so you will need to send the message with either Outlook or EWS eg the following should work to send a message with that property set in EWS
## Get the Mailbox to Access from the 1st commandline argument
$MailboxName = $args[0]
## Load Managed API dll
Add-Type -Path "C:\Program Files\Microsoft\Exchange\Web Services\1.2\Microsoft.Exchange.WebServices.dll"
## 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)
$EmailMessage = New-Object Microsoft.Exchange.WebServices.Data.EmailMessage -ArgumentList $service
$EmailMessage.Subject = "Message Subject"
#Add Recipients
$EmailMessage.ToRecipients.Add("user#domain.com")
$EmailMessage.Body = New-Object Microsoft.Exchange.WebServices.Data.MessageBody
$EmailMessage.Body.BodyType = [Microsoft.Exchange.WebServices.Data.BodyType]::HTML
$EmailMessage.Body.Text = "Body"
$Mileage = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition([Microsoft.Exchange.WebServices.Data.DefaultExtendedPropertySet]::Common,34100,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String);
$EmailMessage.SetExtendedProperty($Mileage,"HB")
$EmailMessage.SendAndSaveCopy() enter code here
Related
I have this code to send email with attachment:-
$encpassword = convertto-securestring -String "*****" -AsPlainText -Force
$cred = new-object -typename System.Management.Automation.PSCredential -argumentlist "***#***", $encpassword
Connect-PnPOnline -Url $sourceWebURL -Credentials $cred
Send-MailMessage -to "" -from "" -Credentials $cred -bcc "" -Port "587" -UseSSL "true" -Subject "subject" -Body "<b>1</b><br><b>2</b>" -BodyAsHtml -SmtpServer "smtp.office365.com" -Attachments "C:\s.csv"
but based on the documentation's warning that Send-MailMessage is obsolete # https://learn.microsoft.com/en-us/powershell/module/microsoft.powershell.utility/send-mailmessage?view=powershell-7.3
and at the same time using Send-PnPMail does not support sending attachments # https://pnp.github.io/powershell/cmdlets/Send-PnPMail.html .
so my question is how we can send an email using power shell using a supported/recommended approach which allow us to attach a file.
Thanks
What the Send-MailMessage documentation's warning that Send-MailMessage is obsolete fails to mention is the underlying reason as to why it is now obsolete. For example, Send-MailMessage still works just fine when you continue to connect to your on-premise Exchange Server so why the message?
The reason is as part of Microsoft’s "Secure by Default" policy, Microsoft is permanently disabling Basic Authentication in Exchange Online for everyone on October 1, 2022 (Basic Authentication and Exchange Online – September 2021 Update - Microsoft Tech Community).
This includes Exchange Web Services (EWS), Exchange ActiveSync (EAS), POP, IMAP, Remote PowerShell, MAPI, RPC, SMTP AUTH, and OAB. All client applications need to switch to Modern Authentication/OAuth or Microsoft Graph API to continue to function.
Send-MailMessage uses Basic Authentication (Username and password with an option to use SSL) but wasn't made to use Modern Authentication methods. It was primarily designed to work with on-premise Exchange Servers and didn't have to worry about those pesky things like MFA or options for using key/value/tokens for authentication. Therefore, it's use is now obsolete when trying to use it with Exchange Online/O365 servers.
The O365 supported method is to use Microsoft Graph to send the message with attachment. It's a little more complicated than a vanilla Send-MailMessage, because you need to use JSON to create the configuration. You also need to convert the file Attachment to a Base64 encoded string so that it can be added to the JSON message.
Import-Module Microsoft.Graph.Users.Actions
Connect-MgGraph
#Convert File to Base64
$filename = "C:\attachment.csv"
$filenameBase64string = [Convert]::ToBase64String([IO.File]::ReadAllBytes($filename))
$params = #{
Message = #{
Subject = "Important Attachment"
Body = #{
ContentType = "html"
Content = "Please find <b>Important Document</b> attached"
}
ToRecipients = #(
#{
EmailAddress = #{
Address = "johnGu#contoso.com"
}
}
)
Attachments = #(
#{
"#odata.type" = "#microsoft.graph.fileAttachment"
Name = "attachment.csv"
ContentType = "text/plain"
ContentBytes = $filenameBase64string
}
)
}
}
Send-MgUserMail -UserId johnGu#contoso.com -BodyParameter $params
This is now done with Send-MgUserMail which is from the Microsoft Graph PowerShell module Microsoft.Graph.Users.Actions.
Example 3: Create a message with a file attachment and send the message
Import-Module Microsoft.Graph.Users.Actions
$params = #{
Message = #{
Subject = "Meet for lunch?"
Body = #{
ContentType = "Text"
Content = "The new cafeteria is open."
}
ToRecipients = #(
#{
EmailAddress = #{
Address = "meganb#contoso.onmicrosoft.com"
}
}
)
Attachments = #(
#{
"#odata.type" = "#microsoft.graph.fileAttachment"
Name = "attachment.txt"
ContentType = "text/plain"
ContentBytes = "SGVsbG8gV29ybGQh"
}
)
}
}
# A UPN can also be used as -UserId.
Send-MgUserMail -UserId $userId -BodyParameter $params
Okay so i'm trying to send one email using powershell v2 to some recipients in a text file named emailtargets formatted in new line. below is the sendmailer script.
$emailSmtpServer = "mail.xxxxxxxxx.com"
$emailSmtpServerPort = "587"
$SourceRCPT = "xxxxx#xxxxxxxxx.com"
$DestFile = "emailTargets.txt"
$BodyFile = "emailBody.txt"
$SubjectLine = "testing"
$Pass = "xxxxxxx"
# Start Loop for Email Sending
$file = Get-Content $DestFile
$body = Get-Content $BodyFile
foreach ($line in $file){
$DestinationRCPT = $line.Split(",")[0]
$firstName = $line.Split(",")[1]
$lastName = $line.Split(",")[2]
$body =(Get-Content $BodyFile) | foreach-object {$_ -replace '\[firstName\]',$firstName}| foreach-object {$_ -replace '\[lastName\]',$lastName}
$emailSmtpUser = "$SourceRCPT"
$emailSmtpPass = "$Pass"
$emailFrom = "$SourceRCPT"
$emailTo = "$DestinationRCPT"
$emailMessage = New-Object System.Net.Mail.MailMessage( $emailFrom , $emailTo )
$emailMessage.Subject = $SubjectLine
$emailMessage.IsBodyHtml = $true
$emailMessage.Body = $body
$SMTPClient = New-Object System.Net.Mail.SmtpClient( $emailSmtpServer , $emailSmtpServerPort )
$SMTPClient.EnableSsl = $true
$SMTPClient.Credentials = New-Object System.Net.NetworkCredential( $emailSmtpUser.Split("#")[0] , $emailSmtpPass );
$SMTPClient.Send( $emailMessage )
Write-Host "Sending Email to $DestinationRCPT"
Now the question is i keep getting the error below while testing with office 365
And i get the below error while testing with a different smtp server
What am i doing wrong?
Its a certificate validation issue, If you are okay in suppressing it, you can do
[System.Net.ServicePointManager]::ServerCertificateValidationCallback = {$true}
before sending the message.
Here a set of samples that should assist you in re-writing this to function.
Overview of Cmdlets Available in Windows PowerShell Windows
PowerShell 2.0
https://technet.microsoft.com/en-us/library/ff714569.aspx
Use this example
https://gallery.technet.microsoft.com/scriptcenter/Send-MailMessage-3a920a6d
...
$params = #{
InlineAttachments = $images
Attachments = 'C:\temp\attachment1.txt', 'C:\temp\attachment2.txt'
Body = $body
BodyAsHtml = $true
Subject = 'Test email'
From = 'username#gmail.com'
To = 'recipient#domain.com'
Cc = 'recipient2#domain.com', 'recipient3#domain.com'
SmtpServer = 'smtp.gmail.com'
Port = 587
Credential = (Get-Credential -Credential 'username#gmail.com')
UseSsl = $true
}
Send-MailMessage #params
Or
# Using the PS built-in / online help files.
Get-Command -Name Send-MailMessage
CommandType Name Version Source
----------- ---- ------- ------
Cmdlet Send-MailMessage
3.1.0.0 Microsoft.PowerShell.Utility
# get function / cmdlet details
(Get-Command -Name Send-MailMessage).Parameters.Keys
Attachments
Bcc
Body
BodyAsHtml
Encoding
Cc
DeliveryNotificationOption
From
SmtpServer
Priority
Subject
To
Credential
UseSsl
Port
Verbose
Debug
ErrorAction
WarningAction
InformationAction
ErrorVariable
WarningVariable
InformationVariable
OutVariable
OutBuffer
PipelineVariable
# Get the examples and modify per your use case, splatting used to make it easier to read on the forum.
Get-help -Name Send-MailMessage -Examples
# Example 1: Send an email from one user to another
$Params = #{
To = "User01 <user01#example.com>"
From = "User02 <user02#example.com>"
Subject = "Test mail"
Credential = (Get-Credential -Credential 'user#fabrikam.com')
SmtpServer = "smtp.fabrikam.com"
UseSsl = $true
Port = 587
}
Send-MailMessage #Params
# This command sends an email message from User01 to User02.
#
# The mail message has a subject, which is required, but it does not have a
# body, which is optional. Also, because the SmtpServer parameter is not
# specified,
#
# Send-MailMessage uses the value of the $PSEmailServer preference variable
# for the SMTP server.
# Example 2: Send an attachment
$Params = #{
From = "User01 <user01#example.com>"
To = "User02 <user02#example.com>", "User03 <user03#example.com>"
Subject = "Sending the Attachment"
Body = "Forgot to send the attachment. Sending now."
Attachments = "data.csv"
Priority = High
dno = 'onSuccess, onFailure'
Credential = (Get-Credential -Credential 'user#fabrikam.com')
SmtpServer = "smtp.fabrikam.com"
UseSsl = $true
Port = 587
}
Send-MailMessage #Params
# This command sends an email message with an attachment from User01 to two
# other users.
# It specifies a priority value of High and requests a delivery notification
# by email when the email messages are delivered or when they fail.
# Example 3: Send email to a mailing list
$Params = #{
To = "User01 <user01#example.com>"
From = "ITGroup <itdept#example.com>"
Cc = "User02 <user02#example.com>"
bcc = "ITMgr <itmgr#example.com>"
Subject = "Don't forget today's meeting!"
Credential = 'domain01\admin01'
UseSsl = $true
SmtpServer = "smtp.fabrikam.com"
Port = 587
}
Send-MailMessage #Params
# This command sends an email message from User01 to the ITGroup mailing list
# with a copy (Cc) to User02 and a blind carbon copy (Bcc) to the IT manager
# (ITMgr).
#
# The command uses the credentials of a domain administrator and the UseSsl
# parameter.
Get-help -Name Send-MailMessage -Full
Get-help -Name Send-MailMessage -Online
I have installed SMTP Virtual Server in windows server 2012 r2. Later I have used following PowerShell script to send the email. Which was successful
$email = "xxxxxxxxxx#xxxxxx.com"
$pass = "xxxxxxx"
$smtpServer = "smtp.office365.com"
$smtpPort = "25"
$msg = new-object Net.Mail.MailMessage
$smtp = new-object Net.Mail.SmtpClient($smtpServer)
$smtp.EnableSsl = $true
$msg.From = "$email"
$attachment = New-Object Net.Mail.Attachment("C:abcd/123.txt");
$msg.Attachments.Add($attachment);
$msg.To.Add("xxxx#xxxxx.com")
$msg.BodyEncoding = [system.Text.Encoding]::Unicode
$msg.SubjectEncoding = [system.Text.Encoding]::Unicode
$msg.IsBodyHTML = $true
$msg.Subject ="List of users"
$msg.Body=$msg.Body = "<h2> hi everyone </h2>
$SMTP.Credentials = New-Object System.Net.NetworkCredential("$email", "$pass");
$smtp.Send($msg)
here my question is can I send email without using from address in the above script(Is there any chance to save from email address and credentials somewhere in SMTP virtual server settings so that script can take credentials directly). I don't want to use from email address and credentials in above script
I'd suggest using Send-MailMessage instead of manual .NET manipulation:
$Creds = Import-CliXml -Path 'C:\mycreds.xml'
$MailArgs = #{ 'SmtpServer' = 'smtp.office365.com'
'Port' = 25
'To' = 'xxxx#xxxxx.com'
'From' = $Creds.UserName
'Subject' = 'List of users'
'Attachments' = 'C:\abcd\123.txt'
'Body' = '<h2> hi everyone </h2>'
'Encoding' = [Text.Encoding]::Unicode
'BodyAsHtml' = $true
'UseSsl' = $true
'Credential' = $Creds
}
Send-MailMessage #MailArgs
And you would create your $Creds object as follows:
Get-Credential -Credential 'xxxxxxxxxx#xxxxxx.com' | Export-CliXml -Path 'C:\mycreds.xml'
There are a couple extra options you might be interested in (such as notification of delivery) you can read about in the doc linked above.
Additionally, your password is encrypted when exported using Export-CliXml specific to that device and account utilizing DPAPI.
What I am hoping to do is once a new email hits a folder containing a specific subject. That email is then forwarded to another inbox and a specific file is automatically attached. The code I have been able to cobble together so far is this. Is a .Net method the appropriate method to achieve my goal or would using Send-MailMessge to a hastable be better method? I am new to PowerShell code I am able to get both methods to work. But was wondering A. which method is preferred. B. is there a better/more efficient way?
#####Define Variables########
$fromaddress = "donotreply#fromemail.com"
$toaddress = "blah#toemail.com"
$bccaddress = "blah#bcc.com"
$CCaddress = "blah#cc.com"
$Subject = "ACtion Required"
$body = get-content .\content.htm
$attachment = "C:\sendemail\test.txt"
$smtpserver = "smtp.labtest.com"
##############################
$message = new-object System.Net.Mail.MailMessage
$message.From = $fromaddress
$message.To.Add($toaddress)
$message.CC.Add($CCaddress)
$message.Bcc.Add($bccaddress)
$message.IsBodyHtml = $True
$message.Subject = $Subject
$attach = new-object Net.Mail.Attachment($attachment)
$message.Attachments.Add($attach)
$message.body = $body
$smtp = new-object Net.Mail.SmtpClient($smtpserver)
$smtp.Send($message)
(Example of the hashtable method
$emailHashSplat = #{ To = $toAddress
From = $fromAddress
Subject = $emailSubject
Body = $emailBody SMTPServer = $smtpServer BodyAsHtml =
$true Attachments = "C:\sendemail\test.txt" # Attachments =)
Stick with Powershell commands whenever possible, .NET might be faster in some cases but it is a best practice to use only Powershell commands when possible.
Also make sure your code is easy to read and understand by others, using hastables with splatting wil help with this, see the following example: Github Gist Link (Click Me!)
Copy of the code, in case of link failure.
### Script Global Settings
#Declare SMTP Connection Settings
$SMTPConnection = #{
#Use Office365, Gmail, Other or OnPremise SMTP Relay FQDN
SmtpServer = 'outlook.office365.com'
#OnPrem SMTP Relay usually uses port 25 without SSL
#Other Public SMTP Relays usually use SSL with a specific port such as 587 or 443
Port = 587
UseSsl = $true
#Option A: Query for Credential at run time.
Credential = Get-Credential -Message 'Enter SMTP Login' -UserName "emailaddress#domain.tld"
<#
#Option B: Hardcoded Credential based on a SecureString
Credential = New-Object -TypeName "System.Management.Automation.PSCredential" -ArgumentList #(
#The SMTP User Emailaddress
"emailaddress#domain.tld"
#The Password as SecureString encoded by the user that wil run this script!
#To create a SecureString Use the folowing Command: Read-Host "Enter Password" -AsSecureString | ConvertFrom-SecureString
"Enter the SecureString here as a single line" | ConvertTo-SecureString
)
#>
}
### Script Variables
#Declare Mailmessages.
$MailMessageA = #{
From = "emailaddress#domain.tld"
To = #(
"emailaddress#domain.tld"
)
#Cc = #(
# "emailaddress#domain.tld"
#)
#Bcc = #(
# "emailaddress#domain.tld"
#)
Subject = 'Mailmessage from script'
#Priority = 'Normal' #Normal by default, options: High, Low, Normal
#Attachments = #(
#'FilePath'
#)
#InlineAttachments = #{
#'CIDA'='FilePath'
#} #For more information about inline attachments in mailmessages see: https://gallery.technet.microsoft.com/scriptcenter/Send-MailMessage-3a920a6d
BodyAsHtml = $true
Body = "Something Unexpected Occured as no Content has been Provided for this Mail Message!" #Default Message
}
### Script Start
#Retrieve Powershell Version Information and store it as HTML with Special CSS Class
$PSVersionTable_HTLM = ($PSVersionTable.Values | ConvertTo-Html -Fragment) -replace '<table>', '<table class="table">'
#Retrieve CSS Stylesheet
$CSS = Invoke-WebRequest "https://raw.githubusercontent.com/advancedrei/BootstrapForEmail/master/Stylesheet/bootstrap-email.min.css" | Select-Object -ExpandProperty Content
#Build HTML Mail Message and Apply it to the MailMessage HashTable
$MailMessageA.Body = ConvertTo-Html -Title $MailMessageA.Subject -Head "<style>$($CSS)</style>" -Body "
<p>
Hello World,
</p>
<p>
If your recieved this message then this script works.</br>
</br>
<div class='alert alert-info' role='alert'>
Powershell version
</div>
$($PSVersionTable_HTLM)
</P>
" | Out-String
#Send MailMessage
#This example uses the HashTable's with a technique called Splatting to match/bind the Key's in the HashTable with the Parameters of the command.
#Use the # Symbol instead of $ to invoke Splatting, Splatting improves readability and allows for better management and reuse of variables
Send-MailMessage #SMTPConnection #MailMessageA
I'm trying to retrieve all appointments existing on a calendar in the organization's public folders, for reporting purposes.
Exchange 2010's Powershell cmdlet Get-PublicFolderItemStatistics does return some of the information I need, but it seems like the returned objects are missing some of the properties that should exist on the Appointment object, even though I do see their values on the appointment in Outlook (also 2010).
Specifically, I need the Start and End date properties, which are coming back blank.
An example:
Get-PublicFolderItemStatistics -identity "\30 Day" | Sort-Object CreationTime | Format-List
Returns:
ServerName : EXCHANGE1
DatabaseName : Public Folder Database 167851469
Subject : Test 30
PublicFolderName : \30 Day
LastModificationTime : 1/19/2015 3:05:05 PM
CreationTime : 1/19/2015 3:05:05 PM
HasAttachments : False
ItemType : IPM.Appointment
MessageSize : 5.47 KB (5,601 bytes)
Identity : (removed)
MapiIdentity : (removed)
OriginatingServer : exchange1.mydomain.local
IsValid : True
ObjectState : Changed
And:
Get-PublicFolderItemStatistics -identity "\30 Day" | Sort-Object CreationTime | Format-List Subject,CreationTime,Start,End
Returns:
Subject : Test 30
CreationTime : 1/19/2015 3:05:05 PM
Start :
End :
However the appointment in Outlook shows the Start and End times correctly:
Is there a way to retrieve this information from the server side? I was hoping to avoid Outlook interop if possible.
That cmdlet only returns a limited subset of Item properties if you want anything else you will need to use a client API like EWS or the outlook OOM to access the Public folder and the contents. To use a client API against the folder you will need to have rights to that folder then you can use something like this in EWS and Powershell
## Get the Mailbox to Access from the 1st commandline argument
$MailboxName = $args[0]
## 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 FolderIdFromPath{
param (
$FolderPath = "$( throw 'Folder Path is a mandatory Parameter' )"
)
process{
## Find and Bind to Folder based on Path
#Define the path to search should be seperated with \
$folderid = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::PublicFoldersRoot)
$tfTargetFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)
#Split the Search path into an array
$fldArray = $FolderPath.Split("\")
#Loop through the Split Array and do a Search for each level of folder
for ($lint = 1; $lint -lt $fldArray.Length; $lint++) {
#Perform search based on the displayname of each folder level
$fvFolderView = new-object Microsoft.Exchange.WebServices.Data.FolderView(1)
$SfSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,$fldArray[$lint])
$findFolderResults = $service.FindFolders($tfTargetFolder.Id,$SfSearchFilter,$fvFolderView)
if ($findFolderResults.TotalCount -gt 0){
foreach($folder in $findFolderResults.Folders){
$tfTargetFolder = $folder
}
}
else{
"Error Folder Not Found"
return $null
}
}
if($tfTargetFolder -ne $null){
return $tfTargetFolder.Id.UniqueId.ToString()
}
}
}
#Example use
$fldId = FolderIdFromPath -FolderPath "\test\calendar"
$SubFolderId = new-object Microsoft.Exchange.WebServices.Data.FolderId($fldId)
$SubFolder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$SubFolderId)
if($SubFolder -ne $null){
#Define ItemView to retrive just 1000 Items
$ivItemView = New-Object Microsoft.Exchange.WebServices.Data.ItemView(1000)
$fiItems = $null
do{
$fiItems = $service.FindItems($SubFolder.Id,$ivItemView)
#[Void]$service.LoadPropertiesForItems($fiItems,$psPropset)
foreach($Item in $fiItems.Items){
$Item.Subject + " " + $Item.Start
}
$ivItemView.Offset += $fiItems.Items.Count
}while($fiItems.MoreAvailable -eq $true)
}
Cheers
Glen