Archive
[EXO] Various ways to grab all SMTP address from mailbox
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
$Mailbox = @{ ResultSize = “Unlimited” } $Filter = @{ FilterScript = {$_.PrefixString -ceq “smtp”} } $Select = @{ Property = @{Name=”First Name”;Expression={$_.DisplayName.Split(“,”)[1].Trim()}}, @{Name=”Last Name”;Expression={$_.DisplayName.Split(“,”)[0].Trim()}}, “DisplayName”, “ServerName”, “PrimarySmtpAddress”, @{Name=”EmailAddresses”;Expression={$_.EmailAddresses | Where-Object @Filter}} } Get-Mailbox @Mailbox | Select-Object @Select #Split all SMTP using comma (Get-Mailbox -ResultSize Unlimited |Select-Object DisplayName,ServerName,PrimarySmtpAddress, @{Name=“EmailAddresses”;Expression={$_.EmailAddresses |Where-Object {$_.PrefixString -ceq “smtp”} | ForEach-Object {$_.SmtpAddress}}}) |Select-Object DisplayName,ServerName,PrimarySmtpAddress, @{Name=“EmailAddresses”;Expression={$_.EmailAddresses.Split() -join(“,”)}} |Export-Csv C:\scripts\temp\addresses2.csv -NoTypeInformation Get-Mailbox -ResultSize Unlimited |Select Name, PrimarySMTPAddress, @{Name=’EmailAddresses’;Expression={[string]::join(“;”, ($_.EmailAddresses -cmatch ‘smtp’))}} Get-Mailbox -ResultSize Unlimited | Select-Object DisplayName,PrimarySmtpAddress, @{Name="EmailAddresses";Expression={$_.EmailAddresses | Where-Object {$_.PrefixString -ceq "smtp"} | ForEach-Object {$_.SmtpAddress}}} | Sort-Object DisplayName | Export-CSV "\\sf3\user1\shared\share\e\all_SMTP_Addresses.csv" -NoTypeInformation |
[EXO] Concert IMCEAEX string to X500
Simple script to convert IMCEAEX to X500 Address.
1 2 3 4 5 6 7 8 9 10 11 |
$IMCEAEX = Read-Host -Prompt "Enter IMCEAEX string to convert to X500" $IMCEAEX = $IMCEAEX -replace '_', '/' $IMCEAEX = $IMCEAEX -replace '\+20', ' ' $IMCEAEX = $IMCEAEX -replace '\+28', '(' $IMCEAEX = $IMCEAEX -replace '\+29', ')' $IMCEAEX = $IMCEAEX -replace '\+2E', '.' $IMCEAEX = $IMCEAEX -replace 'IMCEAEX-', '' $IMCEAEXNew = $IMCEAEX -split ('@') $IMCEAEX = $IMCEAEXNew[0] $IMCEAEX = 'X500:' + $IMCEAEX write-host $IMCEAEX |
[EXO] Inbox Rule Issues Post Migration
In some instances, users with client side rules may break as they do not get touched in the migration. For any client rules that reference a specific sender/folder/etc they will normally use X500/LegacyDN to identify conditions and will stop working.
- There is no set limit for the amount of Inbox rules a user can have.
- The amount of rules is dictated more ever by the rule size limit and limited to 256 KB total for all rules.
Each rule you create will take up space. The actual amount of space a rule uses depends on several factors, such as how long the name is and how many conditions you’ve applied. When you reach the 256 KB limit, you’ll be warned that you can’t create any more rules or that you can’t update a rule. You can’t increase the amount of space that’s allocated to store Inbox rules in Exchange Online, but you can decrease it to suit your business needs.
- There is no way to calculate the size for all rules (avg around 3kb for a basic rule)
Options:
- Recreate their rules entirely. Allows user to reorganize and customize their inboxes to their preference.
- Audit, review, and consolidate rules by exporting using below cmdlet:
1 |
Get-Mailbox <user> | Get-InboxRule| Select MailboxOwnerID,Name,@{n='Description';e={$_.Description -join ','}},Enabled,RedirectTo, MoveToFolder,ForwardTo| Export-Csv C:\temp\Output.csv -NoTypeInformation |
[EXO] Identifying Validation Errors
$errors = (Get-MsolContact –ObjectID <Object_ID>).Errors
$errors | foreach-object {“nService: " + $_.ErrorDetail.Name.split("/")[0]; "Error Message: "+ $_.ErrorDetail.ObjectErrors.ErrorRecord.ErrorDescription}
$errors = (Get-MsolGroup –ObjectID <Object_ID>).Errors
$errors | foreach-object {"nService: ” + $_.ErrorDetail.Name.split(“/”)[0]; “Error Message: “+ $_.ErrorDetail.ObjectErrors.ErrorRecord.ErrorDescription}
$errors = (Get-MsolUser -UserPrincipalName “<User_ID>”).Errors
$errors | foreach-object {“`nService: ” + $_.ErrorDetail.Name.split(“/”)[0]; “Error Message: ” + $_.ErrorDetail.ObjectErrors.ErrorRecord.ErrorDescription}
Get-MsolUser -HasErrorsOnly -All | ft DisplayName,UserPrincipalName,@{Name=”Error”;Expression={($_.errors[0].ErrorDetail.objecterrors.errorrecord.ErrorDescription)}} -AutoSize -wrap
https://support.microsoft.com/en-au/help/2741233/you-see-validation-errors-for-users-in-the-office-365-portal-or-in-the
1 2 3 4 5 6 7 8 9 |
$output = @() $usererr = Get-MsolUser -HasErrorsOnly Foreach ($user in $usererr) { $output += New-Object psobject -Property @{ user = $user.UserPrincipalName errordetail = $user.Errors.ErrorDetail.Name.split("/")[0] details = $user.Errors.ErrorDetail.ObjectErrors.ErrorRecord.ErrorDescription} } $output | export-csv c:\temp\outpute.csv -NoTypeInformation |
1 2 3 4 5 6 7 8 |
function Get-MSOLUserWithValidationError { $usererr = Get-MsolUser -HasErrorsOnly Foreach ($user in $usererr) { Write-output $user.UserPrincipalName; "Service: "+ $user.Errors.ErrorDetail.Name.split("/")[0]; "Error Message: "+ $user.Errors.ErrorDetail.ObjectErrors.ErrorRecord.ErrorDescription +"`n" } } |
[EX2010] Identifying Cmd-let associated with Role, and who has it.
$Perms = Get-ManagementRole -Cmdlet remove-remotemailbox
$Perms | Foreach {Get-ManagementRoleAssignment -Role $_.Name -Delegating $false | Format-Table -Auto Role,RoleAssigneeType,RoleAssigneeName}
Role RoleAssigneeType RoleAssigneeName
—- —————- —————-
Mail Recipient Creation RoleGroup Recipient Management
Mail Recipient Creation RoleGroup Organization Management
Get-ManagementRoleAssignment -Role “Mail Recipient Creation”
get-rolegroupmember “organization management”
[EXO] The client and server cannot communicate, because they do not possess a common algorithm
- Windows Server 2008 can’t do beyond TLS 1.0.
- Newer versions can, but don’t have TLS 1.1 or 1.2 turned on by default.
- Best pratice to disable 1.0, 1.1 – mostly depreciated and not supported
Check supported protocols:
https://www.ssllabs.com/ssltest/index.html
Turn off TLS 1.0.1.1 and SSL
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 |
Windows Registry Editor Version 5.00 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Client] "DisabledByDefault"=dword:00000001 "Enabled"=dword:00000000 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 2.0\Server] "DisabledByDefault"=dword:00000001 "Enabled"=dword:00000000 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Client] "DisabledByDefault"=dword:00000001 "Enabled"=dword:00000000 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\SSL 3.0\Server] "DisabledByDefault"=dword:00000001 "Enabled"=dword:00000000 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Client] "DisabledByDefault"=dword:00000001 "Enabled"=dword:00000000 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.0\Server] "DisabledByDefault"=dword:00000001 "Enabled"=dword:00000000 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Client] "DisabledByDefault"=dword:00000001 "Enabled"=dword:00000000 [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\SecurityProviders\SCHANNEL\Protocols\TLS 1.1\Server] "DisabledByDefault"=dword:00000001 "Enabled"=dword:00000000 |
Enabling TLS 1.2 Use
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 REG_DWORD value of: SchUseStrongCrypto with a value of 1 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v4.0.30319 REG_DWORD value of: SystemDefaultTLSVersions with a value of 1 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\.NETFramework\v3.0 REG_DWORD value of: SchUseStrongCrypto with a value of 1 HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.5.23026 REG_DWORD value of: SchUseStrongCrypto with a value of 1 HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.5.1 REG_DWORD value of: SchUseStrongCrypto with a value of 1 HKEY_LOCAL_MACHINE\SOFTWARE\WOW6432Node\Microsoft\.NETFramework\v4.0.30319 REG_DWORD value of: SchUseStrongCrypto with a value of 1 |
[EXO][EX2010] Removing dual mailboxes
Ensure you have a user mailbox backup prior to starting the following process as there is potential risk of data loss. Options are to have a third party solution to perform a mailbox backup or export to PST (see new-mailboxexport cmdlet).
- Capture relevant information from on-premise exchange and exchange online.
- Grab the mailbox information (primary and archive) to help determine which mailbox is active and which one to disable (remove)
- get-mailboxstatistics <user>
- get-mailboxstatistics <user> -archive
- get-exomailboxstatistics (exo ps v2)
- Grab the x500 address (legacydn)
- Grab GUID information
- get-recipient <user> | fl *guid*
- Grab the mailbox information (primary and archive) to help determine which mailbox is active and which one to disable (remove)
- Determine which mailbox is active and which one to disable (remove) –
- Removing the on-premise mailbox will require you to delete and recreate the remote mailbox – an object on-premise will need to represent the object on exchange for remote routing.
- Disable the on-premise mailbox – do not remove, or you will remove the AD user object:
- disable-mailbox <user>
- If litigation hold is enabled, you will need to disable the hold, then disable the mailbox.
- Recreate the remote mailbox on-premise
- Enable-RemoteMailbox -Identity <user> -RemoteRoutingAddress “<user>@<tenant>.mail.onmicrosoft.com”
- Associate the GUID and x500 for sync and mail routing:
- Set-RemoteMailbox -exchangeguid <exchange guid> -archiveguid <archive guid> -EmailAddresses X500: <x500>
- Disable the on-premise mailbox – do not remove, or you will remove the AD user object:
- Removing the cloud mailbox
- Remove the user from Office 365 and resync with AD sync.
- remove-msoluser <user>
- remove-msoluser <user> -removefromrecyclebin -force
- Clearing the previous mailbox information
- Set-User <user> -PermanentlyClearPreviousMailboxInfo
- Remove the user from Office 365 and resync with AD sync.
- Removing the on-premise mailbox will require you to delete and recreate the remote mailbox – an object on-premise will need to represent the object on exchange for remote routing.
Accidentally deleted a on-premise mailbox?
- Identify where the disconnected or soft deleted mailbox is.
- $dbs = Get-MailboxDatabase $dbs | foreach {Get-MailboxStatistics -Database $_.DistinguishedName} | where {$_.DisconnectReason -eq “Disabled”} | Format-Table DisplayName,Database,DisconnectDate
- Reconnect the mailbox
- Connect-Mailbox -Identity “<identity>” -Database <database> -User “<user>” -Alias <alias>
Accidentally deleted the on-premise user, but need to restore the data to cloud mailbox?
- Create a new temporary mailbox on-premise to restore the data to.
- Identify where the disconnected or soft deleted mailbox is.
- $dbs = Get-MailboxDatabase $dbs | foreach {Get-MailboxStatistics -Database $_.DistinguishedName} | where {$_.DisconnectReason -eq “Disabled”} | Format-Table DisplayName,Database,DisconnectDate,*guid*
- Restore the primary and archive data to the temporary mailbox
- New-MailboxRestoreRequest -SourceStoreMailbox <mailbox guid> -SourceDatabase <database> -TargetMailbox <mailbox> -AllowLegacyDNMismatch
- New-MailboxRestoreRequest -SourceStoreMailbox<mailbox guid> -SourceDatabase <database> -TargetMailbox <mailbox> -TargetIsArchive
- Export the data to PST (requires rights)
- New–ManagementRoleAssignment –Role “Mailbox Import Export” –User Administrator
- New-MailboxExportRequest -Mailbox <mailbox> -FilePath <path>
- New-MailboxExportRequest -Mailbox <mailbox> -FilePath <path> -isarchive
- Ensure the Exchange Trust Subsystem group has read/write permissions to path
- Check status:
- Get–MailboxExportRequest | where {$_.status –eq “Completed”}
- Remove job:
- Get-MailboxRestoreRequest -Status Completed | Remove-MailboxRestoreRequest
- Get-MailboxRestoreRequest -Status Failed | Remove-MailboxRestoreRequest
- Import to mailbox:
- In Outlook with Exchange Online Mailbox, you can import directly – ensure you do not copy duplicates.
[EX2010][EXO] Forwarding Address Export and Import
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 |
#Load Exchange 2010 Module Add-PSSnapin Microsoft.Exchange.Management.Powershell.E2010 -ErrorAction SilentlyContinue #Setup Variables $Filename = "C:\temp\tasks\fowarding_address\export.csv" $header = "UPN,ForwardingSmtpAddress,DeliverToMailboxAndForward" $header | Out-File $Filename #Grab Data $Users = Get-Mailbox -ResultSize Unlimited -Filter { (ForwardingAddress -ne $null) -or (ForwardingSmtpAddress -ne $null) } ForEach ($User in $Users) { if ($user.ForwardingSmtpAddress -ne $null) { $forwardingSmtpAddress = $user.ForwardingSmtpAddress $DeliverToMailboxAndForward = $User.DeliverToMailboxAndForward.ToString() $logstring = "$($user.PrimarySmtpAddress),$($forwardingSmtpAddress),$($DeliverToMailboxAndForward)" $logstring | Out-File $Filename -Append } else { if ($user.ForwardingAddress -ne $null) { $forwardingContact = $user.ForwardingAddress $forwardingContactAddress = (Get-Recipient $forwardingContact).PrimarySmtpAddress $DeliverToMailboxAndForward = $User.DeliverToMailboxAndForward.ToString() $logString = "$($user.PrimarySmtpAddress),$($forwardingContactAddress),$($DeliverToMailboxAndForward)" $logString | Out-File $Filename -Append } } } #Remove Exchange 2010 Module Remove-PSSnapin Microsoft.Exchange.Management.Powershell.E2010 #Connect to Exchange Online $username = "<user name>" $targetdir = (dir $env:LOCALAPPDATA”\Apps\2.0\” -Include CreateExoPSSession.ps1,Microsoft.Exchange.Management.ExoPowershellModule.dll -Recurse | Group Directory | ? {$_.Count -eq 2}).Values | sort LastWriteTime -Descending | select -First 1 | select -ExpandProperty FullName import-Module $targetdir\CreateExoPSSession.ps1 $PasswordFile = "Password.txt" $KeyFile = "AES.key" $key = Get-Content $KeyFile $MyCredential = New-Object -TypeName System.Management.Automation.PSCredential -ArgumentList $username, (Get-Content $PasswordFile | ConvertTo-SecureString -Key $key) connect-exopssession -credential $MyCredential #Reapply forwarding to migrated EXO mailboxes $Users = Import-Csv $Filename ForEach ($user in $users) { $DeliverToMailboxAndForward = [System.Convert]::ToBoolean($User.DeliverToMailboxAndForward) Set-Mailbox -Identity $($user.UPN) -DeliverToMailboxAndForward $DeliverTomailboxAndForward -ForwardingSmtpAddress $($user.ForwardingSmtpAddress) -whatif } #Kill Session and Remove Module Get-PSSession | Remove-PSSession Get-Module | Remove-Module |
Single mailbox export to PST file
Add member of a role group which has the Mailbox Import Export role
1 |
New-ManagementRoleAssignment -Role "Mailbox Import Export" -User "<user name or alias>" |
Export primary mailbox:
1 |
New-MailboxExportRequest -Mailbox <user> -FilePath \\<server FQDN>\<shared folder name>\<PST name>.pst |
Export archive mailbox:
1 |
New-MailboxExportRequest -Mailbox <user> -FilePath \\<server FQDN>\<shared folder name>\<PST name>.pst -isarchive |
More details
[PS][EX2010] E-mails Recieved per day of Month Report
.Synopsis
E-mail Counting Script v1 by ELAU 10/10/19
– Script counts emails received for each day of the current month
.DESCRIPTION
– Script pulls days of the month and counts number of emails received for each day of the current month or days specified into a HTML report.
– Script allows option to e-mail report
.EXAMPLE
– Run count.ps1 without parameters will prompt for required options
.EXAMPLE
– Specify days to go back without sending email report
count.ps1 -mailbox <mailbox to search> -day <days to search back from today>
.EXAMPLE
– Specify days to go back with sending email report
count.ps1 -mailbox <mailbox to search> -day <days to search back from today> -emailto <report to send to>
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 |
<# .Synopsis E-mail Counting Script v1 by EPIC 10/10/19 - Script counts emails received for each day of the current month .DESCRIPTION - Script pulls days of the month and counts number of emails received for each day of the current month or days specified into a HTML report. - Script allows option to e-mail report .EXAMPLE - Run count.ps1 without parameters will prompt for required options .EXAMPLE - Specify days to go back count.ps1 -mailbox <mailbox to search> -day <days to search back from today> .EXAMPLE - Specify days to go back and email report count.ps1 -mailbox <mailbox to search> -day <days to search back from today> -emailto <report to send to> #> # Parameters Param( [Parameter(position=1)] [string]$mailbox, [Parameter(position=2)] [string]$day, [Parameter(position=3)] [string]$emailto ) # Setup Variables $smtpServer = "smtpserver.com" $emailFrom = "from@address.com" $subject = "Recieved e-mails per day" $Path = "c:\temp\test.html" [INT]$year = (Get-date).ToString("yy") [INT]$month = (Get-date).ToString("MM") $monthheader = (Get-date).ToString("MMMM,yyyy") # Prompts for input if no parmeters provided if (!$day) { [INT]$day = (Get-date).ToString("dd") [INT]$days = [datetime]::DaysInMonth($year,$month) } if (!$mailbox) { $mailbox = Read-Host -Prompt "Mailbox to Search (user@firstrepublic.com)" } If ($emailto) { $email = "sure" } elseif (!$emailto) { $email = Read-Host -Prompt "E-mail Report : Yes or No" while("yes","no" -notcontains $email) { $email = Read-Host -Prompt "E-mail Report : Yes or No" } } if ($email -eq "yes") { $emailTo = Read-Host -Prompt "E-mail to send Report (user@firstrepublic.com)" } #HTML HEADER $head = @" <title>E-mail Report</title> <style type="text/css"> table, td { border: 1px solid black; border-collapse:collapse;} tr:nth-child(odd) { background-color:lightgrey; } th { color:black; text-align:left; border: 1px solid black; font:normal 16px verdana, arial, helvetica, sans-serif; font-weight:bold; background-color: #6495ED; padding-left:6px; padding-right:6px; } </style> "@ # HTML TABLE HEADER $body += @" <table> <tr><th colspan="2">$monthheader - $mailbox</th></tr> <tr> <td>Date</td> <td>E-mails Recieved</td> </tr> "@ # Performs the search and adds HTML ROWs $i=1 Do { $start = ((get-date -hour 0 -Minute 0 -Second 0).adddays(-($day-$i+1))) $shortstart = ((get-date).adddays(-($day-$i+1)).ToString("MM-dd-yyyy")) $end = ((get-date -hour 0 -Minute 0 -Second 0).adddays(-($day-($i)))) $emails = Get-TransportServer | Get-MessageTrackingLog -ResultSize Unlimited -Start $start -End $end -EventId "Receive" -Recipient $mailbox $count = ($emails | Measure-Object).count $body += @" <tr> <td>$shortstart</td> <td>$count</td> </tr> "@ $i++ } While ($i -le $day) # HTML FOOTER $body += @" </table> "@ # Add HTML together and ouputs report $HTML = $head + $body $HTML | Out-File $Path # Sends e-mail if email is requested if ($email -eq "yes" -or $email -eq "sure") { Send-MailMessage -From $emailFrom -To $emailTo -Subject $Subject -Body $HTML -BodyAsHtml -SmtpServer $smtpServer -EA Stop 2>> $errorlog } |