-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathTest-M365DigestConfig.ps1
More file actions
397 lines (342 loc) · 15.2 KB
/
Test-M365DigestConfig.ps1
File metadata and controls
397 lines (342 loc) · 15.2 KB
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
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
#Requires -Version 5.1
<#
.SYNOPSIS
M365 Digest Email System - Configuration Validator
.DESCRIPTION
Tests and validates your email system configuration without sending emails:
- Checks file paths
- Validates image files
- Tests HTML template processing
- Verifies authentication configuration
- Validates inline image CID references
.NOTES
Run this before your first campaign to catch configuration issues
#>
[CmdletBinding()]
param(
[Parameter(Mandatory = $false)]
[switch]$SkipAuthTest
)
# ============================================================================
# CONFIGURATION (Update these to match your setup)
# ============================================================================
$config = @{
# Paths
ModulePath = ".\M365DigestEmailModule.psm1"
HtmlTemplate = ".\M365_Digest_Template.htm"
TestCsvPath = "C:\Temp\test_recipients.csv"
# Images
InlineImages = @(
@{ ContentId = 'datagroup_logo'; FilePath = 'C:\temp\datagroup_logo.png' }
@{ ContentId = 'm365_icon'; FilePath = 'C:\temp\m365_icon.png' }
@{ ContentId = 'exchange_icon'; FilePath = 'C:\temp\exchange_icon.png' }
@{ ContentId = 'sharepoint_icon'; FilePath = 'C:\temp\sharepoint_icon.png' }
)
# Attachments
Attachments = @(
"C:\temp\Anleitung_Erstanmeldung_Authentifizierung_mit_Smartphone.pdf"
"C:\temp\Anleitung_Erstanmeldung_Authentifizierung_mit_Telefon.pdf"
)
# Auth Test (Basic)
AuthType = 'Basic' # 'Basic' or 'OAuth'
SmtpUser = 'user@example.com'
SmtpPassword = 'password'
# Auth Test (OAuth) - only if AuthType = 'OAuth'
TenantId = 'your-tenant-id'
ClientId = 'your-client-id'
ClientSecret = 'your-secret'
}
# ============================================================================
# TEST FUNCTIONS
# ============================================================================
function Test-FileExists {
param([string]$Path, [string]$Description)
if (Test-Path $Path) {
Write-Host "✓ " -NoNewline -ForegroundColor Green
Write-Host "$Description exists: " -NoNewline
Write-Host $Path -ForegroundColor Cyan
return $true
}
else {
Write-Host "✗ " -NoNewline -ForegroundColor Red
Write-Host "$Description NOT FOUND: " -NoNewline
Write-Host $Path -ForegroundColor Red
return $false
}
}
function Test-ImageFile {
param([hashtable]$Image)
$exists = Test-Path $Image.FilePath
if ($exists) {
# Check if it's a valid image
try {
$file = Get-Item $Image.FilePath
$validExtensions = @('.png', '.jpg', '.jpeg', '.gif')
$ext = $file.Extension.ToLower()
if ($ext -in $validExtensions) {
Write-Host "✓ " -NoNewline -ForegroundColor Green
Write-Host "Image valid: " -NoNewline
Write-Host "CID='$($Image.ContentId)' " -NoNewline -ForegroundColor Yellow
Write-Host "($($file.Length / 1KB) KB) " -NoNewline -ForegroundColor Gray
Write-Host $Image.FilePath -ForegroundColor Cyan
return $true
}
else {
Write-Host "⚠ " -NoNewline -ForegroundColor Yellow
Write-Host "Image has unexpected extension: $ext - $($Image.FilePath)" -ForegroundColor Yellow
return $false
}
}
catch {
Write-Host "✗ " -NoNewline -ForegroundColor Red
Write-Host "Cannot read image: $($Image.FilePath)" -ForegroundColor Red
return $false
}
}
else {
Write-Host "✗ " -NoNewline -ForegroundColor Red
Write-Host "Image NOT FOUND: " -NoNewline
Write-Host "CID='$($Image.ContentId)' " -NoNewline -ForegroundColor Yellow
Write-Host $Image.FilePath -ForegroundColor Red
return $false
}
}
function Test-HtmlTemplateCids {
param([string]$TemplatePath, [hashtable[]]$InlineImages)
Write-Host "`nValidating CID references in HTML template..." -ForegroundColor Cyan
$html = Get-Content $TemplatePath -Raw
$allValid = $true
foreach ($img in $InlineImages) {
$cidPattern = "cid:$($img.ContentId)"
if ($html -match [regex]::Escape($cidPattern)) {
Write-Host "✓ " -NoNewline -ForegroundColor Green
Write-Host "CID reference found in template: " -NoNewline
Write-Host $cidPattern -ForegroundColor Yellow
}
else {
Write-Host "⚠ " -NoNewline -ForegroundColor Yellow
Write-Host "CID reference NOT found in template: " -NoNewline
Write-Host $cidPattern -ForegroundColor Yellow
Write-Host " Make sure template contains: <img src=""$cidPattern"" ...>" -ForegroundColor Gray
$allValid = $false
}
}
return $allValid
}
function Test-ModuleImport {
param([string]$ModulePath)
try {
Import-Module $ModulePath -Force -ErrorAction Stop
Write-Host "✓ Module imported successfully" -ForegroundColor Green
# Test exported functions
$functions = @(
'Get-EmailAuthenticationCredential',
'Get-ProcessedHtmlTemplate',
'New-EmailAlternateViewWithImages',
'Send-HtmlEmail',
'Send-BulkHtmlEmail'
)
$allFound = $true
foreach ($func in $functions) {
if (Get-Command $func -ErrorAction SilentlyContinue) {
Write-Host " ✓ Function available: " -NoNewline -ForegroundColor Green
Write-Host $func -ForegroundColor Cyan
}
else {
Write-Host " ✗ Function NOT available: " -NoNewline -ForegroundColor Red
Write-Host $func -ForegroundColor Red
$allFound = $false
}
}
return $allFound
}
catch {
Write-Host "✗ Failed to import module: $($_.Exception.Message)" -ForegroundColor Red
return $false
}
}
function Test-TemplateProcessing {
param([string]$TemplatePath)
try {
$replacements = @{
'CARD1_TITLE' = 'Test Title 1'
'CARD1_CONTENT' = 'Test Content 1'
'CARD1_LINK' = 'https://example.com/1'
'CARD2_TITLE' = 'Test Title 2'
'CARD2_CONTENT' = 'Test Content 2'
'CARD2_LINK' = 'https://example.com/2'
}
$html = Get-ProcessedHtmlTemplate -TemplatePath $TemplatePath -Replacements $replacements -Encoding UTF8
# Verify replacements occurred
$allReplaced = $true
foreach ($key in $replacements.Keys) {
if ($html -notmatch [regex]::Escape($replacements[$key])) {
Write-Host "⚠ Placeholder not replaced: $key" -ForegroundColor Yellow
$allReplaced = $false
}
}
if ($allReplaced) {
Write-Host "✓ Template processing successful (all placeholders replaced)" -ForegroundColor Green
Write-Host " HTML length: $($html.Length) characters" -ForegroundColor Gray
}
else {
Write-Host "⚠ Some placeholders were not replaced" -ForegroundColor Yellow
}
return $allReplaced
}
catch {
Write-Host "✗ Template processing failed: $($_.Exception.Message)" -ForegroundColor Red
return $false
}
}
function Test-Authentication {
param([hashtable]$Config)
if ($Config.AuthType -eq 'Basic') {
Write-Host "Testing Basic Authentication configuration..." -ForegroundColor Cyan
if ($Config.SmtpUser -eq 'user@example.com' -or $Config.SmtpPassword -eq 'password') {
Write-Host "⚠ Using placeholder credentials - update before production use!" -ForegroundColor Yellow
return $false
}
try {
$cred = Get-EmailAuthenticationCredential `
-AuthMethod 'Basic' `
-Username $Config.SmtpUser `
-Password $Config.SmtpPassword
Write-Host "✓ Basic auth credential created successfully" -ForegroundColor Green
Write-Host " Username: $($Config.SmtpUser)" -ForegroundColor Cyan
return $true
}
catch {
Write-Host "✗ Failed to create Basic auth credential: $($_.Exception.Message)" -ForegroundColor Red
return $false
}
}
elseif ($Config.AuthType -eq 'OAuth') {
Write-Host "Testing OAuth2 configuration..." -ForegroundColor Cyan
if ($Config.TenantId -eq 'your-tenant-id' -or
$Config.ClientId -eq 'your-client-id' -or
$Config.ClientSecret -eq 'your-secret') {
Write-Host "⚠ Using placeholder OAuth values - update before production use!" -ForegroundColor Yellow
return $false
}
try {
Write-Host " Attempting to acquire OAuth token (this may take a few seconds)..." -ForegroundColor Gray
$cred = Get-EmailAuthenticationCredential `
-AuthMethod 'OAuth' `
-Username $Config.SmtpUser `
-TenantId $Config.TenantId `
-ClientId $Config.ClientId `
-ClientSecret $Config.ClientSecret
Write-Host "✓ OAuth token acquired successfully" -ForegroundColor Green
Write-Host " Tenant: $($Config.TenantId)" -ForegroundColor Cyan
Write-Host " Client: $($Config.ClientId)" -ForegroundColor Cyan
return $true
}
catch {
Write-Host "✗ Failed to acquire OAuth token: $($_.Exception.Message)" -ForegroundColor Red
Write-Host " Common issues:" -ForegroundColor Gray
Write-Host " - Verify TenantId, ClientId, ClientSecret are correct" -ForegroundColor Gray
Write-Host " - Ensure Mail.Send permission is granted and admin consent given" -ForegroundColor Gray
Write-Host " - Check Azure AD app is enabled" -ForegroundColor Gray
return $false
}
}
}
# ============================================================================
# MAIN VALIDATION
# ============================================================================
Write-Host "`n╔═══════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
Write-Host "║ M365 Digest Email System - Configuration Validator ║" -ForegroundColor Cyan
Write-Host "╚═══════════════════════════════════════════════════════════╝`n" -ForegroundColor Cyan
$results = @{
ModuleImport = $false
TemplateExists = $false
TemplateProcessing = $false
ImagesValid = $true
CidsValid = $false
AttachmentsValid = $true
Authentication = $false
}
# Test 1: Module Import
Write-Host "`n[1/7] Testing PowerShell Module..." -ForegroundColor Magenta
$results.ModuleImport = Test-ModuleImport -ModulePath $config.ModulePath
if (-not $results.ModuleImport) {
Write-Host "`n✗ Cannot proceed without valid module. Fix module import first." -ForegroundColor Red
exit 1
}
# Test 2: HTML Template
Write-Host "`n[2/7] Checking HTML Template..." -ForegroundColor Magenta
$results.TemplateExists = Test-FileExists -Path $config.HtmlTemplate -Description "HTML Template"
# Test 3: Template Processing
if ($results.TemplateExists) {
Write-Host "`n[3/7] Testing Template Processing..." -ForegroundColor Magenta
$results.TemplateProcessing = Test-TemplateProcessing -TemplatePath $config.HtmlTemplate
}
else {
Write-Host "`n[3/7] Skipping template processing (template not found)" -ForegroundColor Yellow
}
# Test 4: Inline Images
Write-Host "`n[4/7] Validating Inline Images..." -ForegroundColor Magenta
foreach ($img in $config.InlineImages) {
$valid = Test-ImageFile -Image $img
if (-not $valid) { $results.ImagesValid = $false }
}
# Test 5: CID References
if ($results.TemplateExists) {
Write-Host "`n[5/7] Checking CID References..." -ForegroundColor Magenta
$results.CidsValid = Test-HtmlTemplateCids -TemplatePath $config.HtmlTemplate -InlineImages $config.InlineImages
}
else {
Write-Host "`n[5/7] Skipping CID validation (template not found)" -ForegroundColor Yellow
}
# Test 6: Attachments
Write-Host "`n[6/7] Checking Attachments..." -ForegroundColor Magenta
foreach ($attachment in $config.Attachments) {
$valid = Test-FileExists -Path $attachment -Description "Attachment"
if (-not $valid) { $results.AttachmentsValid = $false }
}
# Test 7: Authentication
if (-not $SkipAuthTest) {
Write-Host "`n[7/7] Testing Authentication..." -ForegroundColor Magenta
$results.Authentication = Test-Authentication -Config $config
}
else {
Write-Host "`n[7/7] Skipping authentication test (-SkipAuthTest specified)" -ForegroundColor Yellow
}
# ============================================================================
# SUMMARY
# ============================================================================
Write-Host "`n╔═══════════════════════════════════════════════════════════╗" -ForegroundColor Cyan
Write-Host "║ VALIDATION SUMMARY ║" -ForegroundColor Cyan
Write-Host "╚═══════════════════════════════════════════════════════════╝`n" -ForegroundColor Cyan
$totalTests = 0
$passedTests = 0
foreach ($key in $results.Keys) {
$totalTests++
$status = $results[$key]
if ($status) {
$passedTests++
Write-Host "✓ " -NoNewline -ForegroundColor Green
}
else {
Write-Host "✗ " -NoNewline -ForegroundColor Red
}
Write-Host "$key" -ForegroundColor Cyan
}
Write-Host "`nResults: $passedTests / $totalTests tests passed" -ForegroundColor $(if ($passedTests -eq $totalTests) { 'Green' } else { 'Yellow' })
if ($passedTests -eq $totalTests) {
Write-Host "`n✓ All validation tests passed! System is ready for use." -ForegroundColor Green
Write-Host "`nNext steps:" -ForegroundColor Cyan
Write-Host " 1. Update CSV file with recipient data" -ForegroundColor Gray
Write-Host " 2. Run Send-M365Digest-BasicAuth.ps1 or Send-M365Digest-OAuth.ps1" -ForegroundColor Gray
Write-Host " 3. Start with -ConfigMode Test for initial testing" -ForegroundColor Gray
exit 0
}
else {
Write-Host "`n⚠ Some validation tests failed. Review errors above and fix before proceeding." -ForegroundColor Yellow
Write-Host "`nCommon fixes:" -ForegroundColor Cyan
Write-Host " - Update file paths in this script to match your environment" -ForegroundColor Gray
Write-Host " - Ensure inline images exist and match CID references" -ForegroundColor Gray
Write-Host " - Verify authentication credentials are correct" -ForegroundColor Gray
exit 1
}