212 lines
7.2 KiB
PowerShell
212 lines
7.2 KiB
PowerShell
function Get-O365MailboxServerDatacenterLocation
|
|
{
|
|
<#
|
|
.SYNOPSIS
|
|
Determines the datacenter and location of an Exchange Online Server by name
|
|
|
|
.DESCRIPTION
|
|
Determines the datacenter and location of an Exchange Online Server by name
|
|
Multiple Servers are supported.
|
|
|
|
The Following info is returned:
|
|
ServerName = The server name you used
|
|
Location = City (if known) or country
|
|
Region = Region (e.g. EUR for Europe, or NAM for North America)
|
|
GDPR = Is the Region EUR (Europe) or not
|
|
|
|
.PARAMETER ServerName
|
|
Server Name to check
|
|
|
|
.EXAMPLE
|
|
PS C:\> Get-O365MailboxServerDatacenterLocation -ServerName AM3PR1001MB1421
|
|
|
|
Sample Result:
|
|
ServerName Location Region GDPR
|
|
---------- -------- ------ ----
|
|
AM3PR1001MB1421 Amsterdam, Netherlands EUR True
|
|
|
|
The Server seems to be in Amsterdam, Netherlands (Europe)
|
|
|
|
.EXAMPLE
|
|
PS C:\> Get-O365MailboxServerDatacenterLocation -ServerName 'AM3PR1001MB1421 (15.20.3890.032)'
|
|
|
|
Sample Result:
|
|
ServerName Location Region GDPR
|
|
---------- -------- ------ ----
|
|
AM3PR1001MB1421 Amsterdam, Netherlands EUR True
|
|
|
|
The Server seems to be in Amsterdam, Netherlands (Europe)
|
|
The Server name needs to be the first word in the string, the rest is ignored!
|
|
|
|
.EXAMPLE
|
|
PS C:\> Get-O365MailboxServerDatacenterLocation -ServerName AZ3PR1001MB1421
|
|
|
|
Sample Result:
|
|
ServerName Location Region GDPR
|
|
---------- -------- ------ ----
|
|
AZ3PR1001MB1421 Unknown Unknown Unknown
|
|
|
|
This is the result if the server location is unknown
|
|
|
|
.EXAMPLE
|
|
PS C:\> Get-O365MailboxServerDatacenterLocation -ServerName 'AM3PR1001MB1421', 'AZ3PR1001MB1421'
|
|
|
|
Sample Result:
|
|
ServerName Location Region GDPR
|
|
---------- -------- ------ ----
|
|
AM3PR1001MB1421 Amsterdam, Netherlands EUR True
|
|
AZ3PR1001MB1421 Unknown Unknown Unknown
|
|
|
|
Query multiple servers at the same time
|
|
|
|
.NOTES
|
|
This is something I wrote for myself: I want to get detailed informations about Exchange servers that I find in some of the Microsoft Office 365 Logs
|
|
|
|
Limitation:
|
|
- Table of data-centers is static and may need to be expanded as Microsoft brings additional data-centers online
|
|
- If Microsoft decide to change the naming convention, the table of data-centers will become useless instantly
|
|
- The script works offline and does not check any plausibility (e.g. none existing servers, like in the examples above)
|
|
|
|
The Following info is returned:
|
|
ServerName = The server name you used
|
|
Location = City (if known) or country
|
|
Region = Region (e.g. EUR for Europe, or NAM for North America)
|
|
GDPR = Is the Region EUR (Europe) or not - This is one of the key functions for me!
|
|
|
|
Inspired by this blog post: https://adameyob.com/2018/03/30/exchange-online-woes
|
|
But my solution is slightly different: I use the server name I have from the logs to get the info
|
|
#>
|
|
[CmdletBinding(ConfirmImpact = 'None')]
|
|
param
|
|
(
|
|
[Parameter(Mandatory,
|
|
ValueFromPipelineByPropertyName,
|
|
Position = 0,
|
|
HelpMessage = 'Server Name')]
|
|
[Alias('M365ServerName', 'MailboxServer', 'O365MailboxServerName')]
|
|
[string[]]
|
|
$ServerName
|
|
)
|
|
|
|
begin
|
|
{
|
|
# Run Garbage Collection
|
|
[gc]::Collect()
|
|
|
|
# Create a new Hash-table
|
|
$Datacenter = (New-Object -TypeName Hashtable)
|
|
|
|
# Fill the Hash-table
|
|
$Datacenter['AM'] = @('EUR', 'Amsterdam, Netherlands')
|
|
$Datacenter['BL'] = @('NAM', 'Virginia, USA')
|
|
$Datacenter['BN'] = @('NAM', 'Virginia, USA')
|
|
$Datacenter['BY'] = @('NAM', 'San Francisco, California, USA')
|
|
$Datacenter['CH'] = @('NAM', 'Chicago, Illinois, USA')
|
|
$Datacenter['CO'] = @('NAM', 'Quincy, Washington, USA')
|
|
$Datacenter['CP'] = @('LAM', 'Brazil')
|
|
$Datacenter['CY'] = @('NAM', 'Cheyenne, Wyoming, USA')
|
|
$Datacenter['DB'] = @('EUR', 'Dublin, Ireland')
|
|
$Datacenter['DM'] = @('NAM', 'Des Moines, Iowa, USA')
|
|
$Datacenter['GR'] = @('LAM', 'Brazil')
|
|
$Datacenter['HE'] = @('EUR', 'Finland')
|
|
$Datacenter['HK'] = @('APC', 'Hong Kong')
|
|
$Datacenter['KA'] = @('JPN', 'Japan')
|
|
$Datacenter['KL'] = @('APC', 'Kuala Lumpur, Malaysia')
|
|
$Datacenter['LO'] = @('GBR', 'London, England')
|
|
$Datacenter['ME'] = @('APC', 'Melbourne, Victoria, Australia')
|
|
$Datacenter['MM'] = @('GBR', 'Durham, England')
|
|
$Datacenter['MW'] = @('NAM', 'Quincy, Washington, USA')
|
|
$Datacenter['OS'] = @('JPN', 'Japan')
|
|
$Datacenter['PS'] = @('APC', 'Busan, South Korea')
|
|
$Datacenter['SG'] = @('APC', 'Singapore')
|
|
$Datacenter['SI'] = @('APC', 'Singapore')
|
|
$Datacenter['SN'] = @('NAM', 'San Antonio, Texas, USA')
|
|
$Datacenter['SY'] = @('APC', 'Sydney, New South Wales, Australia')
|
|
$Datacenter['TY'] = @('JPN', 'Japan')
|
|
$Datacenter['VI'] = @('EUR', 'Austria')
|
|
$Datacenter['YQ'] = @('CAN', 'Quebec City, Canada')
|
|
$Datacenter['YT'] = @('CAN', 'Toronto, Canada')
|
|
}
|
|
|
|
process
|
|
{
|
|
$Result = (New-Object -TypeName System.Collections.Generic.List[System.Object])
|
|
|
|
foreach ($SingleServerName in $ServerName)
|
|
{
|
|
# Cleanup the Server name (Remove everything after the 1st word)
|
|
$SingleServerName = ($SingleServerName -split ' ')[0]
|
|
|
|
# This is a bit nasty, but unknown cause errors (null pointer)
|
|
try
|
|
{
|
|
$ObjectRegion = $Datacenter[$($SingleServerName.SubString(0, 2))][0]
|
|
}
|
|
catch
|
|
{
|
|
# If you know the info, please let me know!
|
|
$ObjectRegion = 'Unknown'
|
|
}
|
|
|
|
# This is a bit nasty, but unknown cause errors (null pointer)
|
|
try
|
|
{
|
|
$ObjectLocation = $Datacenter[$($SingleServerName.SubString(0, 2))][1]
|
|
}
|
|
catch
|
|
{
|
|
# If you know the info, please let me know!
|
|
$ObjectLocation = 'Unknown'
|
|
}
|
|
|
|
switch ($ObjectRegion)
|
|
{
|
|
'EUR'
|
|
{
|
|
$ObjectGDPR = $true
|
|
}
|
|
'Unknown'
|
|
{
|
|
# Unknown triggers an internal investigation (find the location Info ASAP)
|
|
$ObjectGDPR = 'Unknown'
|
|
}
|
|
default
|
|
{
|
|
# That triggers an Alarm in my SIEM
|
|
$ObjectGDPR = $false
|
|
}
|
|
}
|
|
|
|
# Keep the object in order!
|
|
$Object = [PSCustomObject][ordered]@{
|
|
ServerName = $SingleServerName
|
|
Location = $ObjectLocation
|
|
Region = $ObjectRegion
|
|
GDPR = $ObjectGDPR
|
|
}
|
|
|
|
# Add to the Output
|
|
$Result.Add($Object)
|
|
|
|
# Cleanup
|
|
$Object = $null
|
|
$ObjectLocation = $null
|
|
$ObjectRegion = $null
|
|
$ObjectGDPR = $null
|
|
}
|
|
}
|
|
|
|
end
|
|
{
|
|
# Dump to the Terminal
|
|
$Result
|
|
|
|
# Cleanup
|
|
$Result = $null
|
|
$Datacenter = $null
|
|
|
|
# Run Garbage Collection
|
|
[gc]::Collect()
|
|
}
|
|
}
|