Skip to content

Instantly share code, notes, and snippets.

@thedavecarroll
Last active May 29, 2021 14:34
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save thedavecarroll/0024d27e05e95800656b080d7c84f96d to your computer and use it in GitHub Desktop.
Save thedavecarroll/0024d27e05e95800656b080d7c84f96d to your computer and use it in GitHub Desktop.
Get IANA Port Number Registry
function Get-IanaPortNumberRegistry {
[CmdLetBinding()]
param(
[ValidateSet('TCP','UDP','SCTP','DCCP')]
[string[]]$Protocol,
[ValidateRange(0,65535)]
[int[]]$PortNumber,
[string]$ServiceName,
[switch]$RefreshCache,
[string]$AlternatePath
)
function Invoke-DownloadIanaPortNumberRegistry {
[CmdLetBinding()]
param($OutFile)
$InvokeWebRequestParams = @{
Uri = 'https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml'
OutFile = $OutFile
ErrorAction = 'Stop'
Verbose = $false
}
try {
Invoke-WebRequest @InvokeWebRequestParams | Out-Null
}
catch {
$PSCmdlet.ThrowTerminatingError($_)
}
}
if ($PSBoundParameters.ContainsKey('AlternatePath') -and $PSBoundParameters.ContainsKey('RefreshCache')) {
$Action = 'SetAlternatePath','Download','ReadCache'
} elseif ($PSBoundParameters.ContainsKey('RefreshCache') -and -Not $PSBoundParameters.ContainsKey('AlternatePath') ) {
$Action = 'SetPath','Download','ReadCache'
} elseif ($PSBoundParameters.ContainsKey('AlternatePath') -and -Not $PSBoundParameters.ContainsKey('RefreshCache') ) {
$Action = 'SetAlternatePath','ReadCache'
} elseif (Get-Variable -Name IanaRegistryCache -Scope Global -ErrorAction SilentlyContinue) {
$Action = 'SetPath','ReadCache'
} else {
$Action = 'SetPath','Download','ReadCache'
}
'Performing the following actions : {0}' -f ($Action -join ', ') | Write-Verbose
switch ($Action) {
'SetPath' {
if (Get-Variable -Name IanaRegistryCache -Scope Global -ErrorAction SilentlyContinue) {
if ($global:IanaRegistryCache -eq (Join-Path -Path $env:TEMP -ChildPath 'IanaRegistryCache.xml')) {
'Existing IanaRegistryCache path : {0}' -f $global:IanaRegistryCache | Write-Verbose
} else {
$global:IanaRegistryCache = Join-Path -Path $env:TEMP -ChildPath 'IanaRegistryCache.xml'
'User TEMP IanaRegistryCache path updated: {0}' -f $global:IanaRegistryCache | Write-Verbose
}
} else {
if (Test-Path -Path $env:TEMP) {
$global:IanaRegistryCache = Join-Path -Path $env:TEMP -ChildPath 'IanaRegistryCache.xml'
'User TEMP IanaRegistryCache path : {0}' -f $global:IanaRegistryCache | Write-Verbose
} else {
$global:IanaRegistryCache = Resolve-Path -Path '.\IanaRegistryCache.xml'
'Current folder IanaRegistryCache path : {0}' -f $global:IanaRegistryCache | Write-Verbose
}
}
continue
}
'SetAlternatePath' {
if (Get-Variable -Name IanaRegistryCache -Scope Global -ErrorAction SilentlyContinue) {
if ($global:IanaRegistryCache -eq (Resolve-Path -Path $AlternatePath)) {
'Existing IanaRegistryCache path : {0}' -f $global:IanaRegistryCache | Write-Verbose
} else {
$global:IanaRegistryCache = Resolve-Path -Path $AlternatePath
'Alternate IanaRegistryCache path updated : {0}' -f $global:IanaRegistryCache | Write-Verbose
}
} else {
$global:IanaRegistryCache = Resolve-Path -Path $AlternatePath
'Alternate IanaRegistryCache path : {0}' -f $global:IanaRegistryCache | Write-Verbose
}
continue
}
'Download' {
try {
Invoke-DownloadIanaPortNumberRegistry -OutFile $global:IanaRegistryCache -ErrorAction Stop
'Downloaded IANA Port Number Registry' | Write-Verbose
continue
}
catch {
'Unable to download. Removing IanaRegistryCache variable' | Write-Warning
Remove-Variable -Name IanaRegistryCache -Scope Global | Out-Null
return
}
}
'ReadCache' {
try {
[xml]$IanaPortNumberRegistry = Get-Content -Path $global:IanaRegistryCache -Raw -ErrorAction Stop
'Read Port Number Registry cache' | Write-Verbose
}
catch {
'Unable to read file; attempting to download' | Write-Warning
try {
Invoke-DownloadIanaPortNumberRegistry -OutFile $global:IanaRegistryCache -ErrorAction Stop
'Second attempt to download IANA Port Number Registry succeeded' | Write-Verbose
[xml]$IanaPortNumberRegistry = Get-Content -Path $global:IanaRegistryCache -Raw -ErrorAction Stop
'Read IANA Port Number Registry' | Write-Verbose
}
catch {
'Unable to download; removing IanaRegistryCache variable' | Write-Warning
Remove-Variable -Name IanaRegistryCache -Scope Global | Out-Null
return
}
}
}
}
$Format = @{l='Protocol';e={$_.protocol.ToUpper()}},
@{l='PortNumber';e={if ($_.number -like '*-*') { [int]::Parse($_.number.Split('-')[0])..[int]::Parse($_.number.Split('-')[1]) } else {$_.number} }},
@{l='ServiceName';e={$_.description}}
$Filter = @()
if ($Protocol) {
$ProtocolFilter = @()
foreach ($Transport in $Protocol) {
$ProtocolFilter += '$_.Protocol -eq "{0}"' -f $Transport.ToLower()
}
$Filter += '(' + ($ProtocolFilter -join ' -or ') + ')'
}
if ($PortNumber) {
$PortFilter = @()
foreach ($Number in $PortNumber) {
$PortFilter += '{0} -in $_.PortNumber' -f $Number
}
$Filter += '(' + ($PortFilter -join ' -or ') + ')'
}
if ($ServiceName) {
$Filter += '$_.ServiceName -match "{0}"' -f $ServiceName
}
$FilterString = $Filter -join ' -and '
if ($Filter.count -gt 0) {
[scriptblock]$FilterScript = [scriptblock]::Create($FilterString)
}
$CacheDate = Get-ChildItem -Path $global:IanaRegistryCache
$DisplayInformation = [PsCustomObject]@{
Title = $IanaPortNumberRegistry.registry.title
XmlUpdated = $IanaPortNumberRegistry.registry.updated
Downloaded = $CacheDate.LastWriteTime
IanaRegistryCachePath = $global:IanaRegistryCache
Records = $IanaPortNumberRegistry.registry.record.count
}
Write-Information -MessageData $DisplayInformation
if ($FilterScript) {
'Search string: {0}' -f $FilterScript | Write-Verbose
$IanaPortNumberRegistry.registry.record |
Select-Object $Format |
Where-Object -FilterScript $FilterScript |
Select-Object -Property Protocol,PortNumber,ServiceName -Unique
} else {
'Retrieving all records' | Write-Verbose
$IanaPortNumberRegistry.registry.record |
Select-Object $Format
}
<#
.SYNOPSIS
The command retrieves the IANA Port Number Registry entries using the
provided filter parameters.
.DESCRIPTION
The command retrieves the IANA Port Number Registry entries using the
provided filter parameters.
The IANA Port Number Registry is available as an XML file.
This command uses a global variable to store the path for the last
downloaded XML file to prevent numerous downloads.
.PARAMETER Protocol
The Protocol parameter will be used to filter the results.
.PARAMETER PortNumber
The PortNumber parameter will be used to filter the results.
.PARAMETER ServiceName
The ServiceName parameter will be used to filter the results.
.PARAMETER RefreshCache
The RefreshCache parameter forces the command to download the registry xml
even if the registry is cached.
.PARAMETER AlternatePath
The AlternatePath parameter instructs the command to download to a different
path. By default, this file is downloaded to the user's TEMP folder.
.EXAMPLE
PS > $IanaRegistry = Get-IanaPortNumberRegistry
Retrieves the entire port number registry into a variable.
Note: On subsequent runs, this will read the registry from the cache.
.EXAMPLE
PS > Get-IanaPortNumberRegistry -Protocol TCP -PortNumber 25,110
Protocol PortNumber ServiceName
-------- ---------- -----------
TCP 25 Simple Mail Transfer
TCP 110 Post Office Protocol - Version 3
TCP 143 Internet Message Access Protocol
TCP 465 URL Rendezvous Directory for SSM
TCP 465 Message Submission over TLS protocol
TCP 993 IMAP over TLS protocol
TCP 995 POP3 over TLS protocol
Filters the cached registry for SMTP, POP, and IMAP entries.
.EXAMPLE
PS > $UpdateRegistry = Get-IanaPortNumberRegistry -RefreshCache -InformationVariable MyInfo
PS > $Myinfo.MessageData
Title : Service Name and Transport Protocol Port Number Registry
XmlUpdated : 2019-11-25
Downloaded : 11/30/2019 7:30:10 PM
IanaRegistryCachePath : C:\Users\Dave\AppData\Local\Temp\IanaRegistryCache.xml
Records : 14170
Forces a refresh of the cache by downloading the XML again.
This example also shows key information that is sent to the information stream.
.INPUTS
None
.OUTPUTS
PsCustomObject[]
.LINK
https://gist.github.com/thedavecarroll/0024d27e05e95800656b080d7c84f96d
.LINK
https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml
.LINK
https://www.iana.org
#>
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment