Anzahl Mails nach Datum in öffentlichen Ordnern finden
Hallo zusammen,
ich möchte in unseren öffentlichen Ordnern die Anzahl an Mails finden die vor dem 21.05.201 in den jeweiligen Ordner erstellt (DateTimeCreated) wurden. Im Idealfall wird das Ergebins in einer CSV mit den Ordnern und der Anzahl an Mails ausgegeben.
Kann mir jemand dabei behiflich sein? Ich bekomme das leider nicht hin.
Es handelt sich um einen Exchange 2016.
Vielen Dank
Chris
ich möchte in unseren öffentlichen Ordnern die Anzahl an Mails finden die vor dem 21.05.201 in den jeweiligen Ordner erstellt (DateTimeCreated) wurden. Im Idealfall wird das Ergebins in einer CSV mit den Ordnern und der Anzahl an Mails ausgegeben.
Kann mir jemand dabei behiflich sein? Ich bekomme das leider nicht hin.
Es handelt sich um einen Exchange 2016.
Vielen Dank
Chris
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 1898980268
Url: https://administrator.de/forum/anzahl-mails-nach-datum-in-oeffentlichen-ordnern-finden-1898980268.html
Ausgedruckt am: 18.04.2025 um 01:04 Uhr
2 Kommentare
Neuester Kommentar
Hi Chris,
mal schnell zusammen gelötet ...
Schönen Abend
Grüße Uwe
mal schnell zusammen gelötet ...
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
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
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
#Requires -Version 3
<#
Count mail messages older than specific date from pubilc folder structure (recursive)
#>
# ================ Variables ================
# Credentials to use
$CREDENTIAL = (new-Object PSCredential('USERNAME',(ConvertTo-SecureString 'PASSWORD' -AsPlainText -Force)))
# Exchange Server FQDN
$SERVER = 'server.domain.tld'
# Messages older than will be counted
$OLDERTHANDATE = '21.05.2021'
# folder path from public folder root
$PUBLICFOLDERPATH = ''
# path to logfile
$LOGPATH = "$PSScriptRoot\report.csv"
# ================ SCRIPT-Prefs ================
# stop on error
$ErrorActionPreference = 'Stop'
# Accept all TLS protocols
[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::GetNames([System.Net.SecurityProtocolType])
# ================== HELPER FUNCTIONS ===================
# Connect to exchange service
function ConnectTo-EWS {
param(
[parameter(mandatory=$true)][bool]$UseScriptCredentials = $true,
[parameter(mandatory=$false)][pscredential]$Credential,
[parameter(mandatory=$true,ParameterSetName='A')][string]$server,
[parameter(mandatory=$true,ParameterSetName='B')][string]$email
)
# trust all certificates
try{
Add-Type '
using System.Net;
using System.Security.Cryptography.X509Certificates;
public class TrustAllCertsPolicy : ICertificatePolicy {
public bool CheckValidationResult(
ServicePoint srvPoint, X509Certificate certificate,
WebRequest request, int certificateProblem) {
return true;
}
}
'
# assign policy to ServicePointManager
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
}catch{}
# load ews dll
Load-EWSLibrary
# EWS-Service Objekt erstellen
$ews = new-object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010)
if ($server){
$ews.Url = "https://$server/ews/exchange.asmx"
}else{
$ews.AutodiscoverUrl($email)
}
$ews.UseDefaultCredentials = $UseScriptCredentials
if (!$UseScriptCredentials){
$ews.Credentials = $Credential.GetNetworkCredential()
}
return $ews
}
# Function to load EWS assemblies from nuget if not found in current folder or temp
function Load-EWSLibrary {
if($psscriptroot -ne ''){
$localpath = join-path $psscriptroot 'Microsoft.Exchange.WebServices.dll'
}else{
$localpath = join-path $env:TEMP 'Microsoft.Exchange.WebServices.dll'
}
$tmp = '';$zip = $null
try{
if(!(Test-Path $localpath)){
Add-Type -A System.IO.Compression.FileSystem
$tmp = "$env:TEMP\$([IO.Path]::GetRandomFileName())"
write-host "Downloading and extracting required 'Microsoft.Exchange.WebServices.dll' ... " -F Green -NoNewline
(New-Object System.Net.WebClient).DownloadFile('https://www.nuget.org/api/v2/package/Exchange.WebServices.Managed.Api', $tmp)
$zip = [System.IO.Compression.ZipFile]::OpenRead($tmp)
$zip.Entries | ?{$_.Fullname -eq 'lib/net35/Microsoft.Exchange.WebServices.dll'} | %{
[System.IO.Compression.ZipFileExtensions]::ExtractToFile($_,$localpath)
}
Unblock-File -Path $localpath
write-host "OK" -F Green
}
Add-Type -Path $localpath
}catch{
write-error "Error downloading required EWS Library / Error: $($_.Exception.Message)"
}finally{
if ($zip){$zip.Dispose()}
if($tmp -ne ''){del $tmp -Force -EA SilentlyContinue}
}
}
# function to bind to a specific folder
function Get-EWSFolder{
param(
[parameter(mandatory=$true)][Microsoft.Exchange.WebServices.Data.WellKnownFolderName]$storeroot,
[parameter(mandatory=$false)][string]$mailbox,
[parameter(mandatory=$false)][string]$path = "",
[parameter(mandatory=$true)][ValidateNotNullOrEmpty()][Microsoft.Exchange.WebServices.Data.ExchangeService]$service
)
$path = $path -replace '^\\'
# rekusiver Skriptblock zum Suchen eines Ordnerpfades
$findfolder = {
param(
[string]$mailbox,
$id,
[string]$subpath
)
# bind folder to specific mailbox only when parameter is not empty and not public folder root
if($mailbox -ne "" -and $id -ne [Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::PublicFoldersRoot){
$id = New-Object Microsoft.Exchange.WebServices.Data.FolderId $id,$mailbox
}
if ($subpath -ne ""){
$parts = $subpath.Split("\")
$view = New-Object Microsoft.Exchange.WebServices.Data.FolderView(1)
$view.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Shallow
$view.PropertySet = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
$f = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,$parts)
$result = $service.FindFolders($id,$f,$view)
if ($result.TotalCount -gt 0){
if ($parts.Count -gt 1 ){
& $findfolder -id $result.Folders.Id -subpath $subpath.Split("\",2)[-1]
}else{
return $result.Folders
}
}else{
throw "Search returned no results for path subpart '$($parts)'."
}
}else{
return ([Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,$id))
}
}
return (& $findfolder -mailbox $mailbox -id $storeroot -subpath $path)
}
# function to load/filter items from folder
function Get-EWSFolderItems{
param(
[parameter(mandatory=$true,ValueFromPipelineByPropertyName=$true)][Microsoft.Exchange.WebServices.Data.FolderId[]]$id,
[parameter(mandatory=$false)][int]$maxitems = 10000,
[parameter(mandatory=$false)][Microsoft.Exchange.WebServices.Data.PropertySet]$propset = $null,
[parameter(mandatory=$false)][Hashtable]$filter = $null,
[parameter(mandatory=$false)][ValidateSet('And','Or')][Microsoft.Exchange.WebServices.Data.LogicalOperator]$filterLogicalOperator = 'And',
[parameter(mandatory=$true,ValueFromPipelineByPropertyName=$true)][ValidateNotNullOrEmpty()][Microsoft.Exchange.WebServices.Data.ExchangeService]$service
)
begin{
$resultSet = @()
$view = New-Object Microsoft.Exchange.WebServices.Data.ItemView($maxitems)
}
process{
foreach($i in $id){
$result = $null
$moreItems = $true
if ($propset -ne $null){
$view.PropertySet = $propset
}else{
$view.PropertySet = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
}
if ($filter -ne $null){
$filterCollection = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection
$filterCollection.LogicalOperator = $filterLogicalOperator
$filter.GetEnumerator() | %{
$itm = $_
if ($itm.Value -is [hashtable]){
switch($itm.Value.Operator){
">" {$filterCollection.Add((New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsGreaterThan($itm.Key,$itm.Value.Value)))}
"<" {$filterCollection.Add((New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsLessThan($itm.Key,$itm.Value.Value)))}
"<=" {$filterCollection.Add((New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsLessThanOrEqualTo($itm.Key,$itm.Value.Value)))}
">=" {$filterCollection.Add((New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsGreaterThanOrEqualTo($itm.Key,$itm.Value.Value)))}
"!=" {$filterCollection.Add((New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsNotEqualTo($itm.Key,$itm.Value.Value)))}
"=" {$filterCollection.Add((New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo($itm.Key,$itm.Value.Value)))}
"contains" {$filterCollection.Add((New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+ContainsSubstring($itm.Key,$itm.Value.Value)))}
}
}else{
$filterCollection.Add((New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo($_.Key,$_.Value)))
}
}
while($moreItems){
$result = $service.FindItems($i,$filterCollection,$view)
if ($result.TotalCount -gt 0){
$resultSet += $result.Items
}
$view.Offset = $result.NextPageOffset
$moreItems = $result.MoreAvailable
}
}else{
while($moreItems){
$result = $service.FindItems($i,$view)
if ($result.TotalCount -gt 0){
$resultSet += $result.Items
}
$view.Offset = $result.NextPageOffset
$moreItems = $result.MoreAvailable
}
}
}
}
end{
if ($resultSet.Count -gt 0){
return $resultSet
}else{
return $null
}
}
}
# get all public folders recursive
function Get-EWSAllPublicFolders {
param(
[parameter(mandatory=$false,ValueFromPipeline=$true)]$folder,
[parameter(mandatory=$true,ValueFromPipelineByPropertyName=$true)][ValidateNotNullOrEmpty()][Microsoft.Exchange.WebServices.Data.ExchangeService]$service
)
if (!$folder){
$folder = [Microsoft.Exchange.WebServices.Data.Folder]::Bind($service,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::PublicFoldersRoot)
}
$view = New-Object Microsoft.Exchange.WebServices.Data.FolderView([int]::MaxValue)
$view.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Shallow
$view.PropertySet = New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)
$resultset = @()
$moreItems = $true
while($moreItems){
$result = $service.FindFolders($folder.id,$view)
if ($result.Count -gt 0){
$resultset += $result.Folders
foreach($f in $result.Folders){
$resultset += Get-EWSAllPublicFolders $f -service $service
}
}
$view.Offset = $result.NextPageOffset
$moreItems = $result.MoreAvailable
}
return $resultset
}
# ==========================================================
# connect to service
write-host "Connecting to service on '$SERVER'." -F Green
$svc = ConnectTo-EWS -Server $SERVER -UseScriptCredentials $false -Credential $CREDENTIAL
# get object of specific folder in public folder root
$root = Get-EWSFolder -storeroot PublicFoldersRoot -path $PUBLICFOLDERPATH -service $svc
# parse date string from variable
$dt = [datetime]::Parse($OLDERTHANDATE,[cultureinfo]'de')
# filter old items from root and all sub folders
write-host "Find matching items, this could take some time please wait ... " -F Green -NoNewline
$result = foreach ($folder in ($root | Get-EWSAllPublicFolders)){
$itemcount = (Get-EWSFolderItems -id $folder.id -filter @{[Microsoft.Exchange.WebServices.Data.ItemSchema]::DateTimeCreated = @{Operator="<";Value=$dt}} -service $svc | ?{$_.ItemClass -in 'IPM.Note'}).Count
[pscustomobject]@{
Folder = $folder.DisplayName
ItemCount = $itemcount
}
}
write-host "Done" -F Green
$result | export-csv -LiteralPath $LOGPATH -Delimiter ";" -NoType -Encoding UTF8
Schönen Abend
Grüße Uwe