My colleague made me happy when he described an easy procedure how to import Exchange cmdlets into PowerShell ISE so let me share it here.
Author Archives: Filip
Exchange Hybrid – 1 account and 2 mailboxes
I have just noticed an issue with Exchange 2010 based hybrid and AADSync. On-prem AD account has assigned on-prem mailbox as well as remote mailbox (Exchange Online – O365). Yes, it seems to be possible, but only technically, because mailbox functionality is broken from end-user point of view at this point.
According my investigation it was caused by wrong procedure by mailbox creation. SD created remote mailbox , ran AADSync, disabled remote mailbox, forgot to run AADSync and created on-prem mailbox immediately.
So what to do then? We have to ensure only one mailbox either in Exchange Online or Exchange On-prem so based on our needs.
I decided to keep on-prem mailbox, because it was used by affected end-user.
Well, I exported all mailbox data from remote mailbox to PST file. There are a few possibilities how to do it e.g. via Outlook or eDiscovery search. I wanted to expert all available mailbox data including dumpster so I preferred eDiscovery approach (be aware to have mailbox still enabled during that time).
When I had the PST I quickly removed remote mailbox and account from Azure AD Recycle Bin. After that I imported the PST into on-prem mailbox and ran AADsync to ensure mail user object in O365.
NirSoft utilities (portable)
Hi, I had to investigate issue at Citrix side without possibility to install troubleshooting tools like Fiddler or Wireshark and I had success to find NirSoft utilities so collection of small and freeware utilities in portable form, hm I would say really nice thing…
PowerShell Tip: Get string array from your list
Very easy procedure how to get string array from listed items from somewhere (e.g. txt file).
Well, run PS, declare a variable like $something=” paste your lines then close it by ” and convert it into the array $something=something.split(“`n”)
Of course there are a lot of other possibilities how to declare the same array e.g. $array = @(“10.10.10.26″,”10.10.10.35″,”10.10.10.44”), but anyway the paste option is useful thing ;).
Remote Migration And (500) Internal Server Error
Experience with Exchange 2010 based hybrid and the following remote migration failure (move requests/test cmdlet):
- Microsoft.Exchange.Migration.MigrationServerConnectionFailedException: The connection to the serve
r ‘mail.ficility.net’ could not be completed. —> Microsoft.Exchange.MailboxReplicationService.Remote
TransientException: The Mailbox Replication Service could not connect to the remote server because
the remote server encountered an internal error. - The remote server returned an error: (500) Internal Server Error.. –> The content type
text/html of the response message does not match the content type of the binding (application/soap
+xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is
implemented properly.
PS C:\> Test-MigrationServerAvailability -ExchangeRemoteMove -RemoteServer mail.ficility.net -Credentials $GetOnpremCred RunspaceId : 4da526a1-2d3a-4ec7-b484-c39e436c4bcc Result : Failed Message : The connection to the server 'mail.ficility.net' could not be completed. ConnectionSettings : SupportsCutover : False ErrorDetail : Microsoft.Exchange.Migration.MigrationServerConnectionFailedException: The connection to the serve r 'mail.ficility.net' could not be completed. ---> Microsoft.Exchange.MailboxReplicationService.Remote TransientException: The Mailbox Replication Service could not connect to the remote server because the remote server encountered an internal error. The call to 'https://mail.ficility.net/EWS/mrsproxy. svc' failed. Error details: The content type text/html of the response message does not match the content type of the binding (application/soap+xml; charset=utf-8). If using a custom encoder, be s ure that the IsContentTypeSupported method is implemented properly. The first 1024 bytes of the re sponse were: '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML dir=ltr><HEAD><TITLE>The page cannot be displayed</TITLE> <STYLE id=L_defaultr_1>A:link { FONT: 8pt/11pt verdana; COLOR: #ff0000 } A:visited { FONT: 8pt/11pt verdana; COLOR: #4e4e4e } </STYLE> <META content=NOINDEX name=ROBOTS> <META http-equiv=Content-Type content="text-html; charset=UTF-8"> <META content="MSHTML 5.50.4522.1800" name=GENERATOR></HEAD> <BODY bgColor=#ffffff> <TABLE cellSpacing=5 cellPadding=3 width=410> <TBODY> <TR> <TD id=L_defaultr_0 valign=middle align=left width=360> <H1 id=L_defaultr_2 style="FONT: 13pt/15pt verdana; COLOR: #000000"><ID id=L_defaultr_3><!-- Problem-->The page cannot be displayed </ID></H1></TD></TR> <TR> <TD width=400 colSpan=2><FONT id=L_defaultr_4 style="FONT: 8pt/11pt verdana; COLOR: #000000"><ID id=L_defaultr_5><B>Explanation: </B>There is a problem with the page you are trying to reach and it cannot be displayed.</ID></FONT></TD></ TR> <TR> '. --> The remote server returned an error: (500) Internal Server Error.. --> The content type text/html of the response message does not match the content type of the binding (application/soap +xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 1024 bytes of the response were: '<!DOCTYPE HTML PUBLIC "-//W3C// DTD HTML 4.0 Transitional//EN"> <HTML dir=ltr><HEAD><TITLE>The page cannot be displayed</TITLE> <STYLE id=L_defaultr_1>A:link { FONT: 8pt/11pt verdana; COLOR: #ff0000 } A:visited { FONT: 8pt/11pt verdana; COLOR: #4e4e4e } </STYLE> <META content=NOINDEX name=ROBOTS> <META http-equiv=Content-Type content="text-html; charset=UTF-8"> <META content="MSHTML 5.50.4522.1800" name=GENERATOR></HEAD> <BODY bgColor=#ffffff> <TABLE cellSpacing=5 cellPadding=3 width=410> <TBODY> <TR> <TD id=L_defaultr_0 valign=middle align=left width=360> <H1 id=L_defaultr_2 style="FONT: 13pt/15pt verdana; COLOR: #000000"><ID id=L_defaultr_3><!-- Problem-->The page cannot be displayed </ID></H1></TD></TR> <TR> <TD width=400 colSpan=2><FONT id=L_defaultr_4 style="FONT: 8pt/11pt verdana; COLOR: #000000"><ID id=L_defaultr_5><B>Explanation: </B>There is a problem with the page you are trying to reach and it cannot be displayed.</ID></FONT></TD></ TR> <TR> '. --> The remote server returned an error: (500) Internal Server Error. ---> Microsoft.Exchang e.MailboxReplicationService.RemoteTransientException: The call to 'https://mail.ficility.net/EWS/mrspr oxy.svc' failed. Error details: The content type text/html of the response message does not match the content type of the binding (application/soap+xml; charset=utf-8). If using a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 1024 bytes of th e response were: '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML dir=ltr><HEAD><TITLE>The page cannot be displayed</TITLE> <STYLE id=L_defaultr_1>A:link { FONT: 8pt/11pt verdana; COLOR: #ff0000 } A:visited { FONT: 8pt/11pt verdana; COLOR: #4e4e4e } </STYLE> <META content=NOINDEX name=ROBOTS> <META http-equiv=Content-Type content="text-html; charset=UTF-8"> <META content="MSHTML 5.50.4522.1800" name=GENERATOR></HEAD> <BODY bgColor=#ffffff> <TABLE cellSpacing=5 cellPadding=3 width=410> <TBODY> <TR> <TD id=L_defaultr_0 valign=middle align=left width=360> <H1 id=L_defaultr_2 style="FONT: 13pt/15pt verdana; COLOR: #000000"><ID id=L_defaultr_3><!-- Problem-->The page cannot be displayed </ID></H1></TD></TR> <TR> <TD width=400 colSpan=2><FONT id=L_defaultr_4 style="FONT: 8pt/11pt verdana; COLOR: #000000"><ID id=L_defaultr_5><B>Explanation: </B>There is a problem with the page you are trying to reach and it cannot be displayed.</ID></FONT></TD></ TR> <TR> '. --> The remote server returned an error: (500) Internal Server Error.. ---> Microsoft.Exchan ge.MailboxReplicationService.RemotePermanentException: The content type text/html of the response message does not match the content type of the binding (application/soap+xml; charset=utf-8). If u sing a custom encoder, be sure that the IsContentTypeSupported method is implemented properly. The first 1024 bytes of the response were: '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional/ /EN"> <HTML dir=ltr><HEAD><TITLE>The page cannot be displayed</TITLE> <STYLE id=L_defaultr_1>A:link { FONT: 8pt/11pt verdana; COLOR: #ff0000 } A:visited { FONT: 8pt/11pt verdana; COLOR: #4e4e4e } </STYLE> <META content=NOINDEX name=ROBOTS> <META http-equiv=Content-Type content="text-html; charset=UTF-8"> <META content="MSHTML 5.50.4522.1800" name=GENERATOR></HEAD> <BODY bgColor=#ffffff> <TABLE cellSpacing=5 cellPadding=3 width=410> <TBODY> <TR> <TD id=L_defaultr_0 valign=middle align=left width=360> <H1 id=L_defaultr_2 style="FONT: 13pt/15pt verdana; COLOR: #000000"><ID id=L_defaultr_3><!-- Problem-->The page cannot be displayed </ID></H1></TD></TR> <TR> <TD width=400 colSpan=2><FONT id=L_defaultr_4 style="FONT: 8pt/11pt verdana; COLOR: #000000"><ID id=L_defaultr_5><B>Explanation: </B>There is a problem with the page you are trying to reach and it cannot be displayed.</ID></FONT></TD></ TR> <TR> '. ---> Microsoft.Exchange.MailboxReplicationService.RemotePermanentException: The remote serve r returned an error: (500) Internal Server Error. --- End of inner exception stack trace --- --- End of inner exception stack trace --- --- End of inner exception stack trace --- at Microsoft.Exchange.MailboxReplicationService.MailboxReplicationServiceFault.<>c__DisplayClas s1.<ReconstructAndThrow>b__0() at Microsoft.Exchange.MailboxReplicationService.ExecutionContext.Execute(Action operation) at Microsoft.Exchange.MailboxReplicationService.MailboxReplicationServiceFault.ReconstructAndTh row(String serverName, VersionInformation serverVersion) at Microsoft.Exchange.MailboxReplicationService.WcfClientWithFaultHandling`2.<>c__DisplayClass1 .<CallService>b__0() at Microsoft.Exchange.Net.WcfClientBase`1.CallService(Action serviceCall, String context) at Microsoft.Exchange.Migration.MigrationExchangeProxyRpcClient.CanConnectToMrsProxy(Fqdn serve rName, Guid mbxGuid, NetworkCredential credentials, LocalizedException& error) --- End of inner exception stack trace --- at Microsoft.Exchange.Migration.DataAccessLayer.ExchangeRemoteMoveEndpoint.VerifyConnectivity() at Microsoft.Exchange.Management.Migration.TestMigrationServerAvailability.InternalProcessEndpo int(Boolean fromAutoDiscover) IsValid : True Identity : ObjectState : New
Reason:
Mail.ficility.net pointed to TMG with enabled custom web security filter.
TMG:
The filter disabled and then:
PS C:\> Test-MigrationServerAvailability -ExchangeRemoteMove -RemoteServer mail.ficility.net -Credentials $GetOnpremCred RunspaceId : 0e75133c-e53f-4dec-86cb-f87eb68bbf5c Result : Success Message : ConnectionSettings : <ExchangeConnectionSettings HasAdminPrivilege="True" HasAutodiscovery="False" HasMrsProxy="True" A utodiscoverUrl="" IncomingEmailAddress="" IncomingRPCProxyServer="mail.ficility.net" IncomingExchangeS erver="mail.ficility.net" IncomingNSPIServer="" IncomingDomain="europe" IncomingUserName="x98490" Encr yptedIncomingPassword="AAAAAQXEWAAEEC2a321JsEZNpm0sI75meOsGCWCGSAFlAwQCAQYJYIZIAWUDBAIBBglghkgBZQM EAQIEIH0n3HnypPK+ASyxgq4uJEXHwgGP7SSaO0gnsudrdL+wBBCEzLR+aCScgC21Yo5AUc3eIEBhgAiNca5RquKktuEWNqZZc 4oJHPOZXfz6RRUrYMZaWd5M/XPUawKeIdj10bPj/W0xvzt5R2hsHyYsj1wd4dLq" IncomingAuthentication="Basic" Se rverVersion="" TargetDomainName="" SourceMailboxLegDn="" PublicFolderDatabaseServerLegacyDN="" /> SupportsCutover : False ErrorDetail : IsValid : True Identity : ObjectState : New
The counter list and portability (read I/O operations)
An ExRAAP scanning detected this issue “The read I/O operations latency is greater than expected for an Exchange database” with an advice I started to monitor related performance counters according to post Analysing Exchange Server 2010 Jetstress BLG Files By Hand which contains also the following table:
Time to time I needed to check read I/O operations without a Data Collector Set, but I did not want to have the counter list/settings dependent on particular server (i.e. the server below hosts mailbox database MDB01 or MDB05 but not MDB02 and I want to have counters for all of them and I do not mind that some counter will not work).
Well, I saved the settings from the server into HTML file and modify its content for 18 databases.
- Changing value: <PARAM NAME=”CounterCount” VALUE=”18″/>
- Adding parameters for missing databases (be careful you have to always use unique PARAM NAME):
After that I could check the latency by pasting the same counter list on any server.
Exchange Cmdlet Statistics
You can use administrator audit logging in Microsoft Exchange Server to record actions taken by a user or administrator that make changes in your organization. By keeping a log of the changes, you can trace a change to the person who made it. You can also augment your change logs with detailed records of the change as it was implemented, use the records to comply with regulatory requirements and requests for discovery, and so on…. [source].
Yes, yes, the auditing is very useful. But I wanted to show you how could look a cmdlet statistic for a month:
PS C:\> Search-AdminAuditLog -StartDate $(get-date).addMonths(-1) -ResultSize 100000 -IsSuccess $true|select CmdletName| group CmdletName|sort count -Descending|ft count,name -a Count Name ----- ---- 12318 Set-MailboxFolderPermission 12307 Set-CalendarProcessing 8752 Set-MailboxAutoReplyConfiguration 5860 Set-Mailbox 678 Add-MailboxFolderPermission 645 Set-User 174 Add-DistributionGroupMember 163 Add-MailboxPermission 126 Remove-DistributionGroupMember 98 Remove-MailboxFolderPermission 89 Add-ADPermission 84 Remove-MailboxPermission 71 Enable-Mailbox 26 Set-InboxRule 24 Set-DistributionGroup 18 Clean-MailboxDatabase 16 Remove-ADPermission 16 Remove-Mailbox 16 Set-CASMailbox 8 New-MailContact 6 Remove-ActiveSyncDevice 6 Disable-Mailbox 5 Remove-MailContact 4 New-DistributionGroup 3 New-InboxRule 2 Remove-AcceptedDomain 2 Enable-DistributionGroup 2 Set-SendConnector 1 Update-Recipient 1 New-MoveRequest 1 Update-MovedMailbox 1 Add-PublicFolderClientPermission 1 New-SendConnector 1 Remove-DistributionGroup 1 New-MailboxSearch 1 Disable-InboxRule 1 Remove-InboxRule
Note: Cmdlets that begin with the verb Test, Get and Search aren’t logged by default.
Connect-Mailbox and AllowLagacyDNMismatch
I have solved a one case where we wanted to connect (Use the Connect-Mailbox cmdlet to connect a disconnected mailbox to an Active Directory user object.) an archive mailbox to a linked mailbox in Exchange 2013.
Error from EMS:
[PS] C:\>Connect-Mailbox -Identity "Personal Archive - Jan Novak" -Archive -User JanNovak2 -Database "EXDAG1-DB03" WARNING: An unexpected error has occurred and a Watson dump is being generated: Object reference not set to an instance of an object. Object reference not set to an instance of an object. + CategoryInfo : NotSpecified: (:) [Connect-Mailbox], NullReferenceException + FullyQualifiedErrorId : System.NullReferenceException,Microsoft.Exchange.Management.MapiTasks.ConnectMailbox + PSComputerName : server1.contoso.com
Error from GUI:
The LegacyDN "/o=CONTOSO/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=Jan Novak" of "cb67270a-ada2-472e-94cc-eb7140f3520f" is in use by the following user in Active Directory: "Pepa Novak (new)". The value for LegacyDN must be unique to each user.
Obviously, the LegacyDN attribute was not unique and defended to connect the mailbox.
[PS] C:\> # disconnected archive [PS] C:\>(Get-mailboxdatabase|Get-Mailboxstatistics|?{$_.DisconnectReason -ne $null -and $_.DisplayName -like "*Jan*"}).LegacyDN /o=CONTOSO /ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=Jan Novak [PS] C:\># linked mailbox [PS] C:\>(Get-mailbox JanNovak2).LegacyDN /o=contoso/ou=exchange administrative group (fydibohf23spdlt)/cn=recipients/cn=Jan Novak
How to connect mailbox in case this case? According to Technet and Connect-Mailbox (Exchange 2013) there is available a switch:
Well, we have available the switch for similar scenario (i.e. AllowLagacyDNMismatch), but it is reserved only for MS use. I do not know why is it so (let me know if you a clue), but it worked for me without problem:
[PS] C:\> Connect-Mailbox -Identity "Personal Archive - Jan Novak" -Archive -User JanNovak2 -Database "EXDAG1-DB03" -AllowLegacyDNMismatch [PS] C:\> Test-ArchiveConnectivity jan.novak@contoso.com RunspaceId : 7df20326-4fc0-4ca3-877f-5273aea0d5b7 Identity : jan.novak@contoso.com PrimaryMRMConfiguration : PrimaryLastProcessedTime : ArchiveDomain : ArchiveDatabase : EXDAG1-DB03 ArchiveMRMConfiguration : ArchiveLastProcessedTime : ComplianceConfiguration : ElcV2 ItemMRMProperties : Result : Successfully logged on to the users Archive mailbox. Error : IsValid : True ObjectState : New
Test-ExchangeServer2010.ps1
Let me publish my script which tests and gathers information directly from Exchange server 2010 (Windows 2008). It is my little helper in case of patching or troubleshooting. Basically it is nothing special, but let’s look at its help:
.DESCRIPTION Test-ExchangeServer2010.ps1 - filip.kasaj@tieto.com - v1.180714 This script performs test cmdlets and gathers information from Exchange Server 2010 (Windows Server 2008) into own txt log. It can be used only directly on the Exchanger server (the server role is chosen automatically). Only get and test cmdlets are used for this type of health check. Run-space: PowerShell 2.0 or Exchange Management Shell. Prerequisite: new-TestCasConnectivityUser.ps1 Tests and information: ---------------------- Always: - Get-WMIObject (Operating System, Volumes) - Get-ExchangeServer - GCM Exsetup - Test-ServiceHealth - Get-ExchangeCertificate - IIS Status - Test-PowerShellConnectivity - Test-FederationTrust - Server Services - Bad Application Events - Bad System Evenets - Top processes - CPU,MemorySize - Server Performance Mailbox role: - Get-MailboxDatabaseCopyStatus - Get-DatabaseAvailabilityGroup - Cluster /quorum - Cluster group /stat - Cluster /prop - Test-Mailflow - Test-MAPIConnectivity - Test-ReplicationHealth CAS role: - Test-OwaConnectivity - Test-ActiveSyncConnectivity - Test-WebServicesConnectivity - Test-OutlookWebServices - Test-OutlookWebServices - Test-OutlookConnectivity - Test-EcpConnectivity - Test-ImapConnectivity - Test-PopConnectivity HUB role: - Test-SmtpConnectivity - Get-Queue .EXAMPLE Test-ExchangeServer.ps1 # It performs test cmdlets and gathers information into txt log generated in C:\temp. .EXAMPLE Test-ExchangeServer.ps1 -ShowOutputLog # It performs test cmdlets and gathers information into txt log generated in C:\temp and opens the log in notepad at the end. .EXAMPLE Test-ExchangeServer.ps1 -OutputLogPath "D:\Report\ExchangeServerLog.txt" # It performs test cmdlets and gathers information into the specified log file. .EXAMPLE Test-ExchangeServer.ps1 -ShowOutputLog -OutputLogPath "D:\Report\ExchangeServerLog.txt" # It performs test cmdlets and gathers information into the specified log file and opens the log in notepad at the end.
How to use it?
Just copy the script to your Exchange server and go ahead:
How to compare logs (i.e. check the state before/after patching)?
For example via Total Commander:
Download: Test-ExchangeServer2010.ps1 – http://1drv.ms/1wI2eS4
Exchange disk statistics
Here is a tip how to gather disk statistics such as
CapacityGB, FreeSpaceGB, FreeSpace% for all disks in your Exchange organization.
$vols = @() Get-ExchangeServer | % { $comp = $_.Name $vols += Get-WmiObject -computername $comp -query "select Name, DriveType, FileSystem, FreeSpace, Capacity, Label from Win32_Volume where DriveType = 2 or DriveType = 3" | select @{Name='Server';Expression={$comp}},Label,Name,@{Name='CapacityGB';Expression={$_.Capacity/1GB}},@{Name='FreeSpaceGB';Expression={$_.FreeSpace/1GB}},@{Name='FreeSpace%';Expression={($_.FreeSpace*100)/$_.Capacity}} } $vols | Export-Csv -NoTypeInformation -Delimiter ";" -path "E:\ExchangeDiskreport.csv"