Sunday, July 19, 2020

Public Folder Migration



    To add Public Folder of exchange onprem 2013 to OWA - Right click Favourites - ADD.
    To see that public folder in Outlook - click Folders - and it will be visible.

    Migrating your Exchange Server public folders to Exchange Online requires Exchange Server 2013 CU15 or later, or Exchange Server 2016 CU4 or later, to be running in your on-premises environment.

    When you upgrade to Exchange Server 2013 CU15 or later, or to Exchange Server 2016 CU4 or later, you must also prepare Active Directory or your public folder migration will fail. Download latest CU. Extract:

    Setup.exe /PrepareAD /IAcceptExchangeServerLicenseTerms

    Check that the size of single public folder is no more than 25 GB. If the size exceeds 25 GB, either delete the content or divide the content into multiple small public folders.



    It takes time for DNS Caches to direct messages to your mail-enabled public folders in cloud. To receive messages in mail enabled

    Public folders in O365, create an accepted domain at On-prem:

    At On-prem:

    To check whether accepted domain is already present:
    Get-AcceptedDomain | Where {$_.DomainName -eq "exolab123.mail.onmicrosoft.com"}   

    "If no Hybrid is setup", run the below command to create a new Accepted domain:

    New-AcceptedDomain -Name PublicFolderDestination_78c0b207_5ad2_4fee_8cb9_f373175b3f99 -DomainName exolab123.mail.onmicrosoft.com -DomainType InternalRelay     (optional)

    If exolab123.mail.onmicrosoft.com is already created by Hybrid Connector, just rename it to PublicFolderDestination_78c0b207_5ad2_4fee_8cb9_f373175b3f99 leaving the domain name Exolab.tk. and all other parameters

    To Rename: AT On-Prem:
    Get-AcceptedDomain | Where {$_.DomainName -eq "exolab123.mail.onmicrosoft.com"} | Set-AcceptedDomain -Name
    PublicFolderDestination_78c0b207_5ad2_4fee_8cb9_f373175b3f99

    Make your custom domain Internal Relay to receive emails in Public Folders in EXO.

    At OnPrem, ensure there is no / or \ in the names of the Public Folders, remove it. To check whether there is any / or \ in the names of Public Folders:

    Get-PublicFolder -Recurse -ResultSize Unlimited | Where {$_.Name -like "*\*" -or $_.Name -like "*/*"} | Format-List Name, Identity, EntryId   (optional)

    If found \ or /, rename it from below command:
    Set-PublicFolder -Identity "<public folder EntryId>" -Name "<new public folder name>"    (optional)

    To check if there is any Previous Migration done on Public Folders: (optional)

    Get-OrganizationConfig | Format-List  PublicFolderMailboxesLockedForNewConnections, PublicFolderMailboxesMigrationComplete    (optional)

    PublicFolderMailboxesLockedForNewConnections : False    (should be False)
    PublicFolderMailboxesMigrationComplete       : False    (should be False)

    If the above value comes out to be True, make it False by running the following: (optional)
    Set-OrganizationConfig -PublicFolderMailboxesLockedForNewConnections:$false -PublicFolderMailboxesMigrationComplete:$false    (optional)

    To take snapshots of your current public folder deployment:  (make take some time)
    Get-PublicFolder -Recurse -ResultSize Unlimited | Export-CliXML OnPrem_PFStructure.xml

    Public folder statistics such as item count, size, and owner:
    Get-PublicFolderStatistics -ResultSize Unlimited | Export-CliXML OnPrem_PFStatistics.xml

    Public folder permissions:
    Get-PublicFolder -Recurse -ResultSize Unlimited | Get-PublicFolderClientPermission | Select-Object Identity,User,AccessRights -

    ExpandProperty AccessRights | Export-CliXML OnPrem_PFPerms.xml


    Snapshot of your mail-enabled public folders:
    Get-MailPublicFolder -ResultSize Unlimited | Export-CliXML OnPrem_MEPF.xml

    Save the above reports somewhere safe as Source Public Folder Reports

    If you are using Azure AD Connect to Sync AD Objects, re-configure it - Customize synchronization options - Make sure that Exchange Mail Public Folders is not selected.

    Now
    Connect to Exchange Online PowerShell:

    There should not be any existing Public Folder Migration requests:
    Get-MigrationBatch | ?{$_.MigrationType.ToString() -eq "PublicFolder"}

    Remove any existing public folder batch migration requests:  (Optional)
    Remove-MigrationBatch <name of migration batch> -Confirm:$false

    There should not be any Public Folder or Public Folder Mailboxes in O365 earlier:

    See any Public Folder Mailboxes:
    Get-Mailbox -PublicFolder   (Optional)

    See any Public Folders:
    Get-PublicFolder -Recurse

    Remove Public Folders: (Optional)
    Get-MailPublicFolder -ResultSize Unlimited | where {$_.EntryId -ne $null}| Disable-MailPublicFolder -Confirm:$false
    Get-PublicFolder -GetChildren \ -ResultSize Unlimited | Remove-PublicFolder -Recurse -Confirm:$false

    Remove Public Folder Mailboxes: (Optional)
    $hierarchyMailboxGuid = $(Get-OrganizationConfig).RootPublicFolderMailbox.HierarchyMailboxGuid
    Get-Mailbox -PublicFolder | Where-Object {$_.ExchangeGuid -ne $hierarchyMailboxGuid} | Remove-Mailbox -PublicFolder -Confirm:$false -Force
    Get-Mailbox -PublicFolder | Where-Object {$_.ExchangeGuid -eq $hierarchyMailboxGuid} | Remove-Mailbox -PublicFolder -Confirm:$false -Force
    Get-Mailbox -PublicFolder -SoftDeletedMailbox | % {Remove-Mailbox -PublicFolder $_.PrimarySmtpAddress -PermanentlyDelete:$true -force}

    Folder-to-size map file is stats.csv file.
    Folder-to-mailbox map file is map.csv file


    At On-Prem, Create the Folder Name to Folder Size Mapping File using Script "Export-ModernPublicFolderStatistics.ps1":

    Three columns: FolderName, FolderSize, and DeletedItemSize. 

    FolderSize and DeletedItemSize shows value in bytes.

    e.g., \PublicFolder01,10240, 100 means 10240 bytes/ 10 KB in size and 100 bytes of recoverable items are there in it.

    Syntax: (To Run at On-Prem EMS)
    .\Export-ModernPublicFolderStatistics.ps1 <Folder-to-size map path>

    .\Export-ModernPublicFolderStatistics.ps1 stats.csv   (Press A to always run)

    Now map On-Prem Source Public Folders to Exchange Online Public Folder Mailboxes. This file will calculate the correct number of public folder mailboxes in Exchange Online:

    Syntax:
    .\ModernPublicFolderToMailboxMapGenerator.ps1 <Maximum mailbox size in bytes><Maximum mailbox recoverable item size in bytes><Folder-to-size map path><Folder-to-mailbox map path>

    .\ModernPublicFolderToMailboxMapGenerator.ps1 -MailboxSize 25GB -MailboxRecoverableItemSize 1GB -ImportFile .\stats.csv -ExportFile map.csv     

    Map.csv will use Generic Names for the Target Public Folder Mailboxes that will be created in Exchange Online. You can change the name of the Mailbox Names according to your organization choice.

    Create Public Folder Mailboxes in Office 365:  Copy map.csv in C:\

    In Exchange Online PowerShell:

    $mappings = Import-Csv "C:\map.csv"
    $primaryMailboxName = ($mappings | Where-Object FolderPath -eq "\" ).TargetMailbox;
    New-Mailbox -HoldForMigration:$true -PublicFolder -IsExcludedFromServingHierarchy:$false $primaryMailboxName
    ($mappings | Where-Object TargetMailbox -ne $primaryMailboxName).TargetMailbox | Sort-Object -unique | ForEach-Object { New-Mailbox -PublicFolder -IsExcludedFromServingHierarchy:$false $_ }

    The above script will create same set of Public Folder Mailboxes in O365.

    Now Start the Migration Process:

    At On-Prem EMS:

    Synchronize mail-enabled public folders from your local Active Directory to Exchange Online:
    .\Sync-ModernMailPublicFolders.ps1 -Credential (Get-Credential) -CsvSummaryFile:sync_summary.csv    (Press A, it will create Sync_summary file in same folder) Enter O365 Credentials.

    Now add the Admin user to be a member of Public Folder Management Group in ON-Prem 2013.

    At O365 PowerShell:
    Syntax:
    $Source_Credential = Get-Credential <source_domain>\<PublicFolder_Administrator_Account>

    $Source_Credential = Get-Credential Exolab.tk\DC10User          (enter the password)


    Cloud PowerShell in ISE: 
    Syntax: FQDN of Exchange Mailbox Replication Service (MRS) Server:

    $Source_RemoteServer = "<MRS proxy endpoint server>"

    $Source_RemoteServer = "mail.exolab.tk"     (inverted commas important, also important to run in ISE and MRS connection should work properly or migration Endpoint name should come automatically)

    At On-Prem EMS:
    Find the GUID of the primary hierarchy mailbox:

    (Get-OrganizationConfig).RootPublicFolderMailbox.HierarchyMailboxGuid.GUID
    9eccf100-b442-4ecb-b0a1-cff5317a4eb1        (copy this)

    At Cloud Powershell:
    Create the public folder migration endpoint and the public folder migration request:

    Syntax:

    [byte[]]$bytes = Get-Content -Encoding Byte <folder_mapping.csv>
    $PfEndpoint = New-MigrationEndpoint -PublicFolder -Name PublicFolderEndpoint -RemoteServer $Source_RemoteServer -Credentials
    $Source_Credential
    New-MigrationBatch -Name PublicFolderMigration -CSVData $bytes -SourceEndpoint $PfEndpoint.Identity -SourcePfPrimaryMailboxGuid <guid you noted from previous step> -AutoStart -NotificationEmails <email addresses for migration notifications>

    Run In Cloud PowerShell in ISE:

    [byte[]]$bytes = Get-Content -Encoding Byte C:\map.csv
    $PfEndpoint = New-MigrationEndpoint -PublicFolder -Name PublicFolderEndpoint -RemoteServer $Source_RemoteServer -Credentials
    $Source_Credential
    New-MigrationBatch -Name PublicFolderMigration -CSVData $bytes -SourceEndpoint $PfEndpoint.Identity -SourcePfPrimaryMailboxGuid

    9eccf100-b442-4ecb-b0a1-cff5317a4eb1 -AutoStart -NotificationEmails ajey@exolab.tk

    The above command will create a migration endpoint in O365 with type Public Folder (not as remote move). Above Command will ask On-
    Prem Credentials - Exolab.tk\DC10User. If you don't want to enter credentials, $Source_Credential=Get-credentials and save them. It worked for me after closing all windows (freeing up ram, else I was getting mrsproxy timeout connections error)

    If the above command fails, then run this one in Cloud Powershell:
    New-MigrationBatch -Name PublicFolderMigration -CSVData $bytes -SourceEndpoint $PfEndpoint.Identity -AutoStart -NotificationEmails ajey@exolab.tk

    or

    New-MigrationBatch -Name PFM01  -CSVData (Get-Content "C:\stats.csv" -Encoding Byte) -SourceEndpoint PublicFolderEndpoint -NotificationEmails ajey@exolab.tk -TargetDeliveryDomain exolab123.mail.onmicrosoft.com

    Still if it fails, in Cloud create the manual migration endpoint - PublicFolderEndpoint - DC10User@exolab.tk, then DC10.exolab.tk - PublicFolderEndpoint - 100, 100, Finish. Wait for 5 to 10 minutes. Rerun the third command below $PfEndpoint one.

    Start-MigrationBatch PublicFolderMigration   (if the batch has started from above script, it will just say the same)

    The migration process will synchronize the data from the source (on-premises) environment once every 24 hours.

    Get-PublicFolderMailboxMigrationRequest

    Get-PublicFolderMailboxMigrationRequestStatistics -identity publicfoldermigration

    Get-MigrationBatch

    Now Lock down the public folders on the Exchange on-premises server (public folder downtime required):

    Now users will no longer be able to access On-Prem Public Folders and will lock them till final sync. Any message sent to public folders will be queued and remain undelivered until migration completes.

    Get-MigrationBatch |?{$_.MigrationType -like "*PublicFolder*"} | ft *last*sync*

    Get-PublicFolderMailboxMigrationRequest | Get-PublicFolderMailboxMigrationRequestStatistics |ft targetmailbox,*last*sync

    Once final confirmation of migration requests successfully synced, run to lock Public folders for finalization:

    Set-OrganizationConfig -PublicFolderMailboxesLockedForNewConnections $true

    Public folder mailboxes will pick up the PublicFolderMailboxesLockedForNewConnections flag

    AT OnPrem EMS, check public folders are locked or not:

    Get-PublicFolder \

    If locked, output:

    Couldn't find the public folder mailbox. + CategoryInfo : NotSpecified: (:) [Get-PublicFolder], ObjectNotFoundException

    Step 7: Finalize the public folder migration (public folder downtime required)

    No Mailbox move should be running. If there are in Progress or in Completed State, remove them:

    Check any new mail-enabled public folders are synchronized with Exchange Online:

    At On-Prem:
    .\Sync-ModernMailPublicFolders.ps1 -Credential (Get-Credential) -CsvSummaryFile:sync_summary.csv

    Complete the public folder migration. After completing batch, no data will sync to cloud:

    Complete-MigrationBatch PublicFolderMigration

    Exchange will perform a final sync b/w On-prem and ExO. During this period, the status of the migration batch will change from Synced to Completing, and then finally to Completed.
    If the final synchronization is successful, the public folders in Exchange Online will be unlocked

    Step 8: Test and unlock public folders in Exchange Online
    Check the Hierarchy:

    Create Test User Mailboxes, give permission on the migrated mailbox, check the heirarcy, content etc.

    Set-Mailbox -Identity <test user> -DefaultPublicFolderMailbox <public folder mailbox identity>

    Unlock your public folders in Exchange Online:
    Set-OrganizationConfig -RemotePublicFolderMailboxes $Null -PublicFoldersEnabled Local


    Step 9: Finalize the migration on-premises.

    Take a backup of the emails in the queue that were sent to your mail-enabled public folders: (Optional if large organization)

    $Server=Get-TransportService;ForEach ($t in $server) {Get-Message -Server $t -ResultSize Unlimited| ?{$_.Recipients -like "*PF.InTransit*"} | ForEach-Object {Suspend-Message $_.Identity -Confirm:$False; $Temp="C:\ExportFolder\"+$_.InternetMessageID+".eml"; $Temp=$Temp.Replace("<","_"); $Temp=$Temp.Replace(">","_"); Export-Message $_.Identity | AssembleMessage -Path $Temp;Resume-message $_.Identity -Confirm:$false}}

    Make sure all emails to mail-enabled public folders are correctly routed to Exchange Online. Stamp mail-enabled public folders with an ExternalEmailAddress that points them to their Exchange Online counterparts:

    .\SetMailPublicFolderExternalAddress.ps1 -ExecutionSummaryFile:mepf_summary.csv

    Run to indicate that public folder migration is complete:
    Set-OrganizationConfig -PublicFolderMailboxesMigrationComplete:$true -PublicFoldersEnabled Remote

    Verify everything is intact:

    In Cloud PowerShell:

    Snapshot of the new folder structure:
    Get-PublicFolder -Recurse -ResultSize Unlimited | Export-CliXML Cloud_PFStructure.xml

    Snapshot of the public folder statistics, including item count, size, and owner:
    Get-PublicFolder -Recurse -ResultSize Unlimited | Get-PublicFolderStatistics | Export-CliXML Cloud_PFStatistics.xml

    Snapshot of the permissions:
    Get-PublicFolder -Recurse -ResultSize Unlimited | Get-PublicFolderClientPermission | Select-Object Identity,User,AccessRights |

    Export-CliXML Cloud_PFPerms.xml

    Snapshot of the mail-enabled public folders:
    Get-MailPublicFolder -ResultSize Unlimited | Export-CliXML Cloud_MEPF.xml

    Permissions for the root public folder and the EFORMS REGISTRY folder will not be migrated to Exchange Online and have to be applied manually:
    Add-PublicFolderClientPermission "\" -User <user> -AccessRights <access rights>
    Add-PublicFolderClientPermission "\NON_IPM_SUBTREE\EFORMS REGISTRY" -User <user> -AccessRights <access rights>

    Send As and Send on Behalf permissions don't get migrated to Exchange Online. Add them manually:

    AT On-Prem, check:

    Get-MailPublicFolder | Get-ADPermission | ?{$_.ExtendedRights -like "*Send-As*"}

    Get-MailPublicFolder | ?{$_.GrantSendOnBehalfTo -ne "$null"} | Format-Table name,GrantSendOnBehalfTo


    In Cloud PowerShell:

    Add Send As permission to a mail-enabled public folder in Exchange Online:

    Add-RecipientPermission -Identity <mail-enabled public folder primary SMTP address> -Trustee <name of user to be assigned permission> -AccessRights SendAs

    Add-RecipientPermission -Identity send1 -Trustee Exo1 -AccessRights SendAs  (Example)

    Set-MailPublicFolder -Identity <name of public folder> -GrantSendOnBehalfTo <user or comma-separated list of users>

    Set-MailPublicFolder send2 -GrantSendOnBehalfTo exo1,exo2  (Example)

    Exchange Online does not support more than 10,000 subfolders. Check:

    (Get-PublicFolder -GetChildren "\NON_IPM_SUBTREE\DUMPSTER_ROOT").Count

    Migration jobs are not making progress or are stalled:
    Set-MigrationEndpoint <PublicFolderEndpoint> -MaxConcurrentMigrations 30 -MaxConcurrentIncrementalSyncs 20 -SkipVerification

    Error:
    Error: Dumpster of the Dumpster folder.
    Stop and then start the batch again.

    PST Import Method:

    1) Use the Scripts.

    2) Generate the .csv file from step 3. It helps in calculating the correct number of public folder mailboxes in Exchange Online.

    3) Create the Public Folder mailboxes that you'll need based on the mapping file manully in EXchange Online.

    4) Create Public Folder using New-PublicFolder.

    5) Export and import the PST files using Outlook.

    6) Assign Permissions.



























    Migrate Public Folders to o365:

    The migration process can be broken down into the following steps:

    1. Download the Migration Scripts
    2. Prepare your local server
    3. Prepare Exchange Online
    4. Create Migration files
    5. Create public folder mailboxes and single public folder and assign the root permission of a mailbox
    6. Start the migration
    7. Lock access to the old public folders
    8. Finish the Migration (Switchover to Exchange Online)
    9. Test
    10. Complete the Migration

    To check concurrent migrations:
    Get-MigrationConfig

    By Default, PF assigns .onmicrosoft.com email address.

    To change, connect Powershell to O365:

    Set-MailPublicFolder -Identity "\PF1" -EmailAddressPolicyEnabled $False

    Get-MailPublicFolder | fl

    Set-MailPublicFolder -Identity pf1 -PrimarySmtpAddress pf1@akginfotech.com

    To check Full Access Rights on Public Folder:

    Get-PublicFolderClientPermission -Identity "\PF1"

    To Add Permissions to access the Public Folder:
    Add-PublicFolderClientPermission -Identity "\PF1" -User Ajey -AccessRights Owner

    To Remove Permissions to access the Public Folder:
    Remove-PublicFolderClientPermission -Identity "\PF1" -User Ajey




    Error:

    User status
    Data migrated:
    Migration rate:
    Last successful sync date:
    Error: MigrationTransientException: The call to ‎'net.tcp://pn1pr0101mb1983.indprd01.prod.outlook.com/Microsoft.Exchange.MailboxReplicationService PN1PR0101MB1983.INDPRD01.PROD.OUTLOOK.COM ‎(15.20.3174.25 ServerCaps:07FFFFFF, ProxyCaps:07FFFFFFFFC7FD6DFDBF5FFFFFCB07EFFF, MailboxCaps:, legacyCaps:07FFFFFF)‎‎' timed out. Error details: This request operation sent to net.tcp://pn1pr0101mb1983.indprd01.prod.outlook.com/Microsoft.Exchange.MailboxReplicationService did not receive a reply within the configured timeout ‎(00:01:00)‎. The time allotted to this operation may have been a portion of a longer timeout. This may be because the service is still processing the operation or because the service was unable to send a reply message. Please consider increasing the operation timeout ‎(by casting the channel/proxy to IContextChannel and setting the OperationTimeout property)‎ and ensure that the service is able to connect to the client. --> The call to ‎'net.tcp://pn1pr0101mb1983.indprd01.prod.outlook.com/Microsoft.Exchange.MailboxReplicationService PN1PR0101MB1983.INDPRD01.PROD.OUTLOOK.COM ‎(15.20.3174.25 ServerCaps:07FFFFFF, ProxyCaps:07FFFFFFFFC7FD6DFDBF5FFFFFCB07EFFF, MailboxCaps:, legacyCaps:07FFFFFF)‎‎' timed out. Error details: This request operation sent to net.tcp://pn1pr0101mb1983.indprd01.prod.outlook.com/Microsoft.Exchange.MailboxReplicationService did not receive a reply within the configured timeout ‎(00:01:00)‎. The time allotted to this operation may have been a portion of a longer timeout. This may be because the service is still processing the operation or because the service was unable to send a reply message. Please consider increasing the operation timeout ‎(by casting the channel/proxy to IContextChannel and setting the OperationTimeout property)‎ and ensure that the service is able to connect to the client. --> This request operation sent to net.tcp://pn1pr0101mb1983.indprd01.prod.outlook.com/Microsoft.Exchange.MailboxReplicationService did not receive a reply within the configured timeout ‎(00:01:00)‎. The time allotted to this operation may have been a portion of a longer timeout. This may be because the service is still processing the operation or because the service was unable to send a reply message. Please consider increasing the operation timeout ‎(by casting the channel/proxy to IContextChannel and setting the OperationTimeout property)‎ and ensure that the service is able to connect to the client.
    Report: Mailbox2Download the report for this user


Saturday, July 18, 2020

Decom 2010


Uninstall 2010:

After migration, none of the migrated user mailbox would occupy space in active databases, we can delete the databases. Just migrate Discovery, System Mailboxes (3 in 2010 and 5 in 2013 & 2016).

Move-ActiveMailboxDatabase DB3 -ActivateOnServer MBX4

Move-ActiveMailboxDatabase -Server MBX1




Get-User | Disable-Mailbox

Get-Mailbox -Arbitration | Disable-Mailbox -Arbitration -DisableLastArbitrationMailboxAllowed

Disable-Mailbox “SystemMailbox{bb558c35-97f1-4cb9-8ff7-d53741dc928c}” -Arbitration -DisableLastArbitrationMailboxAllowed           (to disable particular System mailbox if missing or corrupted)

Get-Mailbox -Monitoring | ?{$_.DisplayName -like "*-exch2-*"} | ft name,displayname,servername,database

Get-Mailbox -Monitoring | ?{$_.DisplayName -like "*-exch2-*"} | Disable-Mailbox

Get-Mailbox -Monitoring | Disable-Mailbox

Get-Mailbox | Get-MailboxStatistics | Where {$_.DisconnectReason -eq “Disabled” } | |foreach {Remove-StoreMailbox -Database $_.database -Identity $_.mailboxguid -MailboxState Disabled}

Get-Mailbox | Get-MailboxStatistics | where {$_.DisconnectReason -eq “SoftDeleted”} |foreach {Remove-StoreMailbox -Database $_.database -Identity $_.mailboxguid -MailboxState SoftDeleted}

Get-mailboxdatabase -server De-exch | Remove-MailboxDatabase

Get-PublicFolder -Server "Exolab" "\" -Recurse -ResultSize:Unlimited | Remove-PublicFolder -Server "OPI-MailDB13" -Recurse -ErrorAction:SilentlyContinue

Get-MailboxDatabase | Remove-MailboxDatabase

Get-PartnerApplication| Remove-PartnerApplication

Get-Mailbox
Get-Mailbox -Arbitration
Get-Mailbox -Monitoring

Setup /Mode:Uninstall /iacceptexchangeserverlicenseterms

this computer is responsible for expanding the membership of XX distribution group. these must be reassigned to another server before setup can continue



Blueprint