Tuesday, July 4, 2017

Using PowerShell To Retrieve IP Addresses for Exchange Servers

Hi Folks,

In this short post I will share with you a command on how to retrieve list of IP addresses for your Exchange servers. As you will see below it's very straightforward. It simply pipes all hostnames and then resolves each of them from DNS:

Get-ExchangeServer  |foreach {Resolve-DnsName $_.Name -NoHostsFile -Type A} |select Name,IPAddress

You will get a nice output like below:



Alternatively you can use Export-Csv command to export your results to CSV file if you need any further processing or reporting of this data.

Enjoy!

Tuesday, June 20, 2017

Quickly Checking Account Lockout State

Hi folks,

In this very quick post I wanted to share with you a quick retrieving of the account lockout status for an user account in the AD. It can be found by running the below simple command:

Get-ADUser "User1" -Properties LockedOut |select Name,LockedOut

And will result in a simple output as below:


If the value for the LockedOut is False then account is not locked and if it is True, then it is locked. Which is pretty obvious.

Enjoy!

Tuesday, June 6, 2017

Cumulative Updates and Recovery Databases

Hi folks,

I want to share about another adventure which I have had with the installation of the latest CU on Exchange 2016. During installation of CU and in particular during configuration of the Mailbox services component installation failed with the error as below:





In couple of words at this stage installation is checking availability of the arbitration mailboxes, and if they're not available, it tries to create them and configure quotas and SCL related settings.

According to this error for some reason Exchange setup program has attempted to configure arbitration mailbox in the recovery database. Probably it was the first retrieved from the list of DBs located on the server and since recovery DB can't store mailboxes setup program had failed.

In my case to solve it I had to remove it by running a command similar the the below:

Get-MailboxDatabase "RecoveryDB001" |Remove-MailboxDatabase -Confirm:$false


After this installation should proceed.

However in my cases there was a problem with AD replication and it was not properly removed from the AD. Therefore the error above would still pop up at every time I tried to re-run the installation program. In the log I have discovered domain controller which install program tried to use and navigated to the path of the DB as below:

CN=Databases,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups,CN=CONTOSO,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=contoso,DC=com

After manual deletion of a DB object from the AD installation had proceeded successfully.


Enjoy

Save Your Time Typing Local Hostname

Hi folks,

This is probably my shortest blog post. If you are just lazy as I am and if you employ a hard-to-remember naming convention for your computers and servers there is a default variable $env:COMPUTERNAME which retrieves local computers hostname. So for example if you want to run a command to check health of the local Exchange server this command will be at your disposal:

Get-ServerComponentState -Identity $env:COMPUTERNAME



Enjoy!

Friday, June 2, 2017

Another BackEnd Site Fixing (This Time for PowerShell)

Hi folks,

I have already shared in this post about my adventures with Exchange Management Shell and other CAS protocols which are caused by misconfigured back end web site on an Exchange 2016 Mailbox server.

Recently I have had yet another adventure. When launching Exchange Management Shell I saw the following error and PowerShell connected to another Exchange server in the same AD site:



Furthermore, I have discovered in the Application log the error event 1003 for Microsoft Front End HTTP Proxy followed by the warning event 1309 for ASP.NET:



My investigation has lead me to this article according to which this is caused by misconfigured certificate on the Exchange Back End web site. This can be easily seen when the binding for port 444 is checked:


All you need to do is to select the self signed certificate with the friendly name of "Microsoft Exchange" and click OK button:



After this you will need to run IIS reset or restart the server after which Exchange Management Shell can be accessed and used again.

Enjoy!

Thursday, June 1, 2017

Mailbox Exports Preventing Exchange 2010 Uninstallation

Hi folks,

In this quick post I would love to share with you about my recent adventure. When uninstalling Exchange 2010 binaries I faced the following error:



This error is self-explanatory and the below command  should be executed for each mailbox database that is displayed in error message:

Get-MailboxExportRequest | ?{ $_.RequestQueue -eq "DB01" }. | Remove-MailboxExportRequest 

After which mailbox database can be removed:

Remove-MailboxDatabase DB01 -Confirm:$false

Enjoy!

Wednesday, May 17, 2017

CAS Services and Remote PowerShell Fail on An Exchange 2016 Box


Hi folks,

In this quick post I will share with you about fixing the error when CAS authentication related modules fail to start on a freshly installed Exchange 2016 server. When launching remote PowerShell I was greeted with the below error and redirected to another server in the same AD site:





Furthermore in the Event Log you will see that the error of loading DLL files for OWA authentication and failure of starting Exchange BackEnd site (ID 2268 and 2214):




This article became very helpful. It pointed me to the missing path to the Exchange bin folder in the Path variable. On the server I was working on it was missing along with the other folders including paths to system folders. So from a healthy Exchange server I copied values of the Path variable and pasted them to the broken server, In my case it was something like below (in real life this of course may vary):

; ;C:\WINDOWS\system32;C:\WINDOWS;C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;C:\Program Files\Dell\SysMgt\oma\bin;C:\Program Files\Dell\SysMgt\shared\bin;C:\Program Files\Dell\SysMgt\idrac;C:\Program Files (x86)\Symantec\Data Center Security Server\Agent\IPS\bin;C:\Program Files\BMC Software\Control-M Agent\Default\exe;C:\Program Files\HP\HP BTO Software\lib;C:\Program Files\HP\HP BTO Software\bin;C:\Program Files\HP\HP BTO Software\bin\win64;C:\Program Files\HP\HP BTO Software\bin\win64\OpC;C:\Program Files\Microsoft\Exchange Server\bin;C:\Program Files\Microsoft\Exchange Server\Bin\Search\Ceres\Native\;C:\Program Files\Microsoft\Exchange Server\Scripts;C:\Program Files\Microsoft\Exchange Server\Scripts

I hope you will find this time saving for your troubleshooting and fixing activity.

Enjoy!

Wednesday, March 22, 2017

Windows HotFixes for Skype for Business Installation

Hi folks,

Just a short post on the installation of Skype for Business server. The hotfix from KB2982006 is listed among prerequisites server installation. However when the update is downloaded during the installation you will the message saying"This update is not applicable to your computer".

According to this article two more updates are needed for successful install of this hotfix. Below is sequence that the updates should be install in: first you install KB2919442, then KB2919355, which is the biggest one and finally KB2982006. You will need to reboot your server after the second and the third updates and your server is ready for installation.

Enjoy!

Retrieve BitLocker Recovery Password Information PowerShell

Hi folks,

I have recently spend quite a time investigating BitLocker technology and also implementing it for Exchange servers to protect drives on servers according to Microsoft's preferred architecture about which you can read here. You can also read this article on how to plan and implement BitLocker. So apart of this I will not comment much on this because this subject is covered there quite well.

When configuring BitLocker on your computer or server drives you can chose to backup your recovery keys to the AD. This is very handy as you can easily retrieve them when needed from the AD. And if your AD environment is tightened well enough you can keep it secure.

Now how do you check whether your BitLocker keys have been backed up to the AD or not. Obviously you can do it by using ADUC tool. However, if you are looking to create a dump of these keys ADUC may not be a very handy tool to use. After some investigation I have found this and this articles which were the major sources of my inspirations. Capitalizing on them, I have put together the below code which retrieves information on the recovery keys from AD and dumps them to CSV file which can be later processed by Excel.

$usrInput = $(Get-WmiObject Win32_Computersystem).name
$objComputer = Get-ADComputer $usrInput
$objADObject = get-adobject -Filter * | Where-Object {$_.DistinguishedName -match $objComputer.Name -and $_.ObjectClass -eq "msFVE-RecoveryInformation"}
$objADObject |select DistinguishedName,Name,ObjectClass |Export-Csv D:\Scripts\RecPwd-Report.csv

I hope you will find this little script useful for your BitLocker adventures as it applies to any Windows Server or client box.

Enjoy!

Monday, March 13, 2017

Fixing Broken BackEnd Site

Hi folks,

I would love to share with you my recent experience that I had with Remote PowerShell on an Exchange 2016 box. As you well know since Exchange 2013 Exchange server is using 2 web sites in IIS: Default WebSite and BackEnd. The prior is listening on ports 80 and 443 while the latter is listening on ports 81 and 444.

In my case when I launched Exchange Management Shell I was greeted with the below error:


My investigation led me to the following error events in System log



And Application log:




The errors were pointing to the BackEnd site where actual data rendering and processing for all protocols including PowerShell. As I was looking for solution of this problem this post and this TechNet article. According to it we need to retrieve information of all certificates that are used by IIS. We will need to use the below command for it.

netsh http show sslcert

You will get output as below:



When retrieved we will need to record certificate hash and application ID (appid) for 127.0.0.1:443. Usually I prefer to dump the above command to a test file to make it easier. Also I was not able to find a certificate which was listed for 0.0.0.0:444 in the certificate store of the affected server. So the certificate needs to be removed and replace with the existing one which is used for the Default Web Site.

After this  you will need to delete cert for the back-end site represented by 0.0.0.0:444 by running the below command:

netsh http delete sslcert ipport=0.0.0.0:444

After cert has been removed we will need to configure certificate for our back-end web site to use the same certificate that is used  by the Default Web Site. In the output above it is presented as 127.0.0.1:443.
Let's imagine that certificate hash for 127.0.0.1:443  is 1234567890abcdef3456787asabaec4e8ba and application id is  "{1abc2e345-a14b-4c22-b022-59fc885b0974}"

netsh http add sslcert ipport=0.0.0.0:444 certhash=1234567890abcdef3456787asabaec4e8ba appid="1234567890abcdef3456787asabaec4e8ba"{1abc2e345-a14b-4c22-b022-59fc885b0974}"



Make sure that all the brackets and quotes are in place.

I hope you will find this article helpful.

Enjoy!

Thursday, March 9, 2017

Exporting Mailboxes in Multi-Domain Environment

Hi folks,

Just wanted to share with you about an issue I have recently encountered. In the AD forest which has multiple domains when remotely connected to Exchange server via PowerShell and running New-MailboxExportRequest command you may experience the issue as below:


Basically, PowerShell will complain that it can't find mailbox on a DC from the same domain as Exchange server is. And this is because that by default EMS is by default talking to the same domain where Exchange servers are located and where it was launched. As I previously posted to see mailboxes cross forest you will need to execute this command:

Set-ADServerSettings -ViewEntireForest:$true

However, in this case it doesn't become a magic bullet to solve the problem.

Google-ing took me to this thread on MS TechNet forum. According to it in addition to seeing the whole forest you also need to talk to a domain controller in a child domain where your mailbox is located. So imagine and in the contoso.com forest you have a domain child.contoso.com which has Exchange mailboxes the code for exporting mailbox to PST file will be as follows;

Set-ADServerSettings -ViewEntireForest:$true
New-MailboxExportRequest user@child.contoso.com –FileName \\servername\pst\test.pst -DomainController DC01.child.contoso.com

I hope you will find it useful.

Enjoy!

Thursday, March 2, 2017

And Back to the Subject of ActiveSync Devices Reporting

Hi folks,

I have already shared with you about creating reports for Exchange ActiveSync devices using PowerShell. You can read this post about it.

I have recently discovered this reporting script for reporting ActiveSync devices published here by Paul Cunningham. All the information about it can be found in the article as well as in this Paul's post. The script is amazing and perfectly fits the purpose.

However, there're couple of the things that are missing in the script. First, if you have a multi-domain forest it is possible that not all of your mailboxes are retrieved and added to the report. To fix it you will need to edit the script and add the following line:

Set-AdServerSettings -ViewEntireForest:$true

I have added this line after the section which loads Exchange 2013 management shell as below:



This script is also good for creating ActiveSync reports from Office 365. However when trying to run this from my Windows 10 laptop I would be greeted with error like below:



This is quite easy to fix. Simply remove the whole section which loads on-premises EMS and run script from the remote PowerShell session connected to Office 365 endpoint. To be clear this is what you need to remove from the script to run it successfully against the cloud:


Enjoy!

Creating Reports from Admin Audit Logs

Hi folks,

In this post I would love to share with you some of experience that I had with Audit logs in Exchange. You well know about admin audit and mailbox audit logs available in Exchange and their usage so I won't spend too much time discussing them, but rather jump into some examples of retrieving info from admin audit logs.

So I once was requested about preparing report on who removed user mailboxes and also who added extra permissions to them. The 2 below lines provide code which retrieve when the commands which remove and disable mailboxes and also that assign permissions to the mailbox and also who ran them and when.

Search-AdminAuditLog -Cmdlets Disable-Mailbox, Remove-Mailbox -StartDate 09/20/2016 -EndDate 09/22/2016 |select ObjectModified,CmdletName,@{N="CmdletParameters";E={$_.CmdletParameters}},Caller,ExternalAccess,Succeeded,RunDate,OriginatingServer,ObjectState |export-csv C:\Reports\Lost-MBX-Report.csv


Search-AdminAuditLog -Cmdlets Add-MailboxPermission, Add-ADPermission -StartDate 11/18/2016 -EndDate 11/21/2016 |select ObjectModified,CmdletName,@{N="CmdletParameters";E={$_.CmdletParameters}},Caller,ExternalAccess,Succeeded,RunDate,OriginatingServer,ObjectState |export-csv C:\Reports\AD-Perm-Report.csv

There is also a nicer way to create reports from Admin Audit Logs and this article was very helpful as it points to this script which allows creating quite a nice and readable reports. Imagine you were requested to generate a report on which databases mailboxes have been moved. You will need to execute the code below which will generate reports similar to the ones that are generated by one-liners above:

$AdmSearch = Search-AdminAuditLog -Cmdlets new-moverequest,New-MigrationBatch
$AdmSearch | .\Get-SimpleAuditLogReport.ps1 –agree |Export-csv MigrationCmdlets.csv

The most valuable information is that the full command is being reported which gives you a good picture what was exactly happening in your environment.

Of course you can modify your request for admin log search to anything you like or need. Just use this article for more information.

Enjoy



Reinstalling Failed DAG Node from Scratch

Hi folks,

Just wanted to share with you about another scenario which you may face when you work with DAGs. Sometimes you can have your Exchange servers dead which you need to reinstall . There're 2 options of doing it. The first one is using /RecoverServer parameter while in the other case you will need to scrap all the Exchange server related information from AD. In this post I will cover the second scenario.

First, you will need to remove all the database copies from the failed server. You will need to run command as below:

Get-MailboxDatabaseCopyStatus -Server Server01 |foreach {Remove-MailboxDatabaseCopy -Identity $_.Name}

After this server should be removed from DAG. Since server is offline and can't be accessed by the cluster service you will need to use the -ConfigurationOnly parameter and command will be as below:

Remove-DatabaseAvailabilityGroupServer -Identity DAG01 -MailboxServer Server01 -Confirm:$false -ConfigurationOnly

After this you will need to verify that the server has been indeed removed from DAG by running the below command:

Get-DatabaseAvailabilityGroup DAG01 |select Name,Servers |fl

After DAG server has been removed it should be evicted from cluster:

Get-ClusterNode Server01 |Remove-ClusterNode -Force

Finally, we will need to clean up AD object for Exchange server. For this purpose ADSIEDIT tool will be needed. You will need to connect ADSIEDIT to Configuration partition and then navigate to the server object, something like below:

CN=Server01,CN=Servers,CN=Exchange Administrative Group (FYDIBOHF23SPDLT),CN=Administrative Groups,CN=CONTOSO,CN=Microsoft Exchange,CN=Services,CN=Configuration,DC=contoso,DC=com

Delete server object and click Yes for deleting container object. Please don't forget to be extremely careful when using ADSIEDIT, because one wrong mouse click can destroy your Exchange org and you will need to restore AD from backup authoritatively which is not a lot of fun.

Finally, in this scenario we will need to delete computer object of a dead Exchange server. Merely resetting password for it is not enough. And this is because when Exchange is installed it registers a bunch of Exchange-related SPN records. You can see it as below:

setspn -l SERVER01
Registered ServicePrincipalNames for CN=SERVER01,OU=Servers,DC=contoso,DC=com
:
        MSServerClusterMgmtAPI/SERVER01.contoso.com
        MSServerClusterMgmtAPI/SERVER01
        IMAP/SERVER01
        IMAP/SERVER01.contoso.com
        IMAP4/SERVER01
        IMAP4/SERVER01.contoso.com
        POP/SERVER01
        POP/SERVER01.contoso.com
        POP3/SERVER01
        POP3/SERVER01.contoso.com
        exchangeRFR/SERVER01
        exchangeRFR/SERVER01.contoso.com
        exchangeAB/SERVER01
        exchangeAB/SERVER01.contoso.com
        exchangeMDB/SERVER01
        exchangeMDB/SERVER01.contoso.com
        SMTP/SERVER01
        SMTP/SERVER01.contoso.com
        SmtpSvc/SERVER01
        SmtpSvc/SERVER01.contoso.com

If brand new computer object is not created Exchange installation may fail or in case of its success, services may fail starting, therefore I highly insist that it is deleted before the OS is re-imaged.

I hope you will find this post helpful for your dealings with Exchange servers.

Enjoy!

Wednesday, February 8, 2017

RBAC Effective Permissions

Hi folks,

You are well aware with the effective permissions in the NTFS and also on other objects that are controlled by ACLs (like AD objects or registry).

Now the same kind of check and report is available for Exchange RBAC. What it does, it checks all the role group membership of an admin account and then provides as an output roles that they were assigned to.

The below code should do this magic:

Get-ManagementRoleAssignment -GetEffectiveUsers | Where-Object {$_.EffectiveUserName -eq "Admin"} | Select-Object Role

And it provides code as below:



Enjoy!

Monday, February 6, 2017

A Great and Easy Way to Retrieve Average Message Size


Hi folks,

I have recently been working on one sizing exercise for Exchange 2016. In particular I needed to size servers that will be used for email routing only, no storage of mailboxes whatsoever. As you well know in Exchange 2013 and what's more on 2016 transport is no longer a separate role, however there are no tools available for sizing transport only servers.

The key parameter for any Exchange calculations is an average message size. Previously Profile Analyzer was a very helpful tool to achieve this purpose. As you know Profile Analyzer no longer works for Exchange 2010 and later. Microsoft has released this nice tool as a replacement of the Profile Analyzer, however it doesn't work against sites without mailboxes.

Therefore the only way to get average mail size on the transpport only servers is to use message tracking log. After some searching I have found this great article that came to my help.

So if you have only a single site with the Exchange calculating average size is pretty easy. The following code needs to be executed to achieve this:

For Exchange 2007 and 2010:

Get-TransportServer | Get-MessageTrackingLog -resultsize unlimited | measure-object -Property TotalBytes -Maximum –Average

For Exchange 2013 and 2016:

Get-TransportService | Get-MessageTrackingLog -resultsize unlimited | measure-object -Property TotalBytes -Maximum –Average

Nice and easy, isn't it.

Now, let's imagine we will need to calculate average size of all the messages that went trough the server over the course of a business week and that we have more than one AD site. We will need to change our query to all servers within a site, let's call it NEWYORK. the script will look something like this:

$TrpSrv = Get-ExchangeServer  |Where-Object {$_.Site -like "*NEWYORK*"} | |Get-TransportService

$TrpSrv |foreach {Get-MessageTrackingLog -Server $_.Name -Start "01/09/2017 09:00:00" -End "01/13/2017 17:00:00" -resultsize unlimited | measure-object -Property TotalBytes -Maximum –Average |out-file D:\Scripts\Average.txt -append}

Alternatively you will need to run the same command for each individual server in a site and then use tools like calculator or Excel to calculate average size of the message. In this case the code will be like below:

Get-TransportService SERVER01 | Get-MessageTrackingLog -Start "01/09/2017 09:00:00" -End "01/13/2017 17:00:00" -resultsize unlimited | measure-object -Property TotalBytes -Maximum –Average |out-file D:\Scripts\Average.txt

I hope you will find this post useful for your sizing adventures.

Enjoy!


Friday, January 20, 2017

PowerShell Module to Retrieve ACLs from Different Sources

Hi folks,

In this post I have shared with you about PowerShell module that can be used to manage and report NTFS permissions on disk drives and files and folders. However I was also looking for a nice way to report Active Directory ACLs and ACEs by using PowerShell. The Get-Acl cmdlet wouldn't suffice as it would report extended permissions on AD as ExtendedRight without any clear details. Here you can download PowerShell module that allows you to manage ACLs and ACEs not only on file system but also on printers, registry and most importantly AD.

Just as NTFS module this module needs to be installed to the server or computer on which you are running it. You will need to unzip the downloaded files and copy module and the related files to %Windir%\System32\WindowsPowerShell\v1.0\Modules. Before this you will need to create a folder named  PowerShellAccessControl. The below code should do installation magic.

New-Item "C:\Windows\System32\WindowsPowerShell\v1.0\Modules\PowerShellAccessControl" -Type Directory
Copy-Item "C:\Scripts\PowerShellAccessControl\*" "C:\Windows\System32\WindowsPowerShell\v1.0\Modules\PowerShellAccessControl"


You can read more about the cmdlets in the module in the link published below as they are described in the article. Before running any cmdlet you will first need to import the module into your PowerShell session:

Import-Module PowerShellAccessControl

There're a bunch of the cmdlets in module, I will show you just couple of the samples that you needed and you will thread your own way.

This command will get AD permission from

Get-ADObject "CN=SERVER01,OU=Servers,DC=CONTOSO,DC=COM"| Get-AccessControlEntry

(you can also use Get-AdUser, Get-ADGroup and other cmdlets from the Active Directory PowerShell module to get AD input object)

Finally, another sample below retrieves permissions for the same object for a particular user or group:

Get-ADObject "CN=SERVER01,OU=Servers,DC=CONTOSO,DC=COM" |Get-AccessControlEntry |Where-Object {$_.Principal -eq "Contoso\ContosoAdmins"}

I will let you explore this module further by yourselves and I hope you will find it to be useful.

Enjoy!

Monday, January 16, 2017

Some Additions to My Old ActiveSync Reporting Post

Hi folks,

Couple of years ago I have shared with you this post on the code that can be used for reporting of the ActiveSync devices. It still remains valid. However, I'd love to post here some amendments that may be useful for you.

Firstly, Microsoft has introduced in Exchange 2013 the cmdlet Get-MobileDeviceStatistics which at one point may replace Get-ActiveSyncDeviceStatistics and I won't be surprised that the latter one will be deprecated in one of the next builds or major versions. Therefore I have updated my code using it. And secondly I also wanted to report some more information into my report. I wanted to be able to report user agent and also when the device has successfully synced last time. Therefore parameters LastSuccessSync and DeviceUserAgent have been added to the code. The updated code looks like as below, and I would recommend using it with Exchange 2013 and 2016.

$EasUser=Get-CASMailbox -ResultSize Unlimited |Where-Object {$_.HasActiveSyncDevicePartnership-eq 'True'}
$EasUser | foreach {Get-MobileDeviceStatistics -Mailbox $_.Name | select identity,LastSuccessSync,devicetype,deviceid,DeviceUserAgent,isremotewipesupported,LastSuccessSync} |Export-Csv D:\MessagingMetricsReports\ActiveSyncUsageReport.csv

Again, you can add as many parameters as you want to see in your final report.

Enjoy!

Friday, January 13, 2017

Retrieve TPM Module Version Using PowerShell

Hi folks,

I would love to share with you two quick ways to retrieve version of TPM module. What is TPM module and how it helps in BitLocker encryption you can find here.

I found it thanks to this article from Dell. I have adapted this command to retrieve the hostname and version of TPM module installed there. My code looks like below:

Get-WMIObject –class Win32_Tpm –Namespace root\cimv2\Security\MicrosoftTpm |select PsComputerName,SpecVersion


This will produce output as below:


The SpecVersion corresponds to the version of the TPM module. Above is the output for TPM 2.0


Finally, there is a nice way to report it for more than one server remotely. This can be achieved by using TPM management module which has been published here in TechNet gallery. ZIP file can be downloaded from the same link and exported. After which module needs to be imported into PS session. Since in my case I'm trying to report information on TPM module installed on Exchange servers I imported it to EMS session.

The command Get-OSCTPMChip is needed to retrieve information from the computer and can be run against remote computers. For it to work successfully you will need to create variable for credentials.

I have composed the below code to connect to all Exchange 2016 servers in the environment and retrieve server host name and TPM module version:

$Cred = Get-Credential
Import-Module 'C:\Scripts\GetTPMChipsStatus (PowerShell)\GetTPMChipsStatus.psm1'
$Exch2016 = Get-ExchangeServer | where-object {$_.AdminDisplayVersion -like "*Version 15.1*"}
$Exch2016 |foreach {Get-OSCTPMChip -ComputerName $_.Name -Credential $Cred} |select ComputerName,SpecVersion |Export-Csv C:\Scripts\TPMExchangeReport.csv

I hope you will find it useful.

Enjoy!




Thursday, January 12, 2017

Sending Messages as Scheduled Task

Hi folks,

I would love to share with you about my recent adventure on configuring scheduled task for running some Exchange-related scheduled tasks using PowerShell. To avoid using excessive permissions for an account that will run the scheduled task I created user account in AD with the default group membership (Domain Users). This account has been granted "Logon as batch job" rights on a server where the scheduled task will run. The script included a line to send results of the script execution to an admin's email address, something like below:

Send-MailMessage -from sender@contoso.com -to recipient@contoso.com -subject "Scheduled Task Report" -body ($bb | out-string) -smtpServer 'server01.contoso.com' -bodyashtml

However, emails wouldn't arrive. There was nothing in the task to indicate failure of it as it ran smootly. So the following line was added to the beginning of the script:

Start-Transcript -Path C:\Scripts\executionTranscript.txt

And at the end of the script I appended:

Stop-Transcript

When checking execution transcript I would see the error as below:

Send-MailMessage : Mailbox unavailable. The server response was: 5.7.1 Client does not have permissions to send as
this sender
At D:\ML\Scripts\QueueStatus.ps1:16 char:1
+ Send-MailMessage -from sender@contoso.com -to recipient@contoso.com ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
    + CategoryInfo          : InvalidOperation: (System.Net.Mail.SmtpClient:SmtpClient) [Send-MailMessage], SmtpExcept
   ion
    + FullyQualifiedErrorId : SmtpException,Microsoft.PowerShell.Commands.SendMailMessage

What it says that service account can send as sender@contoso.com (of course there should be your sender address here). To resolve this issue scheduled task will need to be reconfigured to run as sender@contoso.com with granting rights as mentioned above. Alternatively, service account can be mail or mailbox enabled (I would recommend the former) and script updated to send email as service account.

You will need to run the below code to mail-enable the service account:

Enable-MailUser -Identity "CONTOSO\serviceaccount" -PrimarySMTPAddress "serviceaccount@contoso.com" -ExternalEmailAddress "serviceaccount@contoso.com"

Then you will need to reconfigure your code to something as below:

Send-MailMessage -from serviceaccount@contoso.com -to recipient@contoso.com -subject "Scheduled Task Report" -body ($bb | out-string) -smtpServer 'server01.contoso.com' -bodyashtml


I hope you will find this useful when troubleshooting issue as this one.

Enjoy!

Resetting IDRAC on Dell Servers

Hi folks,

If you are using Dell R720 or R730 you may have encountered IDRAC, a Java-based tool that allows us to remotely connect to server and manage it from console without a need to go to a datacenter and play with KVM there.

However this is what I once encountered. I saw that the Volume Console Preview shows me black screen while trying to connect to server remotely. In the Virtual Console Preview on the IDRAC page instead of server login page I would see black screen:


When trying to launch remote console I would see the error as below:




To resolve this, you will need to launch Command Line (not PowerShell!) as admin on your server and run the below command:

racadm racreset soft


Give it about 5 Minutes to reset and then login to IDRAC again and in the virtual console section you will see the following in the Virtual Console Preview section:



This indicates that the command has done the magic and you now can click Launch to connect to your server's console remotely.

I hope you will find this helpful.

Enjoy!

Wednesday, January 11, 2017

Decommissioning Exchange 2010 and Later Mailbox Servers

Hi folks,

As Exchange 2016 is around and Exchange 2013 has been around even longer many of you are dealing with decommissioning of your Exchange 2010 servers. Another reason for decommissioning 2010 servers is moving to the cloud. Surely this is one of the greatest versions of Exchange and will be greatly missed.

In this post I will focus on decommissioning of Mailbox servers, especially DAG members. You can read this article for more details on decommissioning of Exchange 2010 servers and consideration on every role.

This post assumes that all mailboxes have been moved off servers, otherwise we won't be able to decommission mailbox databases.

First we need to remove every mailbox database copy on the server. As a lazy man I prefer to do it using one code line (two if possible). One liner didn't work for me:

Get-MailboxDatabaseCopyStatus -Server SERVER01 |foreach {Remove-MailboxDatabaseCopy -Identity $_.Name -Confirm:$false}

I got the error as below:


So I ended up feeding database copies to the variable $DBCop, After this I ran Remove-MailboxDatabaseCopy against every DB in the $DBCop variable. The code looks as below:

$DBCop = Get-MailboxDatabaseCopyStatus -Server SERVER01
$DBCop |foreach {Remove-MailboxDatabaseCopy -Identity $_.Name -Confirm:$false}

After mailbox database copies are removed we will need to remove mailbox databases themselves:

$DB = Get-MailboxDatabase -Server SERVER01
$DB |foreach {Remove-MailboxDatabase -Identity $_.Name -Confirm:$false}

You are not mistaken to see Get-MailboxDatabase command with -Server parameter. Though in Exchange 2010 and onward DBs are managed globally, still this command works and retrieves all mailbox DB copies stored on a server, This is ideal for limiting output of mailbox databases to a server which we decommissioning. And I don't want PowerShell to complain me about buffer so I create here $DB variable almost immidiately.

After this we will need to remove every DAG member from DAG. Firstly, we will need to disable DAC mode from DAG:

Set-DatabaseAvailabilityGroup DAG01 -DatacenterActivationMode Off

After this we will need to remove each DAG member by runing this command:

Remove-DatabaseAvailabilityGroupServer -Identity DAG01 -MailboxServer SERVER01 -Confirm:$false

After all of mailbox servers are removed from DAG you can kill DAG object in the AD as well:

Remove-DatabaseAvailabilityGroup -Identity DAG01 -Confirm:$false

Remove CAS array (the only ugly thing about Exchange 2010) object from the AD:

Remove-ClientAccessArray outlook.contoso.com -Confirm:$false

Finally, you will need to uninstall Exchange binaries. For Exchange 2010 this command does the magic:

setup.com /m:Uninstall




For Exchange 2013 and later you will need to run

setup.exe /m:Uninstall /IAcceptExchangeServerLicenseTerms

Enjoy!

Tuesday, January 10, 2017

Changing Your AD Password Via RDP

Hi folks,

Many of you may already know it and therefore please feel free to ignore this little post. However, I have recently learned a nice trick on how to change your AD password via RDP screen. It is especially useful for engineers and admins who admin their Windows servers via RDP Manager or a single RDP conenction (aka MSTSC command).

You will need to run the following command: osk

It will display on-screen keyboard. On your normal keyboard you will need to hit Ctrl+Alt while on the on-screen keyboard you will need to click on Delete.



That will display password change screen. An you know yourself what to do further.




Enjoy!

Extracting AD Group Members Using PowerShell

Hi guys,

Imagine you know the name of the distribution list of the AD group which is not mail-enabled and you will need to extract members of it. The below code should come to your help. I personally ran it from the Exchange Management Shell and had AD PowerShell module loaded (which is needed on any machine running Exchange tools anyway. The first line extracts distinguished name of the group into a variable, while the second one is extracting group members (in my case attributes like DistinguishedName and samAccountName (you can change output attributes just as you need). These attributes are dropped into the CSV file.

$Grp = (Get-Group MyGroupName).DistinguishedName


Get-ADGroupMember $Grp |select DistinguishedName,SamAccountName |Export-Csv c:\Scripts\GrpMbr.csv

Enjoy!

Monday, January 9, 2017

Capturing Exchange Components Logs

Hi folks,

There are moments in our lives when we need to perform some troubleshooting of our Exchange environment. You can increase loggi

You can read more about logging for Exchange components in this article

For components list and how it has changed in Exchange 2013 you can refer here

If you want to retrieve list of all Exchange components you can run this command:

Get-EventLogLevel -Identity "MSExchange*" |sort Identity



In my case I needed to perform troubleshooting of EWS so to check its logging level you will need to run the following command:

Get-EventLogLevel -Identity "MSExchange Web Services\Core"



Depending on the logging detail level required you will need to run Set-EventLogLevel command and specify logging level depending on the logging details required. The possible logging levels that you can set are: 0 (Lowest), 1 (Low), 3 (Medium), 5 (High), and 7 (Expert). In my case I needed all details so I ran the following command:

Set-EventLogLevel -Identity "MSExchange Web Services\Core" -Level 7

After completing your troubleshooting activities you will need immidiately revert setting back to the default (Lowest or 0 in our case)

Set-EventLogLevel -Identity "MSExchange Web Services\Core" -Level 0



Enjoy!




UM Certificate Configuration in Exchange 2013 and Later

Hi folks,

Just wanted to quickly share with you about the configuration of Exchange certificate for Unified Messaging on Exchange 2013 and 2016 servers. In Exchange 2007 and 2010, as you remember, UM was a separate role and Set-UMServer was the command which did all the configuration magic. This has changed in Exchange 2013 as UM service has been spread between the Mailbox and CAS roles. Now Mailbox server run UM service which is manipulated by the Set-UMService cmdlet, while CAS service runs UM Call Router service which accepts all the SIP traffic and proxies it to the UM service on the Mailbox servers that hosts active DB copy for the mailbox where the call is being routed to. You can read more about UM in Exchange 2013 here. On the Exchange 2016 both of the services mentioned above are hosted on the Mailbox role.

So in order to configure certificate for UM on the Exchange 2013 and later server you will need to enable startup mode for UM and UM Call Router services either to TLS (for integration with Lync or Skype for Business) or Dual mode:

Set-UMService UMSRV01 -UMStartupMode Dual

Set-UMCallRouterSettings -Server UMSRV01 -UMStartupMode Dual

After which you will need to import certificate from the file and enable it for the appropriate services:

Import-ExchangeCertificate -FileData ([Byte[]]$(Get-Content -Path certfile.NET.pfx -Encoding byte -ReadCount 0)) -Password:(Get-Credential).password

Enable-ExchangeCertificate -Thumbprint XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX -Services UM,UMCallRouter

Don't forget that you will need a separate cert for each of the Exchange servers with a server hostname as subject name.

Enjoy!