I don't know how good your PowerShell has gotten, but the script below, with a
little fiddling with $StartDate and $EndDate along with Measure-Object and
Group-Object, should be able to give you exactly what you want, based on your
description. :)
This is the same script I gave Candee (I think it was Candee) last month.
##
## Dump-Calendar.ps1
##
## Michael B. Smith
## michael at TheEssentialExchange dot com
## November, 2014
##
## Provided as-is. No warranties, express or implied, are available.
##
param
(
[DateTime]$StartDate = ( Get-Date -Year 1970 -Month 1 -Day 1
-Hour 8 -Minute 0 -Second 0 ),
[DateTime]$EndDate = ( Get-Date ),
[bool]$useDefaultCredentials = $true,
[bool]$IsRecurring = $true,
[bool]$FilterRecurring = $false,
[string]$ewsURL = 'https://server2/ews/exchange.asmx'
)
Set-StrictMode -Version 2.0
function Connect-EWS
{
## Load EWS Managed API
Add-Type -Path "C:\Program Files\Microsoft\Exchange\Web
Services\2.2\Microsoft.Exchange.WebServices.dll"
## Set minimum EWS managed API Version
$Version =
[Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010_SP2
## Create Exchange Service Object
$script:service = New-Object
Microsoft.Exchange.WebServices.Data.ExchangeService( $Version )
if( $service -eq $null )
{
throw $error[ 0 ]
}
if( $useDefaultCredentials )
{
$script:service.useDefaultCredentials = $true
}
else
{
## FIXME
## $service.Credentials = ????
}
## define a couple of well-known folders
$script:wkf_Inbox =
[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox
$script:wkf_Calendar =
[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Calendar
}
function Set-myCertificatePolicy
{
## 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.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
$script:TrustAll = $TAAssembly.CreateInstance(
'Local.CertificatePolicy.TrustAll' )
[System.Net.ServicePointManager]::CertificatePolicy = $script:TrustAll
## end code from http://poshcode.org/624
}
## Main
Connect-EWS
Set-myCertificatePolicy
$mailboxes = Get-Mailbox -ResultSize Unlimited
## Get the EWS URL. Use either AutoD or a hardcoded EWS URL
if( [String]::IsNullOrEmpty( $ewsURL ) )
{
$mailboxSmtp = $mailboxes[ 0 ].PrimarySmtpAddress.ToString()
$service.AutodiscoverUrl( $mailboxSmtp, $true )
Write-Host "Using AutoD EWS Server :" $Service.url
}
else
{
$uri = [System.URI] $ewsURL
$service.Url = $uri
Write-Host "Using parameterized EWS server :" $ewsURL
}
$start = Get-Date
$i = 0
foreach( $mailbox in $mailboxes )
{
$i += 1
$Duration = ( New-TimeSpan -Start ($start) -End (Get-Date)
).TotalSeconds
$TimeLeft = ( $Duration / $i ) * ( $mailboxes.Count - $i )
Write-Progress -Status $mailbox.DisplayName `
-Activity "Mailbox $i of $($mailboxes.Count)" `
-PercentComplete ( $i / $mailboxes.Count * 100
) `
-SecondsRemaining $timeleft `
-Id 100
## FIXME - impersonation? or admin perms? I don't care, but
decide
## Optional section for Exchange Impersonation
## $service.ImpersonatedUserId = new-object
Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress,
$Mailbox.PrimarySMTPAddress)
$folderid = $null ## clear value (if any) from prior iteration
$calendar = $null ## clear value (if any) from prior iteration
try
{
$folderid = New-Object
Microsoft.Exchange.WebServices.Data.FolderId( $wkf_Calendar,
$mailbox.PrimarySMTPAddress.ToString() )
$calendar =
[Microsoft.Exchange.WebServices.Data.Folder]::Bind( $service, $folderid )
}
catch
{
Write-Host "Could not bind to Calendar for"
$mailbox.PrimarySMTPAddress.ToString()
continue
}
##$calendar | fl * -force
##$global:saveCal = $calendar
##$global:saveEWS = $service
##$global:propSet = $calPropSet
Write-Host "Bound to Calendar for"
$mailbox.PrimarySMTPAddress.ToString()
Write-Host ".... total items in Calendar
$($calendar.TotalCount)"
if( $calendar.TotalCount -eq 0 )
{
continue
}
$calPropSet = New-Object
Microsoft.Exchange.WebServices.Data.PropertySet( `
[Microsoft.Exchange.WebServices.Data.BasePropertySet
]::IdOnly, `
[Microsoft.Exchange.WebServices.Data.ItemSchema
]::Subject, `
[Microsoft.Exchange.WebServices.Data.ItemSchema
]::DateTimeCreated, `
[Microsoft.Exchange.WebServices.Data.ItemSchema
]::Id, `
[Microsoft.Exchange.WebServices.Data.AppointmentSchema]::AppointmentState,
`
[Microsoft.Exchange.WebServices.Data.AppointmentSchema]::AppointmentType,
`
[Microsoft.Exchange.WebServices.Data.AppointmentSchema]::End,
`
[Microsoft.Exchange.WebServices.Data.AppointmentSchema]::Start,
`
[Microsoft.Exchange.WebServices.Data.AppointmentSchema]::IsRecurring,
`
[Microsoft.Exchange.WebServices.Data.AppointmentSchema]::Location,
`
[Microsoft.Exchange.WebServices.Data.AppointmentSchema]::Organizer
)
##
[Microsoft.Exchange.WebServices.Data.AppointmentSchema]::
### a calendar view is limited to two years
### so to look at an entire calendar is a bit of a hassle
### we just examine $EndDate - 730 days worth of data (or up to
1000 calendar items)
### $StartDate = $EndDate.AddDays( -730 )
$calView = $null
$calView = New-Object
Microsoft.Exchange.WebServices.Data.CalendarView( $StartDate, $EndDate, 1000 )
$calView.PropertySet = $calPropSet
$global:Collection = $null
$global:Collection = $calendar.FindAppointments( $calView )
$count = 0
foreach( $appointment in $Collection.Items )
{
if( $FilterRecurring -and ( $appointment.IsRecurring
-eq $IsRecurring ) )
{
continue
}
##$appointment | ft Subject, IsRecurring,
## AppointmentType, AppointmentState,
## Location, Organizer
$count += 1
Write-Progress -Status $mailbox.DisplayName `
-Activity "Mailbox $i of
$($mailboxes.Count)" `
-PercentComplete ( $i/ $mailboxes.count
* 100 ) `
-SecondsRemaining $timeleft `
-Id 100 `
-CurrentOperation "Processing
calendarItem $count of $($Collection.Items.Count)"
$obj = "" | Select Id, Subject, `
AppointmentState, AppointmentType, `
Start, End, DateTimeCreated, `
IsRecurring, `
Location, Organizer
$obj.Id = $appointment.Id
$obj.Subject = $appointment.Subject
$obj.AppointmentState = $appointment.AppointmentState
$obj.AppointmentType = $appointment.AppointmentType
$obj.Start = $appointment.Start
$obj.End = $appointment.End
$obj.DateTimeCreated = $appointment.DateTimeCreated
$obj.IsRecurring = $appointment.IsRecurring
$obj.Location = $appointment.Location
$obj.Organizer = $appointment.Organizer
Write-Output $obj
}
} ## foreach( $mailbox in $mailboxes )