Exchange: How to search by an email address?

What if you have an email address, you want to know which object that email address belongs to? Mailbox or Distribution Group or Contact or Public Folder?

You have to keep searching by the following commands till you find your object. Open PowerShell and connect to Exchange (or Exchange Online).

Get-Mailbox | %{$_.EmailAddresses | ?{$_ -like “*<email address>*”}}

Get-RemoteMailbox | %{$_.EmailAddresses | ?{$_ -like “*<email address>*”}}
Get-DistributionGroup | %{$_.EmailAddresses | ?{$_ -like “*<email address>*”}}

Get-MailContact| %{$_.EmailAddresses | ?{$_ -like “*<email address>*”}}
Get-MailPublicFolder | %{$_.EmailAddresses | ?{$_ -like “*<email address>*”}}


Hope you saved some time and found your Exchange Object. Enjoy!!


Find SQL Servers on the network by PowerShell

I will make simple and short. PowerShell command uses SQL Browser service to populate the local SQL servers and instances on the network.

So the requirements are:

  1. SQL Browser service installed and running (or run it on a SQL server)
  2. You should be a Administrator (preferably domain admin)
  3. You have to run this command on each site (on one of the local server)

Open PowerShell and run this command.


Things are getting much easier these days. 🙂

Office 365: Send service alert emails using PowerShell

Office 365 service health information (healthy, degraded, etc.,) can be checked at Office 365 Admin console or using Office 365 Admin App on the phone.

At least Office 365 Admin App (for iPhone/Android/Windows) alerts when there is a change in service status.

I wrote a script for old school boys and girls who want to receive the Office 365 service degradation in emails.

This script can be run in intervals using Windows Task Scheduler. There is no special requirements (PS Modules) to run the script in PowerShell.

First Step: Create a Password XML file

Copy/Paste the following two PowerShell commands to create the password XML file. We are saving just the password (of the Office 365 Administrator account) in encrypted form. When asked type the password carefully.

$text = Read-Host -AsSecureString -Prompt ‘Enter Password’
$text | Export-Clixml -Path “$home\Documents\mypassword.xml”

Note: We are only saving the password in encrypted form in XML file in the user profile. Since only the user has access to their user profile, password file is in safe location. And we are not storing the user name, so it is not useful without knowing which user this password belongs to.

Another Note: if you are going to run the script in different user context in Task Scheduler, you have move the mypassword.xml file to the user profile location of the correct user context.

Now the script:

Either copy/paste the script in NotePad and name it Get-O365-Service-Health-Alerts.ps1 or DOWNLOAD THE SCRIPT.

Important: Make sure you assign appropriate values in the beginning of the script.


Script Name: Get-O365-Service-Health-Alerts.ps1
Purpose: Get the Office 365 tenant service health alerts using
JSON and send email to admins if the any degraded service is

Prerequiste 1: mypassword.xml file in your documents folder

You have to create the password.xml file using the
following PowerShell commands:

$text = Read-Host -AsSecureString -Prompt ‘Enter Password’
$text | Export-Clixml -Path “$home\Documents\mypassword.xml”

Prerequiste 2: Assign correct values to the variables
in this script (see below)

Written by: Anand, the awesome, Venkatachalapathy


#Assign the appropriate values in these variables
$username = ‘’
$SMTPServername = “”
$SMTPPort = 25
$From = “”
$To = “”


# read in the secret and encrypted password from file
$password = Import-Clixml -Path “$home\Documents\mypassword.xml”
# add the username and create a credential object
$credential = New-Object -TypeName PSCredential($username, $password)

# convert the credential to JSON format   
$jsonPayload = (@{userName=$credential.username;password=$credential.GetNetworkCredential().password;} | convertto-json).tostring()

# Fetch the Office 365 sevice health status using REST
$cookie = (invoke-restmethod -contenttype “application/json” -method Post -uri “” -body $jsonPayload).RegistrationCookie
$jsonPayload = (@{lastCookie=$cookie;locale=”en-US”;preferredEventTypes=@(0,1)} | convertto-json).tostring()
$events = (invoke-restmethod -contenttype “application/json” -method Post -uri “” -body $jsonPayload)

#Assign the service health events to a variable
$serviceEvents = $events.Events

#Check each event
foreach($event in $serviceEvents)
    $status = $event.status
    $detailedstatus = $event.AffectedServiceHealthStatus
    $Title = $event.Title
    $UpdatedTime = $event.LastUpdatedTime
    $Messages = $event.Messages

    #Check if the status is degraded
    If ($status -like “*degradation” )
        #form the mail subject
        $subject = $detailedstatus.ServiceName + ” – $status at $UpdatedTime”
        #display the subject

        #form the mail body
        $text = “”
        foreach($Message in $Messages)
            $text += $Message.MessageText

        #Send email to the admin
        Send-MailMessage -SmtpServer $SMTPServername `
                         -Port $SMTPPort `
                         -From $From -To $To `
                         -Subject $subject -Body $text
******************* End of the script ********************

Search-ADAccount for disabled, expired, inactive accounts

What would be the easiest way to list disabled accounts, inactive accounts or expired accounts from AD. You could use Get-ADUser or Get-ADObject, but they are more complicated & dealing with User attributes.

I found Search-ADAccount, it’s been much easier and generating reports from AD on the fly pretty much. Search-ADAccount description and help is at HERE.

Here is the sample commands. Note the number of days is set to 90 days in these commands. Change the day from 90 to your suitable number. You can remove Export-Csv command to show the results in the PowerShell window.

  • Search AD for Inactive Computer Accounts for more than 90 days.

Search-ADAccount -ComputersOnly -AccountInactive | ? { $_.LastLogonDate -lt (get-date).AddDays(-90) } | Select-Object Name,LastLogonDate,DistinguishedName | Export-Csv -Path .\Inactive-Computers-morethan-90days.csv –NoTypeInformation

  • Search AD for Inactive User accounts for more than 90 days

Search-ADAccount -AccountInactive -UsersOnly | ? { $_.LastLogonDate -lt (get-date).AddDays(-90) } | Select-Object Name,SAMAccountName,LastLogonDate,Enabled,LockedOut,PasswordExpired | Export-Csv -Path .\Inactive-Users-morethan-90days.csv –NoTypeInformation

  • Search AD for Expired User accounts for more than 90 days

Search-ADAccount -AccountExpired -UsersOnly | Select-Object Name,SAMAccountName,AccountExpirationDate,LastLogonDate,DistinguishedName | Export-Csv -Path .\Expired-UserAccounts.csv –NoTypeInformation

I believe you get the idea. Tweak the cmdlet or filter to get more combination of reports.

Outlook removes line breaks, but Why?

When we type beautiful emails with some (apparently) extra lines (line breaks) to make the message more readable sometimes. And when it reaches the user, Outlook removes the extra lines and make the email real ugly. Then Outlook displays this message on top of the message window: We removed extra line breaks from this message.


You can restore the extra lines by clicking on that message and choose Restore line breaks.


To permanently disable Outlook to remove the line breaks, you have to go to Outlook Options in File/Outlook Options, under Mail section.  Scroll down and find Remove extra line breaks in plain text messages option under Message Format section.


Machine generated alternative text:

Exchange: Members can’t remove themselves from security groups. Please set the group to Closed…

It was interesting to see when I was trying to add a member to a “mail enabled” security group in Exchange Admin Center, I get this:


Oh! I was freaking add a member…what the?

Well, we have two options.

One: Add the member using Active Directory Users and Computer console. It is easy, but we are not fixing the under laying issue.  So the option two is necessary.

Two: Make the group closed so members can’t leave themselves (even freaking though nobody is trying to leave the group) so we don’t get above message. Open PowerShell and connect to your Exchange Server and use the following cmdlet to close the group.

Set-DistributionGroup <Group Name or Alias>  -MemberDepartRestriction Closed

Did it help? Leave me a reply.

List all authorized DHCP servers from Active Directory

Here is PowerShell command to list all authorized DHCP servers from Active Directory. Replace the DOMAIN and COM with your domain name in the command below.

Get-ADObject -SearchBase “cn=configuration,dc=DOMAIN,dc=COM” -Filter { ObjectClass -eq ‘dhcpclass’ } | Select-Object Name  | Format-Table –Wrap

I used format-table with wrap option to display full DHCP server name if it is long name.

If you browser the same location (in SearchBase in Get-ADObject cmdlet) in AD Sites and Services (with services option enabled), you will see the DHCP servers. This command list those DHCP servers, that’s all.