I have a guilty secret: I screen my incoming phone calls. I no longer answer blocked numbers on my work phone – it’s always PPI spam – and I recognise the numbers of those I work closely with, so I can prioritise my response (i.e. do I want to be interrupted by that person, or can I respond to voicemail later?). To be honest, it’s just the same with email – some people will get an immediate response, others will need more thought and I’ll respond when I have more time (or not, in some cases). Is it unprofessional? I don’t think so – it’s about time management.
Recently, I had a missed call on my mobile from a number I didn’t recognise. I could see it was internal (all of our mobile phones have the same first few digits) so I thought I’d search the Global Address List in Outlook. Unfortunately though, Outlook doesn’t let me search the GAL on phone numbers…
Using PowerShell to search Active Directory and see who a missed call is from… maybe I should just pick up the phone… nah, geek away…
— Mark Wilson (@markwilsonit) February 21, 2013
I could have just called them back (actually, I did!) but the geek in me had the bit between the teeth… could I script up some kind of reverse lookup for phone numbers? And, in true Barack Obama (or Bob the Builder if you’re on this side of the Atlantic) style, the answer turns out to be:
“Yes, we can!”
So, if you use a Windows PC and you like scripting, read on. If you don’t, probably best just call the number back and see who answers!
Getting ready to query Active Directory with PowerShell
The first hurdle was that, in order to query Active Directory from PowerShell, I needed to have the Remote Server Administration Tools (RSAT) component installed on my Windows 7 workstation in order to do this, but it’s actually a two-step installation process.
- Firstly, download and install the RSATs to the workstation.
- In Control Panel, Programs, Programs and Features, Turn Windows features on or off, make sure that the Active Directory Module for Windows PowerShell is available under Role Administration Tools, AD DS and AD LDS Tools.
Once the RSATs were installed and the Active Directory Module for Windows PowerShell was enabled, I could fire up Windows PowerShell and issue the command to load the Active Directory management cmdlets:
Import-Module ActiveDirectory
Finding the available attributes to search against
Next up, I needed to know which properties are available for an Active Directory User object. I used my own email address as a filter to Get-User, which retrieved the details for the given AD User object, then selected all properties and piped the resulting output into Get-Member (which gets the properties and methods of objects):
Get-ADUser -Filter {EmailAddress -like "user@domain.com"} -Properties * |
Get-Member -MemberType property
Building up confidence, I started to play around and query individual attributes for the selected object:
$user = Get-ADUser -Filter {EmailAddress -like "user@domain.com"} -Properties *
$user.Title
$user.OfficePhone
$user.SAMAccountName
I found that each of these returned the information I would expect for my own user account in Active Directory.
Constructing the query
The next step was to search the whole directory but this time to filter the properties returned and to pipe through Where-Object
to match certain criteria, then pipe the resulting output from that query into a table:
Get-AdUser -Filter * -Properties OfficePhone |
Where-Object {$_.UserPrincipalName -match "Wilson"} |
Format-Table OfficePhone,UserPrincipalName
This returns the office phone number for everyone whose user name contains the string Wilson
. That tested the principle but was not the query I was trying to create, so I edited the query to match a number against a number of phone number properties (making sure that all the properties that need to be displayed are in the filter) and also prompted for the search string, storing it in a variable:
$Search = Read-Host 'What number would you like to search for?'
Get-AdUser -Filter * -Properties OfficePhone,MobilePhone,TelephoneNumber |
Where-Object {$_.OfficePhone -match $Search -or $_.MobilePhone -match
$Search -or $_.TelephoneNumber -match $Search} |
Format-Table GivenName,Surname,OfficePhone,MobilePhone,TelephoneNumber
This time, the resulting output was exactly what I was after – a single entry matching the partial phone number I’d asked it to match (824753
in the example below):
GivenName Surname OfficePhone MobilePhone TelephoneNumber --------- ------- ----------- ----------- --------------- Mark Wilson 73824753 +447xxx824753 73824753
Finally, I wrapped the whole thing up in a script and, as long as I’ve done the usual Set-ExecutionPolicy remotesigned
stuff, I can perform reverse lookups on phone numbers to my heart’s content… now, if only I could have an iPhone app to do this for me when the calls come in…
Nice! This is awesome!
Super!!!! saves me a lot of time. But, how do I save this to a cvs file?