public/Get-ADSite.ps1

#Requires -Modules ActiveDirectory
<#
.SYNOPSIS
    Module for returning AD Site details.
.DESCRIPTION
    Use this module to perform search of a whole or partial AD site name or subnet
    or to get the AD site of a computer.
.PARAMETER ComputerName
    Enter the full name or IP address of a computer.
.PARAMETER Full
    A switch will return the full AD site info. Used in conjuntion with ComputerName value.
.PARAMETER Name
    This parameter is a full or partial AD site name.
.PARAMETER Subnet
    Enter the first two or three octets of an IP address. Subnets are treated as regular expressions;
    all rules pertaining to regular expressions are in play.
.PARAMETER All
    A switch that will simply get ALL known sites and subnets. This is helpful when assessing large datasets.
    No other parameter will be assessed when this switch is true.
.EXAMPLE
    Get-ADSite -ComputerName "D1233210"

    ComputerName Site
    ------------ ----
    D1233210 Duluth



    Description
    -----------
    Returns the Site of the computer input.
.EXAMPLE
    Get-ADSite -ComputerName "D1233210" -Full

    Site Description Subnet
    ---- ----------- ------
    DULUTH Duluth, GA 11.166.240.0/24, 11.166.244.0/23


    Description
    -----------
    Used only in conjuntion with ComputerName value.
    Use of this switch returns the Site, Description and Subnet(s) of
    the identified AD Site of the computer input.
.EXAMPLE
    Get-ADSite -Name "Duluth"

    Site Description Subnet
    ---- ----------- ------
    DULUTH Duluth, GA 11.166.240.0/24, 11.166.244.0/23


    Description
    -----------
    This example of a full or partial AD site name returns the Site, Description and
    Subnet(s) of locations matching the name input.
.EXAMPLE
    Get-ADSite -Subnet "11.48"

    Site Description Subnet
    ---- ----------- ------
    DULUTH Duluth, GA 11.48.242.0/24
    TAMPA Tampa, FL 11.48.244.0/23


    Description
    -----------
    The example returns all AD Sites matching the IP/subnet input.
.NOTES
     Project: https://github.com/tmknight/TMK-CoreModules
#>


function  Get-ADSite {
    [CmdletBinding(DefaultParametersetName = 'p0')]
    param(
        [Parameter(ParameterSetName = 'p0',
            Mandatory = $true,
            ValueFromPipeline = $true,
            HelpMessage = 'Enter the full name or IP address of a computer',
            Position = 0)]
        [string] $ComputerName,
        [Parameter(ParameterSetName = 'p0',
            Mandatory = $false,
            Position = 2)]
        [switch] $Full,
        [Parameter(ParameterSetName = 'p1',
            Mandatory = $false)]
        [string] $Name,
        [Parameter(ParameterSetName = 'p2',
            Mandatory = $false)]
        [string] $Subnet,
        [Parameter(ParameterSetName = 'p3',
            HelpMessage = 'A switch that will simply get ALL known sites and subnets. No other parameter will be assessed',
            Mandatory = $false)]
        [switch] $All
    )

    begin {
        $ErrorActionPreference = 'Stop'

        if ($All) {
            ## A switch that will simply get ALL known sites and subnets. No other parameter will be assessed
        }
        elseif (($Name -and $Subnet -and $ComputerName) -or ($Name -and ($Subnet -or $ComputerName)) -or ($Subnet -and $ComputerName)) {
            Write-Error -Message 'Please enter only one of an AD Site Name, a portion of the subnet address or a computer name. Using more than one parameter is not supported at this time.' -Category InvalidArgument
            break
        }
        elseif ($Subnet -match '[a-zA-Z]') {
            Write-Error -Message 'Please enter a full or partial subnet address in the form of dotted decimal-numbers' -Category InvalidArgument
            break
        }
        elseif ($Name -match '^\d{1,3}.*\d{1,3}?') {
            Write-Error -Message 'Please enter a valid AD Site Name' -Category InvalidArgument
            break
        }
        elseif (!($Name -or $Subnet -or $ComputerName)) {
            Write-Error -Message 'Please enter one of an AD Site Name, a portion of the subnet address or a computer name' -Category InvalidArgument
            break
        }
    }
    process {
        ## get AD site of a specific computer
        switch ($PsCmdlet.ParameterSetName) {
            'p0' {
                try {
                    if ($ComputerName -eq $env:COMPUTERNAME) {
                        $cn = '.'
                    }
                    else {
                        $cn = $ComputerName
                    }
                    $siteName = (Get-CimInstance -ComputerName $cn -ClassName Win32_NTDomain | Where-Object { $Domain -Match $_.DomainName -and $null -ne $_.ClientSiteName }).ClientSiteName
                }
                catch {
                    $siteName = ($_.Exception).Message
                }

                if ($siteName -eq $err -or ($siteName -and $Full -ne $true)) {
                    $result = [PSCustomObject] @{
                        ComputerName = $ComputerName
                        Site         = $siteName
                    }
                }
                elseif ($siteName -ne $err -and $Full) {
                    $Name = $siteName
                    $site = Get-ADReplicationSite -Identity $Name
                    $subs = Get-ADReplicationSubnet -Filter "Site -eq '$($site.DistinguishedName)'"
                    $result = [PSCustomObject]@{
                        Site        = $site.Name
                        Description = $site.Description
                        Subnet      = $subs.Name -join '; '
                    }
                }
            }
            'p1' {
                $site = Get-ADReplicationSite -Identity $Name
                $subs = Get-ADReplicationSubnet -Filter "Site -eq '$($site.DistinguishedName)'"
                $result = [PSCustomObject]@{
                    Site        = $site.Name
                    Description = $site.Description
                    Subnet      = $subs.Name -join '; '
                }
            }
            'p2' {
                $result = @()
                $subs = Get-ADReplicationSubnet -Filter "Name -like '$Subnet*'"
                foreach ($item in $subs) {
                    $site = Get-ADReplicationSite -Filter * | Where-Object DistinguishedName -EQ "$($item.site)"
                    $result += [PSCustomObject]@{
                        Site        = $site.Name
                        Description = $site.Description
                        Subnet      = $item.Name -join '; '
                    }
                }

            }
            'p3' {
                $result = @()
                $site = Get-ADReplicationSite -Filter *
                foreach ($item in $site) {
                    $subs = Get-ADReplicationSubnet -Filter "Site -eq '$($item.DistinguishedName)'"
                    $result += [PSCustomObject]@{
                        Site        = $item.Name
                        Description = $item.Description
                        Subnet      = $subs.Name -join '; '
                    }
                }
            }
        }
    }
    end {
        if ($result) {
            return $result
        }
        else {
            Write-Warning -Message "There are no objects matching $ComputerName$Name$Subnet"
        }
    }
}