forked from iricigor/OutlookConnector
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathExport-OutlookFolder.ps1
159 lines (124 loc) · 7.22 KB
/
Export-OutlookFolder.ps1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
function Export-OutlookFolder {
<#
.SYNOPSIS
OutlookConnector function: Saves all messages from passed Outlook folder to a disk.
.DESCRIPTION
Saves all messages from passed Outlook folder(s) to a disk. It will also process all contained subfolders.
Function is internally calling Export-OutlookMessage function.
Folder(s) can be obtained via Get-OutlookFolder function and piped or used as an argument.
.EXAMPLE
Get-OutlookFolder -Recurse -MainOnly | ? Name -eq 'Done' | Export-OutlookFolder -OutputFolder 'C:\tmp\Done'
Saves all messages from folder named 'Done' to a disk using default file naming.
.EXAMPLE
Get-OutlookFolder -MainOnly | Export-OutlookFolder -OutputFolder 'C:\tmp\all' -Progress -WarningAction SilentlyContinue
Saves all messages from main mailbox 'C:\tmp\all' to a disk using default file naming. Warnings for messages without subject used in file naming, are ignored.
.PARAMETER InputFolder
Mandatory parameter that specifies which Outlook folder needs to be exported. Easies is to obtain it via
.PARAMETER OutputFolder
Mandatory parameter which specifies to which folder messages will be saved. It can be both local disk, as well as network location.
If folder is not existing, it will be created.
Entire Outlok folder structure will be generated within specified folder.
.PARAMETER FileNameFormat
Optional parameter that specifies how individual files will be named based. If omitted, files will be saved in format 'FROM= %SenderName% SUBJECT= %Subject%'.
File name can contain any of message parameters surrounded with %. For list of parameters, type Get-OutlookInbox | Get-Member.
Custom format can be specified after a | character within the %, e.g. %ReceivedTime|yyyyMMddhhmmss%.
Parameter is passed to Export-OutlookMessage function.
.PARAMETER Filter
Optional parameter that can contain a filter string expression to be applied to restrict items to be exported.
For syntax see https://msdn.microsoft.com/en-us/vba/outlook-vba/articles/items-restrict-method-outlook.
.PARAMETER IncludeTypes
Optional parameter to specify specific types of items to be exported, such as olMail for e-mail items.
To list all possible values: [enum]::GetNames([Microsoft.Office.Interop.Outlook.OlObjectClass])
.PARAMETER ExcludeTypes
Optional parameter to specify specific types of items to not export, such as olContact for contact items.
To list all possible values: [enum]::GetNames([Microsoft.Office.Interop.Outlook.OlObjectClass])
.PARAMETER Progress
If current Outlook session is connected online to remote Exchange server, saving all folders might take a minute. You may display standard progress bar while obtaining that list.
.OUTPUTS
Function returns array of Outlook folder objects. Output can be filtered and piped to Export-OutlookFolder.
Outlook can contain also other containers, like Calendar, connected and Archive mailboxes, etc.
Best practice is to run first command without -Recurse to see structure of returned data.
.LINK
about_OutlookConnector
.NOTES
NAME: Export-OutlookFolder
AUTHOR: Igor Iric, [email protected]
CREATEDATE: September 29, 2015
#>
# ---------------------- [Parameters definitions] ------------------------
[CmdletBinding()]
Param(
[parameter(Mandatory=$true,ValueFromPipeline=$true,Position=0)][psobject[]]$InputFolder,
[parameter(Mandatory=$true,ValueFromPipeline=$false)][string]$OutputFolder,
[parameter(Mandatory=$false,ValueFromPipeline=$false)][string]$FileNameFormat='FROM= %SenderName% SUBJECT= %Subject%',
[parameter(Mandatory=$false,ValueFromPipeline=$false)][string]$Filter,
[parameter(Mandatory=$false,ValueFromPipeline=$false)][Microsoft.Office.Interop.Outlook.OlObjectClass[]]$IncludeTypes,
[parameter(Mandatory=$false,ValueFromPipeline=$false)][Microsoft.Office.Interop.Outlook.OlObjectClass[]]$ExcludeTypes,
[switch]$Progress
) #end param
# ------------------------- [Function start] -----------------------------
BEGIN {
Write-Verbose -Message 'Export-OutlookFolder starting...'
$ReqProps = @('Items','FullFolderPath','Folders')
$OutputFolderPath = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($OutputFolder)
} # End of BEGIN block
PROCESS {
:folderloop foreach ($F in $InputFolder) {
# check input object
$NotFoundProps = Validate-Properties -InputObject $F -RequiredProperties $ReqProps # Validate-Properties is internal function
if ($NotFoundProps) {
Write-Error -Message ('Folder ' + $F.ToString() + ' is not proper object. Missing: ' + ($NotFoundProps -join ','))
Continue # next foreach
}
$FolderPath = $F.FolderPath
Write-Verbose -Message (' Checking: '+($FolderPath))
# check number of items
if ($Filter) {
$Items = $F.Items.Restrict($Filter)
} else {
$Items = $F.Items
}
$ItemsCount = $Items.Count
$SubCount = $F.Folders.Count
if ($ItemsCount -gt 0) {
Write-Verbose -Message (' Exporting ' + $FolderPath + ' , ' + $ItemsCount + ' message(s).') # may be fewer actual exported items to due to include/exclude type filter not considered yet, and also any errors such as missing properties
# TODO Try foreach
$msg = $Items.GetFirst()
$itemCounter = 0
$exportCounter = 0
:itemloop do {
if ($Progress) {Write-Progress -Activity ($FolderPath) -Status (' '+$msg.subject+' ') -PercentComplete (($itemCounter++)*100/$ItemsCount)}
# TODO Add numbering of folders in Progress, like (1/5)
if ((-not $IncludeTypes -or $msg.Class -in $IncludeTypes) -and (-not $ExcludeTypes -or $msg.Class -notin $ExcludeTypes)) {
if ($exportCounter -eq 0) {
# before first export, create folder container if needed
$TargetFolder = ($OutputFolderPath+$FolderPath.Replace('\\', '\')).Replace('\\', '\')
try {
New-Folder -TargetFolder $TargetFolder # internal commands
} catch {
Write-Error -Message $_
Continue folderloop # next folder
}
}
Export-OutlookMessage -Messages $msg -OutputFolder $TargetFolder -FileNameFormat $FileNameFormat
++$exportCounter
} else {
Write-Verbose -Message ('Excluding message of type ' + [enum]::GetName([Microsoft.Office.Interop.Outlook.OlObjectClass], $msg.Class))
}
$msg = $Items.GetNext()
} while ($msg)
if ($Progress) {Write-Progress -Completed -Activity $F}
}
if ($SubCount -gt 0) {
# export subfolders
foreach ($subfolder in ($F.Folders)) {
Export-OutlookFolder -InputFolder $subfolder -OutputFolder $OutputFolderPath -FileNameFormat $FileNameFormat -Filter $Filter -IncludeTypes $IncludeTypes -ExcludeTypes $ExcludeTypes -Progress:$Progress
}
}
} # End of foreach
} # End of PROCESS block
END {
Write-Verbose -Message 'Export-OutlookFolder completed.'
} # End of END block
# ------------------------- [End of function] ----------------------------
}