Dns.psm1

[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
    'PSAvoidAssignmentToAutomaticVariable', 'IsWindows',
    Justification = 'IsWindows doesnt exist in PS5.1'
)]
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
    'PSUseDeclaredVarsMoreThanAssignments', 'IsWindows',
    Justification = 'IsWindows doesnt exist in PS5.1'
)]
[CmdletBinding()]
param()
$baseName = [System.IO.Path]::GetFileNameWithoutExtension($PSCommandPath)
$script:PSModuleInfo = Import-PowerShellDataFile -Path "$PSScriptRoot\$baseName.psd1"
$script:PSModuleInfo | Format-List | Out-String -Stream | ForEach-Object { Write-Debug $_ }
$scriptName = $script:PSModuleInfo.Name
Write-Debug "[$scriptName] - Importing module"

if ($PSEdition -eq 'Desktop') {
    $IsWindows = $true
}

#region [classes] - [public]
Write-Debug "[$scriptName] - [classes] - [public] - Processing folder"
#region [classes] - [public] - [DnsHost]
Write-Debug "[$scriptName] - [classes] - [public] - [DnsHost] - Importing"
class DnsHost {
    [string]$Name
    [string]$Alias
    [string[]]$AddressList

    DnsHost() {}

    DnsHost([string]$Name, [string]$Alias, [string[]]$AddressList) {
        $this.Name = $Name
        $this.Alias = $Alias
        $this.AddressList = $AddressList
    }
}
Write-Debug "[$scriptName] - [classes] - [public] - [DnsHost] - Done"
#endregion [classes] - [public] - [DnsHost]
Write-Debug "[$scriptName] - [classes] - [public] - Done"
#endregion [classes] - [public]
#region [functions] - [public]
Write-Debug "[$scriptName] - [functions] - [public] - Processing folder"
#region [functions] - [public] - [Resolve-DnsHost]
Write-Debug "[$scriptName] - [functions] - [public] - [Resolve-DnsHost] - Importing"
function Resolve-DnsHost {
    <#
        .SYNOPSIS
        Resolves a hostname to an IP address.

        .DESCRIPTION
        This function resolves a hostname to an IP address using the System.Net.Dns class.

        .EXAMPLE
        Resolve-DnsHost -HostName 'google.com'

        .OUTPUTS
        [DnsHost]
    #>

    [OutputType([DnsHost])]
    [CmdletBinding()]
    param (
        # The name of the host to resolve
        [Parameter(Mandatory)]
        [string] $Name,

        # The address family to use for the DNS resolution
        [Parameter()]
        [System.Net.Sockets.AddressFamily] $AddressFamily = 'Unspecified'
    )

    try {
        $entry = [System.Net.Dns]::GetHostEntry($Name, $AddressFamily)
        return [DnsHost]::new($entry.HostName, $entry.Aliases, $entry.AddressList)
    } catch {
        Write-Debug "Failed to resolve DNS for [$Name]"
        Write-Debug $_
    }
}
Write-Debug "[$scriptName] - [functions] - [public] - [Resolve-DnsHost] - Done"
#endregion [functions] - [public] - [Resolve-DnsHost]
Write-Debug "[$scriptName] - [functions] - [public] - Done"
#endregion [functions] - [public]
#region Class exporter
# Get the internal TypeAccelerators class to use its static methods.
$TypeAcceleratorsClass = [psobject].Assembly.GetType(
    'System.Management.Automation.TypeAccelerators'
)
# Ensure none of the types would clobber an existing type accelerator.
# If a type accelerator with the same name exists, throw an exception.
$ExistingTypeAccelerators = $TypeAcceleratorsClass::Get
# Define the types to export with type accelerators.
$ExportableEnums = @(
)
$ExportableEnums | Foreach-Object { Write-Verbose "Exporting enum '$($_.FullName)'." }
foreach ($Type in $ExportableEnums) {
    if ($Type.FullName -in $ExistingTypeAccelerators.Keys) {
        Write-Verbose "Enum already exists [$($Type.FullName)]. Skipping."
    } else {
        Write-Verbose "Importing enum '$Type'."
        $TypeAcceleratorsClass::Add($Type.FullName, $Type)
    }
}
$ExportableClasses = @(
    [DnsHost]
)
$ExportableClasses | Foreach-Object { Write-Verbose "Exporting class '$($_.FullName)'." }
foreach ($Type in $ExportableClasses) {
    if ($Type.FullName -in $ExistingTypeAccelerators.Keys) {
        Write-Verbose "Class already exists [$($Type.FullName)]. Skipping."
    } else {
        Write-Verbose "Importing class '$Type'."
        $TypeAcceleratorsClass::Add($Type.FullName, $Type)
    }
}

# Remove type accelerators when the module is removed.
$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = {
    foreach ($Type in ($ExportableEnums + $ExportableClasses)) {
        $null = $TypeAcceleratorsClass::Remove($Type.FullName)
    }
}.GetNewClosure()
#endregion Class exporter
#region Member exporter
$exports = @{
    Alias    = '*'
    Cmdlet   = ''
    Function = 'Resolve-DnsHost'
    Variable = ''
}
Export-ModuleMember @exports
#endregion Member exporter