-
Notifications
You must be signed in to change notification settings - Fork 10
/
get-DLHealthReport.ps1
5162 lines (3981 loc) · 243 KB
/
get-DLHealthReport.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
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
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
659
660
661
662
663
664
665
666
667
668
669
670
671
672
673
674
675
676
677
678
679
680
681
682
683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
702
703
704
705
706
707
708
709
710
711
712
713
714
715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
732
733
734
735
736
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
769
770
771
772
773
774
775
776
777
778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
799
800
801
802
803
804
805
806
807
808
809
810
811
812
813
814
815
816
817
818
819
820
821
822
823
824
825
826
827
828
829
830
831
832
833
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
859
860
861
862
863
864
865
866
867
868
869
870
871
872
873
874
875
876
877
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
893
894
895
896
897
898
899
900
901
902
903
904
905
906
907
908
909
910
911
912
913
914
915
916
917
918
919
920
921
922
923
924
925
926
927
928
929
930
931
932
933
934
935
936
937
938
939
940
941
942
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
#############################################################################################
# DISCLAIMER: #
# #
# THE SAMPLE SCRIPTS ARE NOT SUPPORTED UNDER ANY MICROSOFT STANDARD SUPPORT #
# PROGRAM OR SERVICE. THE SAMPLE SCRIPTS ARE PROVIDED AS IS WITHOUT WARRANTY #
# OF ANY KIND. MICROSOFT FURTHER DISCLAIMS ALL IMPLIED WARRANTIES INCLUDING, WITHOUT #
# LIMITATION, ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR OF FITNESS FOR A PARTICULAR #
# PURPOSE. THE ENTIRE RISK ARISING OUT OF THE USE OR PERFORMANCE OF THE SAMPLE SCRIPTS #
# AND DOCUMENTATION REMAINS WITH YOU. IN NO EVENT SHALL MICROSOFT, ITS AUTHORS, OR #
# ANYONE ELSE INVOLVED IN THE CREATION, PRODUCTION, OR DELIVERY OF THE SCRIPTS BE LIABLE #
# FOR ANY DAMAGES WHATSOEVER (INCLUDING, WITHOUT LIMITATION, DAMAGES FOR LOSS OF BUSINESS #
# PROFITS, BUSINESS INTERRUPTION, LOSS OF BUSINESS INFORMATION, OR OTHER PECUNIARY LOSS) #
# ARISING OUT OF THE USE OF OR INABILITY TO USE THE SAMPLE SCRIPTS OR DOCUMENTATION, #
# EVEN IF MICROSOFT HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES #
#############################################################################################
Function get-DLHealthReport
{
<#
.SYNOPSIS
This is the trigger function that begins the process of allowing an administrator to migrate a distribution list from
on premises to Office 365.
.DESCRIPTION
Trigger function.
.PARAMETER GROUPSMTPADDRESS
*REQUIRED*
This attribute specifies the windows mail address of the group to be migrated.
.PARAMETER GLOBALCATALOGSERVER
*REQUIRED*
This attribute specifies the global catalog server that will be utilized to process Active Directory commands.
.PARAMETER ACIVEDIRECTORYCREDENTIAL
*REQUIRED*
This attribute specifies the credentials for Active Directory connections.
Domain admin credentials are required if the group does not have resorces outside of the domain where the group resides.
Enterprise admin credentials are required if the group has resources across multiple domains in the forest.
.PARAMETER ACTIVEDIRECTORYAUTHENTICATIONMETHOD
Allows the administrator to specify kerberos or basic authentication for connections to Active Directory.
.PARAMETER AADCONNECTSERVER
*OPTIONAL*
This parameter specifies the FQDN of the Azure Active Directory Connect Server.
When specified the server is utilized to trigger delta syncs to provide timely migrations.
If not specified the script will wait for standard sync cycles to run.
.PARAMETER AADCONNECTCREDENTIAL
*OPTIONAL*
*MANDATORY with AADConnectServer specified*
This parameter specifies the credentials used to connect to the AADConnect server.
The account specified must be a member of the local administrators sync group of the AADConnect Server
.PARAMETER AADCONNECTAUTHENTICATIONMETHOD
Allows the administrator to specify kerberos or basic authentication for connections to the AADConnect server.
.PARAMETER EXCHANGESERVER
*OPTIONAL*
*REQUIRED with enableHybridMailFlow:TRUE*
This parameter specifies that local Exchange on premises installation utilized for hybrid mail flow enablement.
Exchange server is no required for migrations unlss enable hyrbid mail flow is required.
.PARAMETER EXCHANGECREDENTIAL
*OPTIONAL*
*REQUIRED with ExchangeServer specified*
This is the credential utilized to connect to the Exchange server remote powershell instance.
Exchange Organization Adminitrator rights are recommended.
.PARAMETER EXCHANGEAUTHENTICATIONMETHOD
*OPTIONAL*
*DEFAULT: BASIC*
This specifies the authentication method for the Exchage on-premsies remote powershell session.
.PARAMETER EXCHANGEONLINECREDENTIAL
*REQUIRED if ExchangeOnlineCertificateThumbprint not specified*
*NOT ALLOWED if ExchangeCertificateThubprint is specified*
The credential utilized to connect to Exchange Online.
This account cannot have interactive logon requirements such as multi-factored authentication.
Exchange Organization Administrator rights recommened.
.PARAMETER EXCHANGEONLINECERTIFICATETHUMBPRINT
*REQUIRED if ExchangeOnlineCredential is not specified*
*NOT ALLOWED if ExchangeCredential is specified*
This is the thumbprint of the certificate utilized to authenticate to the Azure application created for Exchange Certificate Authentication
.PARAMETER EXCHANGEONLINEORGANIZATIONNAME
*REQUIRED only with ExchangeCertificateThumbpint*
This specifies the Exchange Online oragnization name in domain.onmicroosft.com format.
.PARAMETER EXCHANGEONLINEENVIRONMENTNAME
*OPTIONAL*
*DEFAULT: O365DEFAULT
This specifies the Exchange Online environment to connect to if a non-commercial forest is utilized.
.PARAMETER EXCHANGEONLINEAPPID
*REQUIRED with ExchangeCertificateThumbprint*
This specifies the application ID of the Azure application for Exchange certificate authentication.
.PARAMETER AZUREADCREDENTIAL
*REQUIRED if AzureCertificateThumbprint is not specified*
This is the credential utilized to connect to Azure Active Directory.
Global administrator is the tested permissions set / minimum permissions to execute get-azureADGroup
.PARAMETER AZUREENVRONMENTNAME
*OPTIONAL*
*DEFAULT: AzureCloud*
This is the Azure tenant type to connect to if a non-commercial tenant is used.
.PARAMETER AZURETENANTID
*REQUIRED if AzureCertificateThumbprint is specified*
This is the Azure tenant ID / GUID utilized for Azure certificate authentication.
.PARAMETER AZURECERTIFICATETHUMBPRINT
*REQUIRED if AzureADCredential is not specified*
This is the certificate thumbprint associated with the Azure app id for Azure certificate authentication
.PARAMETER AZUREAPPLICATIONID
*REQUIRED if AzureCertificateThumbprint is specified*
This is the application ID assocaited with the Azure application created for certificate authentication.
.PARAMETER LOGFOLDERPATH
*REQUIRED*
This is the logging directory for storing the migration log and all backup XML files.
If running multiple SINGLE instance migrations use different logging directories.
.PARAMETER doNoSyncOU
*REQUIRED*
This is the organizational unit configured in Azure AD Connect to not sync.
This is utilize for temporary group storage to process the deletion of the group from Office 365.
.PARAMETER RETAINORIGINALGROUP
*OPTIONAL*
By default the original group is retained, mail disabled, and renamed with an !.
If the group should be deleted post migration set this value to TRUE.
.PARAMETER ENBABLEHYBRIDMAILFLOW
*OPTIONAL*
*REQUIRES use of ExchangeServer and ExchangeCredential*
This option enables mail flow objects in the on-premises Active Directory post migration.
This supports relay scenarios through the onpremises Exchange organization.
.PARAMETER GROUPTYPEOVERRIDE
*OPTIONAL*
This allows the administrator to override the group creation type in Office 365.
For example, an on premises security group may be migrated to Office 365 as a distribution only list.
If any security dependencies are discovered during the migration this option is always overridden to preserve security and the settings.
.PARAMETER TRIGGERUPGRADETOOFFICE365GROUP
*OPTIONAL*
*Parameter retained for backwards compatibility but now disabled.*
.PARAMETER OVERRIDECENTRALIZEDMAILTRANSPORTENABLED
*OPTIONAL*
If centralized transport enabled is detected during migration this switch is required.
This is an administrator acknowledgement that emails may flow externally in certain mail flow scenarios for migrated groups.
.PARAMETER ALLOWNONSYNCEDGROUP
*OPTIONAL*
Allows for on-premises group creation in Office 365 from forests that are not directory syncrhonized for some reason.
.PARAMETER USECOLLECTEDFULLMAILBOXACCESSONPREM
*OPTIONAL*
*Requires us of start-collectOnPremFullMailboxAccess*
This switch will import pre-collected full mailbox access data for the on premises organization and detect permissions for migrated DLs.
.PARAMETER USECOLLECTEDFULLMAILBOXACCESSOFFICE365
*OPTIONAL*
*Requires use of start-collectOffice365FullMailboxAccess
THis switch will import pre-collected full mailbox access data from the Office 365 organiation and detect permissions for migrated DLs.
.PARAMETER USERCOLLECTEDSENDASONPREM
*OPTIONAL*
*Requires use of start-collectOnPremSendAs*
This switch will import pre-collected send as data from the on premsies Exchange organization and detect dependencies on the migrated DLs.
.PARAMETER USECOLLECTEDFOLDERPERMISSIONSONPREM
*OPTIONAL*
*Requires use of start-collectOnPremMailboxFolderPermissions*
This switch will import pre-collected mailbox folder permissions for any default or user created folders within mailboxes.
The data is searched to discover any dependencies on the migrated DL.
.PARAMETER USECOLLECTEDFOLDERPERMISSIONSOFFICE365
*OPTIONAL*
*Requires use of start-collectOffice365MailboxFolderPermissions*
This switch will import pre-collected mailbox folder permissions for any default or user created folders within mailboxes.
The data is searched to discover any dependencies on the migrated DL.
.PARAMETER THREADNUMBERASSIGNED
*RESERVED*
.PARAMETER TOTALTHREADCOUNT
*RESERVED*
.PARAMETER ISMULTIMACHINE
*RESERVED*
.PARAMETER REMOTEDRIVELETTER
*RESERVED*
.PARAMETER ALLOWTELEMETRYCOLLECTION
Allows administrators to opt out of telemetry collection for DL migrations. No identifiable information is collected in telemetry.
.PARAMETER ALLOWDETAILEDTELEMETRYCOLLECTIOn
Allows administrators to opt out of detailed telemetry collection. Detailed telemetry collection includes information such as attribute member counts and time to process stages of the migration.
.PARAMETER ISHEALTHCHECK
Specifies if the function call is performing a distribution list health check.
.OUTPUTS
Logs all activities and backs up all original data to the log folder directory.
Moves the distribution group from on premieses source of authority to office 365 source of authority.
.NOTES
The following blog posts maintain documentation regarding this module.
https://timmcmic.wordpress.com.
Refer to the first pinned blog post that is the table of contents.
.EXAMPLE
Start-DistributionListMigration -groupSMTPAddress $groupSMTPAddress -globalCatalogServer server.domain.com -activeDirectoryCredential $cred -logfolderpath c:\temp -dnNoSyncOU "OU" -exchangeOnlineCredential $cred -azureADCredential $cred
.EXAMPLE
Start-DistributionListMigration -groupSMTPAddress $groupSMTPAddress -globalCatalogServer server.domain.com -activeDirectoryCredential $cred -logfolderpath c:\temp -dnNoSyncOU "OU" -exchangeOnlineCredential $cred -azureADCredential $cred -enableHybridMailFlow:$TRUE -triggerUpgradeToOffice365Group:$TRUE
.EXAMPLE
Start-DistributionListMigration -groupSMTPAddress $groupSMTPAddress -globalCatalogServer server.domain.com -activeDirectoryCredential $cred -logfolderpath c:\temp -dnNoSyncOU "OU" -exchangeOnlineCredential $cred -azureADCredential $cred -enableHybridMailFlow:$TRUE -triggerUpgradeToOffice365Group:$TRUE -useCollectedOnPremMailboxFolderPermissions:$TRUE -useCollectedOffice365MailboxFolderPermissions:$TRUE -useCollectedOnPremSendAs:$TRUE -useCollectedOnPremFullMailboxAccess:$TRUE -useCollectedOffice365FullMailboxAccess:$TRUE
#>
[cmdletbinding()]
Param
(
[Parameter(Mandatory = $true)]
[string]$groupSMTPAddress,
#Local Active Director Domain Controller Parameters
[Parameter(Mandatory = $true)]
[string]$globalCatalogServer,
[Parameter(Mandatory = $true)]
[pscredential]$activeDirectoryCredential,
[Parameter(Mandatory = $false)]
[ValidateSet("Basic","Negotiate")]
$activeDirectoryAuthenticationMethod="Negotiate",
#Exchange Online Parameters
[Parameter(Mandatory = $false)]
[pscredential]$exchangeOnlineCredential=$NULL,
[Parameter(Mandatory = $false)]
[string]$exchangeOnlineCertificateThumbPrint="",
[Parameter(Mandatory = $false)]
[string]$exchangeOnlineOrganizationName="",
[Parameter(Mandatory = $false)]
[ValidateSet("O365Default","O365GermanyCloud","O365China","O365USGovGCCHigh","O365USGovDoD")]
[string]$exchangeOnlineEnvironmentName="O365Default",
[Parameter(Mandatory = $false)]
[string]$exchangeOnlineAppID="",
#Define Microsoft Graph Parameters
[Parameter(Mandatory = $false)]
[ValidateSet("China","Global","USGov","USGovDod")]
[string]$msGraphEnvironmentName="Global",
[Parameter(Mandatory=$false)]
[string]$msGraphTenantID="",
[Parameter(Mandatory=$false)]
[string]$msGraphCertificateThumbprint="",
[Parameter(Mandatory=$false)]
[string]$msGraphApplicationID="",
#Define other mandatory parameters
[Parameter(Mandatory = $true)]
[string]$logFolderPath,
#Define other optional parameters.
[Parameter(Mandatory = $false)]
[boolean]$errorMembersOnly = $false,
[Parameter(Mandatory = $false)]
[boolean]$includeVerboseOutput = $true,
#Define parameters for multi-threaded operations
[Parameter(Mandatory = $false)]
[int]$threadNumberAssigned=0,
[Parameter(Mandatory = $false)]
[int]$totalThreadCount=0,
#Definte parameters for pre-collected permissions
[Parameter(Mandatory = $false)]
[boolean]$useCollectedFullMailboxAccessOnPrem=$FALSE,
[Parameter(Mandatory = $false)]
[boolean]$useCollectedFullMailboxAccessOffice365=$FALSE,
[Parameter(Mandatory = $false)]
[boolean]$useCollectedSendAsOnPrem=$FALSE,
[Parameter(Mandatory = $false)]
[boolean]$useCollectedFolderPermissionsOnPrem=$FALSE,
[Parameter(Mandatory = $false)]
[boolean]$useCollectedFolderPermissionsOffice365=$FALSE,
[Parameter(Mandatory =$FALSE)]
[boolean]$allowTelemetryCollection=$TRUE,
[Parameter(Mandatory =$FALSE)]
[boolean]$allowDetailedTelemetryCollection=$TRUE
)
#Define global variables.
$global:threadNumber=$threadNumberAssigned
$global:blogURL = "https://timmcmic.wordpress.com"
#Establish required MS Graph Scopes
$msGraphScopesRequired = @("User.Read.All", "Group.Read.All")
#Initialize telemetry collection.
$appInsightAPIKey = "63d673af-33f4-401c-931e-f0b64a218d89"
$traceModuleName = "DLConversion"
if ($allowTelemetryCollection -eq $TRUE)
{
start-telemetryConfiguration -allowTelemetryCollection $allowTelemetryCollection -appInsightAPIKey $appInsightAPIKey -traceModuleName $traceModuleName
}
#Create telemetry values.
$telemetryDLConversionV2Version = $NULL
$telemetryExchangeOnlineVersion = $NULL
$telemetryDLHierarchyVersionVersion = $NULL
$telemetryAzureADVersion = $NULL
$telemetryMSGraphAuthentication = $NULL
$telemetryMSGraphUsers = $NULL
$telemetryMSGraphGroups = $NULL
$telemetryActiveDirectoryVersion = $NULL
$telemetryOSVersion = (Get-CimInstance Win32_OperatingSystem).version
$telemetryStartTime = get-universalDateTime
$telemetryEndTime = $NULL
[double]$telemetryElapsedSeconds = 0
$telemetryEventName = "Start-DistributionListMigration"
$telemetryFunctionStartTime=$NULL
$telemetryFunctionEndTime=$NULL
[double]$telemetryNormalizeDN=0
[double]$telemetryValidateCloudRecipients=0
[double]$telemetryDependencyOnPrem=0
[double]$telemetryCollectOffice365Dependency=0
[boolean]$telemetryError=$FALSE
$windowTitle = ("get-DLHealthReport "+$groupSMTPAddress)
$host.ui.RawUI.WindowTitle = $windowTitle
$global:logFile=$NULL #This is the global variable for the calculated log file name
[string]$global:staticFolderName="\DLHealthCheck\"
[string]$global:staticAuditFolderName="\AuditData\"
[string]$global:importFile=$logFolderPath+$global:staticAuditFolderName
[string]$htmlFileName = "DLHealth.html"
[array]$global:testOffice365Errors=@()
[array]$htmlSections = @()
#Define variables for import data - used for importing data into pre-collect.
[array]$importData=@() #Empty array for the import data.
[string]$importFilePath=$NULL #Import file path where the XML data is located to import (calculated later)
#For mailbox folder permissions set these to false.
#Supported methods for gathering folder permissions require use of the pre-collection.
#Precolletion automatically sets these to true. These were origianlly added to support doing it at runtime - but its too slow.
[boolean]$retainMailboxFolderPermsOnPrem=$FALSE
[boolean]$retainMailboxFolderPermsOffice365=$FALSE
[boolean]$retainOffice365Settings=$true
[boolean]$retainFullMailboxAccessOnPrem=$FALSE
[boolean]$retainSendAsOnPrem=$FALSE
[boolean]$retainFullMailboxAccessOffice365=$FALSE
[boolean]$retainSendAsOffice365=$TRUE
#Define variables utilized in the core function that are not defined by parameters.
$coreVariables = @{
useOnPremisesExchange = @{ "Value" = $FALSE ; "Description" = "Boolean determines if Exchange on premises should be utilized" }
useAADConnect = @{ "Value" = $FALSE ; "Description" = "Boolean determines if an AADConnect isntance will be utilzied" }
exchangeOnPremisesPowershellSessionName = @{ "Value" = "ExchangeOnPremises" ; "Description" = "Static exchange on premises powershell session name" }
aadConnectPowershellSessionName = @{ "Value" = "AADConnect" ; "Description" = "Static AADConnect powershell session name" }
ADGlobalCatalogPowershellSessionName = @{ "Value" = "ADGlobalCatalog" ; "Description" = "Static AD Domain controller powershell session name" }
exchangeOnlinePowershellModuleName = @{ "Value" = "ExchangeOnlineManagement" ; "Description" = "Static Exchange Online powershell module name" }
DLHierarchyPowershellModuleName = @{ "Value" = "DLHierarchy" ; "Description" = "Static name for the DLHierarchy module" }
activeDirectoryPowershellModuleName = @{ "Value" = "ActiveDirectory" ; "Description" = "Static active directory powershell module name" }
azureActiveDirectoryPowershellModuleName = @{ "Value" = "AzureAD" ; "Description" = "Static azure active directory powershell module name" }
msGraphAuthenticationPowershellModuleName = @{ "Value" = "Microsoft.Graph.Authentication" ; "Description" = "Static ms graph powershell name authentication" }
msGraphUsersPowershellModuleName = @{ "Value" = "Microsoft.Graph.Users" ; "Description" = "Static ms graph powershell name users" }
msGraphGroupsPowershellModuleName = @{ "Value" = "Microsoft.Graph.Groups" ; "Description" = "Static ms graph powershell name groups" }
dlConversionPowershellModule = @{ "Value" = "DLConversionV2" ; "Description" = "Static dlConversionv2 powershell module name" }
globalCatalogPort = @{ "Value" = ":3268" ; "Description" = "Global catalog port definition" }
globalCatalogWithPort = @{ "Value" = ($globalCatalogServer+($corevariables.globalCatalogPort.value)) ; "Description" = "Global catalog server with port" }
}
#The variables below are utilized to define working parameter sets.
#Some variables are assigned to single values - since these will be utilized with functions that query or set information.
$onPremADAttributes = @{
onPremAcceptMessagesFromDLMembers = @{"Value" = "dlMemSubmitPerms" ; "Description" = "LDAP Attribute for Accept Messages from DL Members"}
onPremAcceptMessagesFromDLMembersCommon = @{"Value" = "AcceptMessagesFromMembers" ; "Description" = "LDAP Attribute for Accept Messages from DL Members"}
onPremRejectMessagesFromDLMembers = @{"Value" = "dlMemRejectPerms" ; "Description" = "LDAP Attribute for Reject Messages from DL Members"}
onPremRejectMessagesFromDLMembersCommon = @{"Value" = "RejectMessagesFromMembers" ; "Description" = "LDAP Attribute for Reject Messages from DL Members"}
onPremBypassModerationFromDL = @{"Value" = "msExchBypassModerationFromDLMembersLink" ; "Description" = "LDAP Attribute for Bypass Moderation from DL Members"}
onPremBypassModerationFromDLCommon = @{"Value" = "BypassModerationFromSendersOrMembers" ; "Description" = "LDAP Attribute for Bypass Moderation from DL Members"}
onPremForwardingAddress = @{"Value" = "altRecipient" ; "Description" = "LDAP Attribute for ForwardingAddress"}
onPremForwardingAddressCommon = @{"Value" = "ForwardingAddress" ; "Description" = "LDAP Attribute for ForwardingAddress"}
onPremGrantSendOnBehalfTo = @{"Value" = "publicDelegates" ; "Description" = "LDAP Attribute for Grant Send on Behalf To"}
onPremGrantSendOnBehalfToCommon = @{"Value" = "GrantSendOnBehalfTo" ; "Description" = "LDAP Attribute for Grant Send on Behalf To"}
onPremRejectMessagesFromSenders = @{"Value" = "unauthorig" ; "Description" = "LDAP Attribute for Reject Messages from Sender"}
onPremRejectMessagesFromSendersCommon = @{"Value" = "RejectMessagesFromSenders" ; "Description" = "LDAP Attribute for Reject Messages from Sender"}
onPremAcceptMessagesFromSenders = @{"Value" = "authOrig" ; "Description" = "LDAp Attribute for Accept Messages From Sender"}
onPremAcceptMessagesFromSendersCommon = @{"Value" = "AcceptMessagesFromSenders" ; "Description" = "LDAp Attribute for Accept Messages From Sender"}
onPremManagedBy = @{"Value" = "managedBy" ; "Description" = "LDAP Attribute for Managed By"}
onPremManagedByCommon = @{"Value" = "ManagedBy" ; "Description" = "LDAP Attribute for Managed By"}
onPremCoManagedBy = @{"Value" = "msExchCoManagedByLink" ; "Description" = "LDAP Attributes for Co Managers (Muiltivalued ManagedBy)"}
onPremCoManagedByCommon = @{"Value" = "ManagedBy" ; "Description" = "LDAP Attributes for Co Managers (Muiltivalued ManagedBy)"}
onPremModeratedBy = @{"Value" = "msExchModeratedByLink" ; "Description" = "LDAP Attrbitute for Moderated By"}
onPremModeratedByCommon = @{"Value" = "ModeratedBy" ; "Description" = "LDAP Attrbitute for Moderated By"}
onPremBypassModerationFromSenders = @{"Value" = "msExchBypassModerationLink" ; "Description" = "LDAP Attribute for Bypass Moderation from Senders"}
onPremBypassModerationFromSendersCommon = @{"Value" = "BypassModerationFromSendersorMembers" ; "Description" = "LDAP Attribute for Bypass Moderation from Senders"}
onPremMembers = @{"Value" = "member" ; "Description" = "LDAP Attribute for Distribution Group Members" }
onPremMembersCommon = @{"Value" = "Member" ; "Description" = "LDAP Attribute for Distribution Group Members" }
onPremForwardingAddressBL = @{"Value" = "altRecipientBL" ; "Description" = "LDAP Backlink Attribute for Forwarding Address"}
onPremRejectMessagesFromDLMembersBL = @{"Value" = "dlMemRejectPermsBL" ; "Description" = "LDAP Backlink Attribute for Reject Messages from DL Members"}
onPremAcceptMessagesFromDLMembersBL = @{"Value" = "dlMemSubmitPermsBL" ; "Description" = "LDAP Backlink Attribute for Accept Messages from DL Members"}
onPremManagedObjects = @{"Value" = "managedObjects" ; "Description" = "LDAP Backlink Attribute for Managed By"}
onPremMemberOf = @{"Value" = "memberOf" ; "Description" = "LDAP Backlink Attribute for Members"}
onPremBypassModerationFromDLMembersBL = @{"Value" = "msExchBypassModerationFromDLMembersBL" ; "Description" = "LDAP Backlink Attribute for Bypass Moderation from DL Members"}
onPremCoManagedByBL = @{"Value" = "msExchCoManagedObjectsBL" ; "Description" = "LDAP Backlink Attribute for Co Managers (Multivalued ManagedBY)"}
onPremGrantSendOnBehalfToBL = @{"Value" = "publicDelegatesBL" ; "Description" = "LDAP Backlink Attribute for Grant Send On Behalf To"}
onPremGroupType = @{"Value" = "groupType" ; "Description" = "Value representing universal / global / local / security / distribution"}
}
#Define the Office 365 attributes that will be used for filters.
$office365Attributes = @{
office365AcceptMessagesFrom = @{ "Value" = "AcceptMessagesOnlyFromDLMembers" ; "Description" = "All Office 365 objects that have accept messages from senders or members for the migrated group"}
office365BypassModerationFrom = @{ "Value" = "BypassModerationFromDLMembers" ; "Description" = "All Office 365 objects that have bypass moderation from senders or members for the migrated group"}
office365CoManagers = @{ "Value" = "CoManagedBy" ; "Description" = "ALl office 365 objects that have managed by set for the migrated group"}
office365GrantSendOnBehalfTo = @{ "Value" = "GrantSendOnBehalfTo" ; "Description" = "All Office 365 objects that have grant sent on behalf to for the migrated group"}
office365ManagedBy = @{ "Value" = "ManagedBy" ; "Description" = "All Office 365 objects that have managed by set on the group"}
office365Members = @{ "Value" = "Members" ; "Description" = "All Office 365 groups that the migrated group is a member of"}
office365RejectMessagesFrom = @{ "Value" = "RejectMessagesFromDLMembers" ; "Description" = "All Office 365 groups that have the reject messages from senders or members right assignged to the migrated group"}
office365ForwardingAddress = @{ "Value" = "ForwardingAddress" ; "Description" = "All Office 365 objects that have the migrated group set for forwarding"}
office365BypassModerationusers = @{ "Value" = "BypassModerationFromSendersOrMembers" ; "Description" = "All Office 365 objects that have bypass moderation for the migrated group"}
office365UnifiedAccept = @{ "Value" = "AcceptMessagesOnlyFromSendersOrMembers" ; "Description" = "All Office 365 Unified Groups that the migrated group has accept messages from senders or members rights assigned"}
office365UnifiedReject = @{ "Value" = "RejectMessagesFromSendersOrMembers" ; "Description" = "All Office 365 Unified Groups that the migrated group has reject messages from senders or members rights assigned"}
}
#Define XML files to contain backups.
$xmlFiles = @{
originalDLConfigurationADXML = @{ "Value" = "originalDLConfigurationADXML" ; "Description" = "XML file that exports the original DL configuration"}
originalDLConfigurationUpdatedXML = @{ "Value" = "originalDLConfigurationUpdatedXML" ; "Description" = "XML file that exports the updated DL configuration"}
office365DLConfigurationXML = @{ "Value" = "office365DLConfigurationXML" ; "Description" = "XML file that exports the Office 365 DL configuration"}
office365DLConfigurationPostMigrationXML = @{ "Value" = "office365DLConfigurationPostMigrationXML" ; "Description" = "XML file that exports the Office 365 DL configuration post migration"}
office365DLMembershipXML = @{ "Value" = "office365DLMembershipXML" ; "Description" = "XML file that exports the Office 365 DL membership post migration"}
exchangeDLMembershipSMTPXML = @{ "Value" = "exchangeDLMemberShipSMTPXML" ; "Description" = "XML file that holds the SMTP addresses of the on premises DL membership"}
exchangeRejectMessagesSMTPXML = @{ "Value" = "exchangeRejectMessagesSMTPXML" ; "Description" = "XML file that holds the Reject Messages From Senders or Members property of the on premises DL"}
exchangeAcceptMessagesSMTPXML = @{ "Value" = "exchangeAcceptMessagesSMTPXML" ; "Description" = "XML file that holds the Accept Messages from Senders or Members property of the on premises DL"}
exchangeManagedBySMTPXML = @{ "Value" = "exchangeManagedBySMTPXML" ; "Description" = "XML file that holds the ManagedBy proprty of the on premises DL"}
exchangeModeratedBySMTPXML = @{ "Value" = "exchangeModeratedBYSMTPXML" ; "Description" = "XML file that holds the Moderated By property of the on premises DL"}
exchangeBypassModerationSMTPXML = @{ "Value" = "exchangeBypassModerationSMTPXML" ; "Description" = "XML file that holds the Bypass Moderation From Senders or Members property of the on premises DL"}
exchangeGrantSendOnBehalfToSMTPXML = @{ "Value" = "exchangeGrantSendOnBehalfToXML" ; "Description" = "XML file that holds the Grant Send On Behalf To property of the on premises DL"}
exchangeSendAsSMTPXML = @{ "Value" = "exchangeSendASSMTPXML" ; "Description" = "XML file that holds the Send As rights of the on premises DL"}
allGroupsMemberOfXML = @{ "Value" = "allGroupsMemberOfXML" ; "Description" = "XML file that holds all of on premises groups the migrated group is a member of"}
allGroupsRejectXML = @{ "Value" = "allGroupsRejectXML" ; "Description" = "XML file that holds all of the on premises groups the migrated group has reject rights assigned"}
allGroupsAcceptXML = @{ "Value" = "allGroupsAcceptXML" ; "Description" = "XML file that holds all of the on premises groups the migrated group has accept rights assigned"}
allGroupsBypassModerationXML = @{ "Value" = "allGroupsBypassModerationXML" ; "Description" = "XML file that holds all of the on premises groups that the migrated group has bypass moderation rights assigned"}
allUsersForwardingAddressXML = @{ "Value" = "allUsersForwardingAddressXML" ; "Description" = "XML file that holds all recipients the migrated group hsa forwarding address set on"}
allGroupsGrantSendOnBehalfToXML = @{ "Value" = "allGroupsGrantSendOnBehalfToXML" ; "Description" = "XML file that holds all of the on premises objects that the migrated group hsa grant send on behalf to on"}
allGroupsManagedByXML = @{ "Value" = "allGroupsManagedByXML" ; "Description" = "XML file that holds all of the on premises objects the migrated group has managed by rights assigned"}
allGroupsSendAsXML = @{ "Value" = "allGroupSendAsXML" ; "Description" = "XML file that holds all of the on premises objects that have the migrated group with send as rights assigned"}
allGroupsSendAsNormalizedXML= @{ "Value" = "allGroupsSendAsNormalizedXML" ; "Description" = "XML file that holds all normalized send as right"}
allGroupsFullMailboxAccessXML = @{ "Value" = "allGroupsFullMailboxAccessXML" ; "Description" = "XML file that holds all full mailbox access rights assigned to the migrated group"}
allMailboxesFolderPermissionsXML = @{ "Value" = "allMailboxesFolderPermissionsXML" ; "Description" = "XML file that holds all mailbox folder permissions assigned to the migrated group"}
allOffice365MemberOfXML= @{ "Value" = "allOffice365MemberOfXML" ; "Description" = "XML file that holds All cloud only groups that have the migrated group as a member"}
allOffice365AcceptXML= @{ "Value" = "allOffice365AcceptXML" ; "Description" = "XML file that holds All cloud only groups that have the migrated group assigned accept messages from senders or members rights"}
allOffice365RejectXML= @{ "Value" = "allOffice365RejectXML" ; "Description" = "XML file that holds All cloud only groups that have the migrated group assigned reject messages from senders or members rights"}
allOffice365BypassModerationXML= @{ "Value" = "allOffice365BypassModerationXML" ; "Description" = "XML file that holds All cloud only groups that have the migrated group assigned bypass moderation from senders or members"}
allOffice365GrantSendOnBehalfToXML= @{ "Value" = "allOffice365GrantSentOnBehalfToXML" ; "Description" = "XML file that holds All cloud only groups that have the migrated group assigned grant send on behalf to rights"}
allOffice365ManagedByXML= @{ "Value" = "allOffice365ManagedByXML" ; "Description" = "XML file that holds All cloud only groups that have the migrated group assigned managed by rights"}
allOffice365ForwardingAddressXML= @{ "Value" = "allOffice365ForwardingAddressXML" ; "Description" = " XML file that holds all cloud only recipients where forwarding is set to the migrated grouop"}
allOffic365SendAsAccessXML = @{ "Value" = "allOffice365SendAsAccessXML" ; "Description" = "XML file that holds all cloud groups where send as rights are assigned to the migrated group"}
allOffice365FullMailboxAccessXML = @{ "Value" = "allOffice365FullMailboxAccessXML" ; "Description" = "XML file that holds all cloud only objects where full mailbox access is assigned to the migrated group"}
allOffice365MailboxesFolderPermissionsXML = @{ "Value" = 'allOffice365MailboxesFolderPermissionsXML' ; "Description" = "XML file that holds all cloud only recipients where a mailbox folder permission is assigned to the migrated group"}
allOffice365SendAsAccessOnGroupXML = @{ "Value" = 'allOffice365SendAsAccessOnGroupXML' ; "Description" = "XML file that holds all cloud only send as rights assigned to the migrated group"}
routingContactXML= @{ "Value" = "routingContactXML" ; "Description" = "XML file holds the routing contact configuration when intially created"}
routingDynamicGroupXML= @{ "Value" = "routingDynamicGroupXML" ; "Description" = "XML file holds the routing contact configuration when mail enabled"}
allGroupsCoManagedByXML= @{ "Value" = "allGroupsCoManagedByXML" ; "Description" = "XML file holds all on premises objects that the migrated group has managed by rights assigned"}
retainOffice365RecipientFullMailboxAccessXML= @{ "Value" = "office365RecipientFullMailboxAccess.xml" ; "Description" = "Import XML file for pre-gathered full mailbox access rights in Office 365"}
retainMailboxFolderPermsOffice365XML= @{ "Value" = "office365MailboxFolderPermissions.xml" ; "Description" = "Import XML file for pre-gathered mailbox folder permissions in Office 365"}
retainOnPremRecipientFullMailboxAccessXML= @{ "Value" = "onPremRecipientFullMailboxAccess.xml" ; "Description" = "Import XML for pre-gathered full mailbox access rights "}
retainOnPremMailboxFolderPermissionsXML= @{ "Value" = "onPremailboxFolderPermissions.xml" ; "Description" = "Import XML file for mailbox folder permissions"}
retainOnPremRecipientSendAsXML= @{ "Value" = "onPremRecipientSendAs.xml" ; "Description" = "Import XML file for send as permissions"}
azureDLConfigurationXML = @{"Value" = "azureADDL" ; "Description" = "Export XML file holding the configuration from azure active directory"}
azureDLMembershipXML = @{"Value" = "azureADDLMembership" ; "Description" = "Export XML file holding the membership of the Azure AD group"}
msGraphDLConfigurationXML = @{"Value" = "msGraphADDL" ; "Description" = "Export XML file holding the configuration from azure active directory"}
msGraphDLMembershipXML = @{"Value" = "msGraphADDLMembership" ; "Description" = "Export XML file holding the membership of the Azure AD group"}
preCreateErrorsXML = @{"value" = "preCreateErrors" ; "Description" = "Export XML of all precreate errors for group to be migrated."}
testOffice365ErrorsXML = @{"value" = "testOffice365Errors" ; "Description" = "Export XML of all tested recipient errors in Offic3 365."}
office365AcceptMessagesFromSendersOrMembersXML= @{"value" = "office365AcceptMessagesFromSendersOrMembers" ; "Description" = "Export XML of all Office 365 accept messages from senders or member normalized."}
office365RejectMessagesFromSendersOrMembersXML= @{"value" = "office365RejectMessagesFromSendersOrMembers" ; "Description" = "Export XML of all Office 365 reject messages from senders or member normalized."}
office365ModeratedByXML= @{"value" = "office365ModeratedByXML" ; "Description" = "Export XML of all Office 365 moderatedBy normalized."}
office365BypassModerationFromSendersOrMembersXML= @{"value" = "office365BypassModerationFromSendersOrMembers" ; "Description" = "Export XML of all Office 365 bypass moderatios from senders or member normalized."}
office365ManagedByXML= @{"value" = "office365ManagedBy" ; "Description" = "Export XML of all Office 365 managedby normalized."}
office365GrantSendOnBehalfToXML= @{"value" = "office365GrantSendOnBehalfToXML" ; "Description" = "Export XML of all Office 365 grant send on behalf to normalized."}
onPremMemberEvalXML= @{"value" = "onPremMemberEvalXML" ; "Description" = "Export XML of all Office 365 grant send on behalf to normalized."}
office365MemberEvalXML = @{"value" = "office365MemberEvalXML" ; "Description" = "Export XML of all Office 365 grant send on behalf to normalized."}
onPremMemberEvalErrorsXML= @{"value" = "onPremMemberEvalErrorsXML" ; "Description" = "Export XML of all Office 365 grant send on behalf to normalized."}
office365MemberEvalErrorsXML = @{"value" = "office365MemberEvalErrorsXML" ; "Description" = "Export XML of all Office 365 grant send on behalf to normalized."}
office365AcceptMessagesFromSendersOrMembersEvalXML = @{"value" = "office365AcceptMessagesFromSendersOrMembersEvalXML" ; "Description" = "Export XML of all Office 365 grant send on behalf to normalized."}
office365RejectMessagesFromSendersOrMembersEvalXML = @{"value" = "office365RejectMessagesFromSendersOrMembersEvalXML" ; "Description" = "Export XML of all Office 365 grant send on behalf to normalized."}
office365ModeratedByEvalXML = @{"value" = "office365ModeratedByEvalXML" ; "Description" = "Export XML of all Office 365 grant send on behalf to normalized."}
office365BypassMOderationFromSendersOrMembersEvalXML = @{"value" = "office365BypassModerationFromSendersOrMembersEvalXML" ; "Description" = "Export XML of all Office 365 grant send on behalf to normalized."}
office365ManagedByEvalXML = @{"value" = "office365ManagedByEvalXML" ; "Description" = "Export XML of all Office 365 grant send on behalf to normalized."}
office365GrantSendOnBehalfToEvalXML = @{"value" = "office365GrantSendOnBehalfToEvalXML" ; "Description" = "Export XML of all Office 365 grant send on behalf to normalized."}
office365ProxyAddressesEvalXML = @{"value" = "office365ProxyAddressesEvalXML" ; "Description" = "Export XML of all Office 365 grant send on behalf to normalized."}
office365AttributeEvalXML = @{"value" = "office365AttributeEvalXML" ; "Description" = "Export XML of all Office 365 grant send on behalf to normalized."}
summaryCountsXML = @{"value" = "summaryCountsXML" ; "Description" = "Export XML of all Office 365 grant send on behalf to normalized."}
}
[array]$dlPropertySet = '*' #Clear all properties of a given object
#On premises variables for the distribution list to be migrated.
$originalDLConfiguration=$NULL #This holds the on premises DL configuration for the group to be migrated.
[array]$exchangeDLMembershipSMTP=@() #Array of DL membership from AD.
[array]$exchangeRejectMessagesSMTP=@() #Array of members with reject permissions from AD.
[array]$exchangeAcceptMessagesSMTP=@() #Array of members with accept permissions from AD.
[array]$exchangeManagedBySMTP=@() #Array of members with manage by rights from AD.
[array]$exchangeModeratedBySMTP=@() #Array of members with moderation rights.
[array]$exchangeBypassModerationSMTP=@() #Array of objects with bypass moderation rights from AD.
[array]$exchangeGrantSendOnBehalfToSMTP=@() #Array of objects with grant send on behalf to normalized SMTP
[array]$exchangeSendAsSMTP=@() #Array of objects wtih send as rights normalized SMTP
#The following variables hold information regarding other groups in the environment that have dependnecies on the group to be migrated.
[array]$allGroupsMemberOf=$NULL #Complete AD information for all groups the migrated group is a member of.
[array]$allGroupsReject=$NULL #Complete AD inforomation for all groups that the migrated group has reject mesages from.
[array]$allGroupsAccept=$NULL #Complete AD information for all groups that the migrated group has accept messages from.
[array]$allGroupsBypassModeration=$NULL #Complete AD information for all groups that the migrated group has bypass moderations.
[array]$allUsersForwardingAddress=$NULL #All users on premsies that have this group as a forwarding DN.
[array]$allGroupsGrantSendOnBehalfTo=$NULL #All dependencies on premsies that have grant send on behalf to.
[array]$allGroupsManagedBy=$NULL #All dependencies on premises that have managed by rights
[array]$allObjectsFullMailboxAccess=$NULL #All dependencies on premises that have full mailbox access rights
[array]$allObjectSendAsAccess=$NULL #All dependencies on premises that have the migrated group with send as rights.
[array]$allObjectsSendAsAccessNormalized=@() #All dependencies send as rights normalized
[array]$allMailboxesFolderPermissions=@() #All dependencies on premises with mailbox folder permissions defined
[array]$allGroupsCoManagedByBL=$NULL #All groups on premises where the migrated group is a manager
#The following variables hold information regarding Office 365 objects that have dependencies on the migrated DL.
[array]$allOffice365MemberOf=$NULL #All cloud only groups the migrated group is a member of.
[array]$allOffice365Accept=$NULL #All cloud only groups the migrated group has accept messages from senders or members.
[array]$allOffice365Reject=$NULL #All cloud only groups the migrated group has reject messages from senders or members.
[array]$allOffice365BypassModeration=$NULL #All cloud only groups the migrated group has bypass moderation from senders or members.
[array]$allOffice365ManagedBy=$NULL #All cloud only groups the migrated group has managed by rights on.
[array]$allOffice365GrantSendOnBehalfTo=$NULL #All cloud only groups the migrated group has grant send on behalf to on.
[array]$allOffice365ForwardingAddress=$NULL #All cloud only recipients the migrated group has forwarding address
[array]$allOffice365FullMailboxAccess=$NULL #All cloud only recipients the migrated group has full ,amilbox access on.
[array]$allOffice365SendAsAccess=$NULL #All cloud only groups the migrated group has send as access on.
[array]$allOffice365SendAsAccessOnGroup = $NULL #All send as permissions set on the on premises group that are set in the cloud.
[array]$allOffice365MailboxFolderPermissions=$NULL #All cloud only groups the migrated group has mailbox folder permissions on.
#Define normlaized variables for the Office 365 group.
[array]$office365AcceptMessagesFromSendersOrMembers=$NULL
[array]$office365RejectMessagesFromSendersOrMembers=$NULL
[array]$office365ModeratedBy=$NULL
[array]$office365BypassModerationFromSendersOrMembers=$NULL
[array]$office365ManagedBy = $NULL
[array]$office365GrantSendOnBehalfTo = $NULL
[array]$office365DLMembership = $NULL
#Cloud variables for the distribution list to be migrated.
$office365DLConfiguration = $NULL #This holds the office 365 DL configuration for the group to be migrated.
$azureADDlConfiguration = $NULL #This holds the Azure AD DL configuration
$azureADDlMembership = $NULL
$msGraphADDlConfiguration = $NULL #This holds the Azure AD DL configuration
$msGraphDlMembership = $NULL
#Create arrays to track the health objects that will be converted in the reprot.
[array]$onPremMemberEval = @()
[array]$office365MemberEval = @()
[array]$office365AcceptMessagesFromSendersOrMembersEval=@()
[array]$office365RejectMessagesFromSendrsOfMembersEval=@()
[array]$office365ModeratedByEval=@()
[array]$office365BypassModerationFromSendersOrMembersEval=@()
[array]$office365ManagedByEval=@()
[array]$office365GrantSendOnBehalfToEval=@()
[array]$office365ProxyAddressesEval = @()
[array]$office365AttributeEval = @()
#For loop counter.
[int]$forLoopCounter=0
[int]$forLoopTrigger=1000
#Define variables for kerberos enablement.
$commandStartTime = get-date
$commandEndTime = $NULL
[int]$kerberosRunTime = 4
[array]$threadFolder="\Thread0","\Thread1","\Thread2","\Thread3","\Thread4","\Thread5","\Thread6","\Thread7","\Thread8","\Thread9","\Thread10"
#If multi threaded - the log directory needs to be created for each thread.
#Create the log folder path for status before changing the log folder path.
if ($totalThreadCount -gt 0)
{
$logFolderPath=$logFolderPath+$threadFolder[$global:threadNumber]
}
[string]$htmlFile = $logFolderPath+$global:staticFolderName+$htmlFileName
new-LogFile -groupSMTPAddress $groupSMTPAddress.trim() -logFolderPath $logFolderPath
$traceFilePath = $logFolderPath + $global:staticFolderName
out-logfile -string ("Trace file path: "+$traceFilePath)
out-logfile -string "********************************************************************************"
out-logfile -string "NOTICE"
out-logfile -string "Telemetry collection is now enabled by default."
out-logfile -string "For information regarding telemetry collection see https://timmcmic.wordpress.com/2022/11/14/4288/"
out-logfile -string "Administrators may opt out of telemetry collection by using -allowTelemetryCollection value FALSE"
out-logfile -string "Telemetry collection is appreciated as it allows further development and script enhancement."
out-logfile -string "********************************************************************************"
#Output all parameters bound or unbound and their associated values.
Out-LogFile -string "********************************************************************************"
Out-LogFile -string "PARAMETERS"
Out-LogFile -string "********************************************************************************"
write-functionParameters -keyArray $MyInvocation.MyCommand.Parameters.Keys -parameterArray $PSBoundParameters -variableArray (Get-Variable -Scope Local -ErrorAction Ignore)
Out-LogFile -string "================================================================================"
Out-LogFile -string "BEGIN START-DISTRIBUTIONLISTMIGRATION"
Out-LogFile -string "================================================================================"
out-logfile -string "Set error action preference to continue to allow write-error in out-logfile to service exception retrys"
out-logfile -string ("Runtime start UTC: " + $telemetryStartTime.ToString())
if ($errorActionPreference -ne "Continue")
{
out-logfile -string ("Current Error Action Preference: "+$errorActionPreference)
$errorActionPreference = "Continue"
out-logfile -string ("New Error Action Preference: "+$errorActionPreference)
}
else
{
out-logfile -string ("Current Error Action Preference is CONTINUE: "+$errorActionPreference)
}
out-logfile -string "Ensure that all strings specified have no leading or trailing spaces."
#Perform cleanup of any strings so that no spaces existin trailing or leading.
$groupSMTPAddress = remove-stringSpace -stringToFix $groupSMTPAddress
$globalCatalogServer = remove-stringSpace -stringToFix $globalCatalogServer
$logFolderPath = remove-stringSpace -stringToFix $logFolderPath
if ($exchangeOnlineCertificateThumbPrint -ne "")
{
$exchangeOnlineCertificateThumbPrint=remove-stringSpace -stringToFix $exchangeOnlineCertificateThumbPrint
}
$exchangeOnlineEnvironmentName=remove-stringSpace -stringToFix $exchangeOnlineEnvironmentName
if ($exchangeOnlineOrganizationName -ne "")
{
$exchangeOnlineOrganizationName=remove-stringSpace -stringToFix $exchangeOnlineOrganizationName
}
if ($exchangeOnlineAppID -ne "")
{
$exchangeOnlineAppID=remove-stringSpace -stringToFix $exchangeOnlineAppID
}
<#
if ($azureTenantID -ne $NULL)
{
$azureTenantID = remove-StringSpace -stringToFix $azureTenantID
}
if ($azureCertificateThumbprint -ne $NULL)
{
$azureCertificateThumbprint = remove-StringSpace -stringToFix $azureCertificateThumbPrint
}
if ($azureEnvironmentName -ne $NULL)
{
$azureEnvironmentName = remove-StringSpace -stringToFix $azureEnvironmentName
}
if ($azureApplicationID -ne $NULL)
{
$azureApplicationID = remove-stringSpace -stringToFix $azureApplicationID
}
#>
$msGraphTenantID = remove-stringSpace -stringToFix $msGraphTenantID
$msGraphCertificateThumbprint = remove-stringSpace -stringToFix $msGraphCertificateThumbprint
$msGraphApplicationID = remove-stringSpace -stringToFix $msGraphApplicationID
if ($exchangeOnlineCredential -ne $null)
{
Out-LogFile -string ("ExchangeOnlineUserName = "+ $exchangeOnlineCredential.UserName.toString())
}
<#
if ($azureADCreential -ne $NULL)
{
out-logfile -string ("AzureADUserName = "+$azureADCredential.userName.toString())
}
#>
Out-LogFile -string "********************************************************************************"
Out-LogFile -string "********************************************************************************"
Out-LogFile -string " RECORD VARIABLES"
Out-LogFile -string "********************************************************************************"
out-logfile -string ("Global import file: "+$global:importFile)
out-logfile -string ("Global staticFolderName: "+$global:staticFolderName)
out-logfile -string ("Global threadNumber: "+$global:threadNumber)
write-hashTable -hashTable $xmlFiles
write-hashTable -hashTable $office365Attributes
write-hashTable -hashTable $onPremADAttributes
write-hashTable -hashTable $coreVariables
Out-LogFile -string "********************************************************************************"
#Perform paramter validation manually.
Out-LogFile -string "********************************************************************************"
Out-LogFile -string "ENTERING PARAMTER VALIDATION"
Out-LogFile -string "********************************************************************************"
#Validate that only one method of engaging exchange online was specified.
Out-LogFile -string "Validating Exchange Online Credentials."
start-parameterValidation -exchangeOnlineCredential $exchangeOnlineCredential -exchangeOnlineCertificateThumbprint $exchangeOnlineCertificateThumbprint -threadCount 0
#Validating that all portions for exchange certificate auth are present.
out-logfile -string "Validating parameters for Exchange Online Certificate Authentication"
start-parametervalidation -exchangeOnlineCertificateThumbPrint $exchangeOnlineCertificateThumbprint -exchangeOnlineOrganizationName $exchangeOnlineOrganizationName -exchangeOnlineAppID $exchangeOnlineAppID
#Validate that only one method of engaging exchange online was specified.
<#
Out-LogFile -string "Validating Azure AD Credentials."
start-parameterValidation -azureADCredential $azureADCredential -azureCertificateThumbPrint $azureCertificateThumbprint -threadCount 0
#Validate that all information for the certificate connection has been provieed.
out-logfile -string "Validation all components available for AzureAD Cert Authentication"
start-parameterValidation -azureCertificateThumbPrint $azureCertificateThumbprint -azureTenantID $azureTenantID -azureApplicationID $azureApplicationID
#>
out-logfile -string "Validation all components available for MSGraph Cert Auth"
start-parameterValidation -msGraphCertificateThumbPrint $msGraphCertificateThumbprint -msGraphTenantID $msGraphTenantID -msGraphApplicationID $msGraphApplicationID
#exit #Debug exit.
#Validate that an OU was specified <if> retain group is not set to true.
if ($useCollectedFullMailboxAccessOnPrem -eq $TRUE)
{
$retainFullMailboxAccessOnPrem=$TRUE
}
if ($useCollectedFullMailboxAccessOffice365 -eq $TRUE)
{
$retainFullMailboxAccessOffice365=$TRUE
}
if ($useCollectedSendAsOnPrem -eq $TRUE)
{
$retainSendAsOnPrem=$TRUE
}
if ($useCollectedFolderPermissionsOnPrem -eq $TRUE)
{
$retainMailboxFolderPermsOnPrem=$TRUE
}
if ($useCollectedFolderPermissionsOffice365 -eq $TRUE)
{
$retainMailboxFolderPermsOffice365=$TRUE
}
Out-LogFile -string "END PARAMETER VALIDATION"
Out-LogFile -string "********************************************************************************"
# EXIT #Debug Exit
#If exchange server information specified - create the on premises powershell session.
Out-LogFile -string "********************************************************************************"
Out-LogFile -string "ESTABLISH POWERSHELL SESSIONS"
Out-LogFile -string "********************************************************************************"
#Test to determine if the exchange online powershell module is installed.
#The exchange online session has to be established first or the commandlet set from on premises fails.
Out-LogFile -string "Calling Test-PowerShellModule to validate the Exchange Module is installed."
$telemetryExchangeOnlineVersion = Test-PowershellModule -powershellModuleName $corevariables.exchangeOnlinePowershellModuleName.value -powershellVersionTest:$TRUE
out-logfile -string "Calling Test-PowershellModule to validate the DLHierarchy Module."
$telemetryDLHierarchyVersion = Test-PowershellModule -powerShellModuleName $corevariables.dlhierarchypowershellmodulename.value -powershellversiontest:$TRUE
Out-LogFile -string "Calling Test-PowerShellModule to validate the Active Directory is installed."
$telemetryActiveDirectoryVersion = Test-PowershellModule -powershellModuleName $corevariables.activeDirectoryPowershellModuleName.value
out-logfile -string "Calling Test-PowershellModule to validate the DL Conversion Module version installed."
$telemetryDLConversionV2Version = Test-PowershellModule -powershellModuleName $corevariables.dlConversionPowershellModule.value -powershellVersionTest:$TRUE
<#
out-logfile -string "Calling Test-PowershellModule to validate the AzureAD Powershell Module version installed."
$telemetryAzureADVersion = Test-PowershellModule -powershellModuleName $corevariables.azureActiveDirectoryPowershellModuleName.value -powershellVersionTest:$TRUE
#>
out-logfile -string "Calling Test-PowershellModule to validate the Microsoft Graph Authentication versions installed."
$telemetryMSGraphAuthentication = test-powershellModule -powershellmodulename $corevariables.msgraphauthenticationpowershellmodulename.value -powershellVersionTest:$TRUE
out-logfile -string "Calling Test-PowershellModule to validate the Microsoft Graph Users versions installed."
$telemetryMSGraphUsers = test-powershellModule -powershellmodulename $corevariables.msgraphuserspowershellmodulename.value -powershellVersionTest:$TRUE
out-logfile -string "Calling Test-PowershellModule to validate the Microsoft Graph Users versions installed."
$telemetryMSGraphGroups = test-powershellModule -powershellmodulename $corevariables.msgraphgroupspowershellmodulename.value -powershellVersionTest:$TRUE
<#
#Create the azure ad connection
Out-LogFile -string "Calling nea-AzureADPowershellSession to create new connection to azure active directory."
if ($azureCertificateThumbprint -eq "")
{
#User specified non-certifate authentication credentials.
try {
New-AzureADPowershellSession -azureADCredential $azureADCredential -azureEnvironmentName $azureEnvironmentName
}
catch {
out-logfile -string "Unable to create the Azure AD powershell session using credentials."
out-logfile -string $_ -isError:$TRUE
}
}
elseif ($azureCertificateThumbprint -ne "")
{
#User specified thumbprint authentication.
try {
new-AzureADPowershellSession -azureCertificateThumbprint $azureCertificateThumbprint -azureApplicationID $azureApplicationID -azureTenantID $azureTenantID -azureEnvironmentName $azureEnvironmentName
}
catch {
out-logfile -string "Unable to create the exchange online connection using certificate."
out-logfile -string $_ -isError:$TRUE
}
}
#>
#As of now this is optional.
#Create the connection to exchange online.
Out-LogFile -string "Calling New-ExchangeOnlinePowershellSession to create session to office 365."
if ($exchangeOnlineCertificateThumbPrint -eq "")
{
#User specified non-certifate authentication credentials.
try {
New-ExchangeOnlinePowershellSession -exchangeOnlineCredentials $exchangeOnlineCredential -exchangeOnlineEnvironmentName $exchangeOnlineEnvironmentName -debugLogPath $traceFilePath
}
catch {
out-logfile -string "Unable to create the exchange online connection using credentials."
out-logfile -string $_ -isError:$TRUE
}
}
elseif ($exchangeOnlineCertificateThumbPrint -ne "")
{
#User specified thumbprint authentication.
try {
new-ExchangeOnlinePowershellSession -exchangeOnlineCertificateThumbPrint $exchangeOnlineCertificateThumbPrint -exchangeOnlineAppId $exchangeOnlineAppID -exchangeOnlineOrganizationName $exchangeOnlineOrganizationName -exchangeOnlineEnvironmentName $exchangeOnlineEnvironmentName -debugLogPath $traceFilePath
}
catch {
out-logfile -string "Unable to create the exchange online connection using certificate."
out-logfile -string $_ -isError:$TRUE
}
}
Out-LogFile -string "Calling nea-msGraphADPowershellSession to create new connection to msGraph active directory."
if ($msGraphCertificateThumbprint -ne "")
{
#User specified thumbprint authentication.
try {
new-msGraphPowershellSession -msGraphCertificateThumbprint $msGraphCertificateThumbprint -msGraphApplicationID $msGraphApplicationID -msGraphTenantID $msGraphTenantID -msGraphEnvironmentName $msGraphEnvironmentName -msGraphScopesRequired $msGraphScopesRequired
}
catch {
out-logfile -string "Unable to create the exchange online connection using certificate."
out-logfile -string $_ -isError:$TRUE
}
}
elseif ($msGraphTenantID -ne "")
{
try
{
new-msGraphPowershellSession -msGraphTenantID $msGraphTenantID -msGraphEnvironmentName $msGraphEnvironmentName -msGraphScopesRequired $msGraphScopesRequired
}
catch