Scenario: You want to use a EWS Script to perform two functions:
-Calculate the total size of the mailbox per year. This includes both the Mailbox and the Mailbox Dumpster.
-Export a PST for each year. If the size of the yearly emails exceeds 10GB, adjust the dates within that year so each export for that year is under 10GB.
Script:
#Edit Variables############################
$mailboxname = “steve@domain.com”
$Export_Log = “C:tempMbx_Size_Years.csv”
$Export_PST = “\ExServerPSTFiles”
$PSTFilePath = $Export_PST
$Batchname = “Steve”
$Size_for_PST = [int]10240
$PST_Final = @()
$EWSServer = “https://mail.domain.com/EWS/Exchange.asmx”
##########################################
#Paste the Script#########################
Write-host “Starting $Mailboxname” -ForegroundColor Cyan
Import-Module -Name “C:Program FilesMicrosoftExchange ServerV15BinMicrosoft.Exchange.WebServices.dll”
$service = new-object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.Exchangeversion]::exchange2013)
$service.Url = new-object System.Uri($EwsServer)
$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
#CAS URL Option 1 Autodiscover
$service.AutodiscoverUrl($MailboxName,{$true})
“Using CAS Server : ” + $Service.url
# Bind to the Inbox Folder
$folderid= new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Inbox,$MailboxName)
$Inbox = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$folderid)
#Define ItemView to retrive just 1000 Items
$ivItemView = New-Object Microsoft.Exchange.WebServices.Data.ItemView(1000)
$psPropset= new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::IdOnly)
$psPropset.Add([Microsoft.Exchange.WebServices.Data.ItemSchema]::Size)
$psPropset.Add([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived)
$psPropset.Add([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeCreated)
$ivItemView.PropertySet = $psPropset
$TotalSize = 0
$TotalItemCount = 0
#Define Function to convert String to FolderPath
function ConvertToString($ipInputString){
$Val1Text = “”
for ($clInt=0;$clInt -lt $ipInputString.length;$clInt++){
$Val1Text = $Val1Text + [Convert]::ToString([Convert]::ToChar([Convert]::ToInt32($ipInputString.Substring($clInt,2),16)))
$clInt++
}
return $Val1Text
}
#Define Extended properties
$PR_FOLDER_TYPE = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(13825,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Integer);
$folderidcnt = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::MsgFolderRoot,$MailboxName)
$folderidcnt_r = new-object Microsoft.Exchange.WebServices.Data.FolderId([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::RecoverableItemsRoot,$MailboxName)
#Define the FolderView used for Export should not be any larger then 1000 folders due to throttling
$fvFolderView = New-Object Microsoft.Exchange.WebServices.Data.FolderView(1000)
#Deep Transval will ensure all folders in the search path are returned
$fvFolderView.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Deep;
$psPropertySet = new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
$PR_Folder_Path = new-object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(26293, [Microsoft.Exchange.WebServices.Data.MapiPropertyType]::String);
#Add Properties to the Property Set
$psPropertySet.Add($PR_Folder_Path);
$fvFolderView.PropertySet = $psPropertySet;
#The Search filter will exclude any Search Folders
$sfSearchFilter = new-object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo($PR_FOLDER_TYPE,”1″)
$fiResult = $null
$rptHash = @{}
$minYear = (Get-Date).Year
$maxYear = (Get-Date).Year
#The Do loop will handle any paging that is required if there are more the 1000 folders in a mailbox
do {
$fiResult = $Service.FindFolders($folderidcnt,$sfSearchFilter,$fvFolderView)
$fiResult2 = $Service.FindFolders($folderidcnt_r,$sfSearchFilter,$fvFolderView)
$collection_folders = @()
$Collection_Folders = $firesult.folders
$Collection_Folders += $firesult2.folders
$firesult3 = @()
$firesult3 = $fiResult
$firesult3 += $fiResult2
foreach($ffFolder in $collection_Folders){
#foreach($ffFolder in $fiResult.Folders){
$foldpathval = $null
#Try to get the FolderPath Value and then covert it to a usable String
if ($ffFolder.TryGetProperty($PR_Folder_Path,[ref] $foldpathval))
{
$binarry = [Text.Encoding]::UTF8.GetBytes($foldpathval)
$hexArr = $binarry | ForEach-Object { $_.ToString(“X2″) }
$hexString = $hexArr -join ”
$hexString = $hexString.Replace(“FEFF”, “5C00”)
$fpath = ConvertToString($hexString)
}
“FolderPath : ” + $fpath
#Define ItemView to retrive just 1000 Items
$ivItemView = New-Object Microsoft.Exchange.WebServices.Data.ItemView(1000)
$psPropset= new-object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::IdOnly)
$psPropset.Add([Microsoft.Exchange.WebServices.Data.ItemSchema]::Size)
$psPropset.Add([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived)
$psPropset.Add([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeCreated)
$ivItemView.PropertySet = $psPropset
$fiItems = $null
do{
$fiItems = $service.FindItems($ffFolder.Id,$ivItemView)
#[Void]$service.LoadPropertiesForItems($fiItems,$psPropset)
foreach($Item in $fiItems.Items){
$dateVal = $null
if($Item.TryGetProperty([Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeReceived,[ref]$dateVal )-eq $false){
$dateVal = $Item.DateTimeCreated
}
if($rptHash.ContainsKey($dateVal.Year)){
$rptHash[$dateVal.Year].TotalNumber += 1
$rptHash[$dateVal.Year].TotalSize += [Int64]$Item.Size
}
else{
$rptObj = “” | Select TotalNumber,TotalSize
$rptObj.TotalNumber = 1
$rptObj.TotalSize = [Int64]$Item.Size
$rptHash.add($dateVal.Year,$rptObj)
if($dateVal.Year -lt $minYear){$minYear = $dateVal.Year}
}
}
$ivItemView.Offset += $fiItems.Items.Count
}while($fiItems.MoreAvailable -eq $true)
}
$fvFolderView.Offset += $collection_folders.Count
}while($fiResult3.MoreAvailable -eq $true)
$rptCollection = @()
$fnFinalreporttlt = “” | Select Name,TotalNumber,TotalSize, @{Name=”Mbx”;Expression={“$mailboxname”}}
$fnFinalreporttlt.Name = $MailboxName
$rptCollection += $fnFinalreporttlt
$fnFinalreport = “” | Select Name,TotalNumber,TotalSize,@{Name=”Mbx”;Expression={“$mailboxname”}}
$rptCollection += $fnFinalreport
$rptHash.GetEnumerator() | Sort-Object Name | ForEach-Object {
$fnFinalreport = “” | Select Name,TotalNumber,TotalSize,@{Name=”Mbx”;Expression={“$mailboxname”}}
$fnFinalreport.Name = $_.key
$fnFinalreport.TotalNumber = $rptHash[$_.key].TotalNumber
$fnFinalreport.TotalSize = [Math]::Round($rptHash[$_.key].TotalSize/1MB,2)
$fnFinalreporttlt.TotalNumber += $rptHash[$_.key].TotalNumber
$fnFinalreporttlt.TotalSize += [Math]::Round($rptHash[$_.key].TotalSize/1MB,2)
$rptCollection += $fnFinalreport
}
$rptCollection | Select Mbx,Name,TotalNumber,TotalSize
$rptCollection | Export-csv $export_log
############################
$tableStyle = @”
<style>
BODY{background-color:white;}
TABLE{border-width: 1px;
border-style: solid;
border-color: black;
border-collapse: collapse;
}
TH{border-width: 1px;
padding: 10px;
border-style: solid;
border-color: black;
background-color:#66CCCC
}
TD{border-width: 1px;
padding: 2px;
border-style: solid;
border-color: black;
background-color:white
}
</style>
“@
$body = @”
<p style=”font-size:25px;family:calibri;color:#ff9100″>
$TableHeader
</p>
“@
############################################
$PST_Size = $null
#Loop
$rptcollection | Where {($_.Name -ne “”) -and ($_.name -notlike “*@*”)} | %{
#Declare Variables
$Size = [int]$_.TotalSize
$Name = $_.Mbx
$year = $_.Name
$Start = “1/1/$year”
$End = $Start;$End = [datetime]$End;$End = $end.AddYears(1);$End = $End.ToString(“M/d/yyyy”)
“`n`rStarting Loop for: $Name – $Size – $Start <–> $End”
If((Test-Path $PSTFilePath$NAME) -eq $False){MD “$PSTFilePath$NAME”}
If($Size -lt $Size_For_PST){
$PSTName = $Name+”_”+$Start+”_”+$End
$PSTName = $PSTName -replace (“/”,”-“)
$F = “$PSTFilePath$Name$PstName.pst”
write-host “…..Size is less than $Size_for_PST” -foregroundcolor cyan
New-MailboxExportRequest -mailbox $Name -contentFilter {(Received -ge $start) -and (Received -le $end)} -name $PSTName -filepath $f -baditemlimit 1000000 -acceptlargedataloss -batchname $Batchname
}
If($Size -gt $Size_For_PST){
$R = [math]::Round($Size/$Size_For_PST)
If(($R -eq 0) -or ($R -eq 1)){$R = 2}
$Months = 12/$r
$count = 0
$LoopEnd = [datetime]$End
“Startin Loop r = $R, months = $Months”
Do{
$Count++
write-host “Size is bigger than $Size_for_PST” -foregroundcolor green
$start = [datetime]$Start
If($start -ge (Get-date)){Break}
$end = $start.AddMonths($Months)
$start = $start.tostring(“M/d/yyyy”)
$end = $end.tostring(“M/d/yyyy”)
$PSTName = $Name+”_”+$Start+”_”+$End
$PSTName = $PSTName -replace (“/”,”-“)
$F = “$PSTFilePath$Name$PstName.pst”
“…..New Mailbox Export Request for $name for $start –> $end”
$start = $End
$Loopstart = [datetime]$start
New-MailboxExportRequest -mailbox $Name -contentFilter {(Received -ge $start) -and (Received -le $end)} -name $PSTName -filepath $f -baditemlimit 1000000 -acceptlargedataloss -batchname $Batchname
}While($loopstart -ne $Loopend)
“End Loop”
}
}