Exchange 2010 - Auslesen von der Anzahl der gespeicherten Kontakte pro Mailbox
Hallo Leute,
Ich bin auf der Suche nach einem Powershell Befehl der mir für jede Mailbox sagt wieviele Kontakte gespeichert sind.
Ich bin auf den Befehl Get-MailboxStatistics gestossen komme aber damit nicht weiter... geht das mit dem Befehl überhaupt?
nice greetz jojo
Ich bin auf der Suche nach einem Powershell Befehl der mir für jede Mailbox sagt wieviele Kontakte gespeichert sind.
Ich bin auf den Befehl Get-MailboxStatistics gestossen komme aber damit nicht weiter... geht das mit dem Befehl überhaupt?
nice greetz jojo
Bitte markiere auch die Kommentare, die zur Lösung des Beitrags beigetragen haben
Content-ID: 389009
Url: https://administrator.de/forum/exchange-2010-auslesen-von-der-anzahl-der-gespeicherten-kontakte-pro-mailbox-389009.html
Ausgedruckt am: 09.04.2025 um 05:04 Uhr
4 Kommentare
Neuester Kommentar
Moin!
Ich will mich da nicht bis aufs Letzte festlegen, aber vor drei, vier Jahren hatte ich eine ähnliche Idee (es gibt um Termine) und musste feststellen, dass das nicht per Powershell machbar ist, jedenfalls nicht auf Seite der Exchange-Administration.
Ich bin damals den Weg gegangen, mir für alle 50 User, die das bei mir betroffen hat, Vollzugriff auf die Postfächer zu geben und das Ganze dann per VBA innerhalb von Outlook abzufragen. Datenschutzrechtlich nicht nur bedenklich, sondern schlicht verboten, ohne explizite Einwilligung jedes einzelnen Benutzers ist das ein Grund für eine Kündigung, fristlos wäre verhandelbar. Arbeitsrechtsschutz hat sich dann auch erledigt.
Sicher gibt es elegantere Möglichkeiten, aber Du kommst ohne erweiterte Rechte immer nur bis ans Postfach und dessen Eigenschaften und auf die Eigenschaften von Ordnern, nicht aber an die einzelnen Elemente. Würde das gehen, wäre Exchange nicht DSGVO- oder BSDG-konform. Oder Du bräuchtest von jedem User das vollste Vertrauen, schriftlich fixiert und alles.
Gruß
Jörg
Ich will mich da nicht bis aufs Letzte festlegen, aber vor drei, vier Jahren hatte ich eine ähnliche Idee (es gibt um Termine) und musste feststellen, dass das nicht per Powershell machbar ist, jedenfalls nicht auf Seite der Exchange-Administration.
Ich bin damals den Weg gegangen, mir für alle 50 User, die das bei mir betroffen hat, Vollzugriff auf die Postfächer zu geben und das Ganze dann per VBA innerhalb von Outlook abzufragen. Datenschutzrechtlich nicht nur bedenklich, sondern schlicht verboten, ohne explizite Einwilligung jedes einzelnen Benutzers ist das ein Grund für eine Kündigung, fristlos wäre verhandelbar. Arbeitsrechtsschutz hat sich dann auch erledigt.
Sicher gibt es elegantere Möglichkeiten, aber Du kommst ohne erweiterte Rechte immer nur bis ans Postfach und dessen Eigenschaften und auf die Eigenschaften von Ordnern, nicht aber an die einzelnen Elemente. Würde das gehen, wäre Exchange nicht DSGVO- oder BSDG-konform. Oder Du bräuchtest von jedem User das vollste Vertrauen, schriftlich fixiert und alles.
Gruß
Jörg
Servus

Vorraussetzungen für das Skript ist das es in der Exchange Management Shell ausgeführt wird, die EWS 2.2 DLL die ins Skriptverzeichnis gepackt werden muss und der Name des EX-Servers angepasst wird. Zusätzlich muss dem Account der das Skript ausführt die Impersonation RBAC Rolle zugewiesen werden, damit dieser Account sich als jede Mailbox ausgeben kann. Wie das geht steht hier.
Weitere Hinweise zu den Vorraussetzungen auch in diesem Thread:
Script odgl ausführen, wenn E-Mail eingeht
Gezählt werden wirklich alle Kontakte in allen Ordnern, auch dem Papierkorb (kann man anpassen).
Grüße Uwe
Zitat von @YotYot:
Ich will mich da nicht bis aufs Letzte festlegen, aber vor drei, vier Jahren hatte ich eine ähnliche Idee (es gibt um Termine) und musste feststellen, dass das nicht per Powershell machbar ist, jedenfalls nicht auf Seite der Exchange-Administration.
Doch, das ist definitiv mit Powershell machbar! Ich will mich da nicht bis aufs Letzte festlegen, aber vor drei, vier Jahren hatte ich eine ähnliche Idee (es gibt um Termine) und musste feststellen, dass das nicht per Powershell machbar ist, jedenfalls nicht auf Seite der Exchange-Administration.
Vorraussetzungen für das Skript ist das es in der Exchange Management Shell ausgeführt wird, die EWS 2.2 DLL die ins Skriptverzeichnis gepackt werden muss und der Name des EX-Servers angepasst wird. Zusätzlich muss dem Account der das Skript ausführt die Impersonation RBAC Rolle zugewiesen werden, damit dieser Account sich als jede Mailbox ausgeben kann. Wie das geht steht hier.
Weitere Hinweise zu den Vorraussetzungen auch in diesem Thread:
Script odgl ausführen, wenn E-Mail eingeht
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
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
<#
Anzahl der Kontakte jeder Mailbox ermitteln
Vor dem Start des Skript ist dem User welcher das Skript später ausführt die Impersonation-Berechtigungzu erteilen:
In diesem Beispiel der User 'Administrator' (Bitte einmalig in einer EMS ausführen)
New-ManagementRoleAssignment -Name:impersonationAssignmentName -Role:ApplicationImpersonation -User:Administrator
#>
if ($PSVersionTable.PSVersion.Major -lt 3){write-host "ERROR: Minimum Powershell Version 3.0 is required!" -F Yellow; return}
# FQDN des Exchange Servers
$EXCHANGESERVER = 'ex.domain.tld'
# Funktion zum Verbinden mit dem Exchange EWS Dienst
function ConnectTo-EWS {
param(
[parameter(mandatory=$false)][bool]$UseScriptCredentials = $true,
[parameter(mandatory=$false)][pscredential]$Credential,
[parameter(mandatory=$false)][ValidateScript({Test-Path $_})][string]$ewsdll = "$psscriptroot\Microsoft.Exchange.WebServices.dll",
[parameter(mandatory=$false)][string]$mailbox = $null,
[parameter(mandatory=$true)][string]$server
)
# Allen Zertifikaten vertrauen
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;
}
}
'
# Trust all certs policy dem ServicePointManager zuweisen
[System.Net.ServicePointManager]::CertificatePolicy = New-Object TrustAllCertsPolicy
}catch{}
# EWS DLL laden
Add-Type -Path $ewsdll
# EWS-Service Objekt erstellen
$ews = new-object Microsoft.Exchange.WebServices.Data.ExchangeService([Microsoft.Exchange.WebServices.Data.ExchangeVersion]::Exchange2010)
$ews.Url = "https://$server/ews/exchange.asmx"
$ews.UseDefaultCredentials = $UseScriptCredentials
if (!$UseScriptCredentials){
$ews.Credentials = $Credential.GetNetworkCredential()
}
if($mailbox){
$ews.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, $mailbox)
}
return $ews
}
# Funktion um eine Ordnerhierarchie nach einem Ordner zu durchsuchen
function Get-EWSFolder{
param(
[parameter(mandatory=$true)][Microsoft.Exchange.WebServices.Data.WellKnownFolderName]$storeroot,
[parameter(mandatory=$false)][string]$path = "",
[parameter(mandatory=$true)][Microsoft.Exchange.WebServices.Data.ExchangeService]$service
)
# rekusiver Skriptblock zum Suchen eines Ordnerpfades
$findfolder = {
param(
$id,
[string]$subpath
)
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 -id $storeroot -subpath $path)
}
# Funktion um Elemente eines Ordners zurückkzugeben
function Get-EWSFolderItems{
param(
[parameter(mandatory=$true,ValueFromPipelineByPropertyName=$true)]$id,
[parameter(mandatory=$false)][int]$pageSize = 1000,
[parameter(mandatory=$false)][Microsoft.Exchange.WebServices.Data.PropertySet]$propset = (New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.BasePropertySet]::FirstClassProperties)),
[parameter(mandatory=$false)][Hashtable]$filter = $null,
[parameter(mandatory=$false)][ValidateSet('And','Or')][Microsoft.Exchange.WebServices.Data.LogicalOperator]$filterLogicalOperator = 'And',
[parameter(mandatory=$true)][Microsoft.Exchange.WebServices.Data.ExchangeService]$service
)
$result = $null
$view = New-Object Microsoft.Exchange.WebServices.Data.ItemView($pageSize)
$view.PageSize = $pageSize
$view.Traversal = [Microsoft.Exchange.WebServices.Data.ItemTraversal]::Shallow
$view.PropertySet = $propset
$filterCollection = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection
$filterCollection.LogicalOperator = $filterLogicalOperator
if ($filter -ne $null){
$filter.GetEnumerator() | %{
$filterCollection.Add((New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo($_.Key,$_.Value)))
}
}
$moreItems = $true
$resultSet = @()
while($moreItems){
$result = $service.FindItems($id,$filterCollection,$view)
if ($result.TotalCount -gt 0){
$resultSet += $result.Items
}
$view.Offset = $result.NextPageOffset
$moreItems = $result.MoreAvailable
}
if ($resultSet.Count -gt 0){
return $resultSet
}else{
return $null
}
}
# Mit Service verbinden
$svc = ConnectTo-EWS -Server $EXCHANGESERVER
$mailboxes = Get-Mailbox -Filter "IsMailBoxEnabled -eq 'True'" -ResultSize unlimited | select -Expand PrimarySmtpAddress
# Mailboxen durchlaufen
foreach($mailbox in $mailboxes){
# Im Kontext des Benutzers in seiner Mailbox arbeiten
$svc.ImpersonatedUserId = New-Object Microsoft.Exchange.WebServices.Data.ImpersonatedUserId([Microsoft.Exchange.WebServices.Data.ConnectingIdType]::SmtpAddress, [string]$mailbox)
# Extended property für Spezial-Ordner 'AllItems' erzeugen
$allFoldersType = New-Object Microsoft.Exchange.WebServices.Data.ExtendedPropertyDefinition(13825,[Microsoft.Exchange.WebServices.Data.MapiPropertyType]::Integer)
# Root der Mailbox holen
$root = Get-EWSFolder -storeroot ([Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::Root) -service $svc
# AllItems Ordner Ordner suchen
$view = New-Object Microsoft.Exchange.WebServices.Data.FolderView(1)
$view.Traversal = [Microsoft.Exchange.WebServices.Data.FolderTraversal]::Shallow
$filterCollection = New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+SearchFilterCollection
$filterCollection.LogicalOperator = [Microsoft.Exchange.WebServices.Data.LogicalOperator]::And
$filterCollection.Add((New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo($allFoldersType,"2")))
$filterCollection.Add((New-Object Microsoft.Exchange.WebServices.Data.SearchFilter+IsEqualTo([Microsoft.Exchange.WebServices.Data.FolderSchema]::DisplayName,"allitems")))
$result = $svc.FindFolders($root.Id,$filterCollection,$view)
# Anzahl der Kontakte initialisieren
$count = 0
if ($result.TotalCount -gt 0){
# Filter out items in DeletedItems Folder
#$contacts = $result | Get-EWSFolderItems -service $svc -filter @{[Microsoft.Exchange.WebServices.Data.ItemSchema]::ItemClass = 'IPM.Contact'} -filterLogicalOperator And | ?{$_.ParentFolderId -ne [Microsoft.Exchange.WebServices.Data.Folder]::Bind($svc,[Microsoft.Exchange.WebServices.Data.WellKnownFolderName]::DeletedItems).Id.UniqueId}
# Kontaktitems aus dem Spezialordner ausfiltern
$contacts = $result | Get-EWSFolderItems -service $svc -filter @{[Microsoft.Exchange.WebServices.Data.ItemSchema]::ItemClass = 'IPM.Contact'} -filterLogicalOperator And -propset (New-Object Microsoft.Exchange.WebServices.Data.PropertySet([Microsoft.Exchange.WebServices.Data.ItemSchema]::ItemClass))
# Anzahl zuweisen
$count = $contacts.Count
}
# Custom Object mit dem Ergebnis ausgeben
[pscustomobject]@{Mailbox = $mailbox; ContactItems = $count}
}
Grüße Uwe
@colinardo
Ach Mist, jetzt, wo Du den impersonated Account nennst - jaja, hätte mir auch auffallen können, ist bei E-Mail-Archivierung ja auch nichts anderes, wenn man die vorhandenen Postfächer importieren will.
Gut, dass ich mich nicht ganz festgelegt habe
Ach Mist, jetzt, wo Du den impersonated Account nennst - jaja, hätte mir auch auffallen können, ist bei E-Mail-Archivierung ja auch nichts anderes, wenn man die vorhandenen Postfächer importieren will.
Gut, dass ich mich nicht ganz festgelegt habe