Skip to content

Instantly share code, notes, and snippets.

@aduzsardi
Created July 25, 2017 07:51
Show Gist options
  • Save aduzsardi/5e358589e025f2c16052aa4600be112b to your computer and use it in GitHub Desktop.
Save aduzsardi/5e358589e025f2c16052aa4600be112b to your computer and use it in GitHub Desktop.
generate dhcp option 119 (DNS Search Suffix) powershell script
# ----------------------------------------------------------------------------------------------------------
# PURPOSE: Creates a byte array for use with DHCP Option 119
#
# VERSION DATE USER DETAILS
# 1 07/03/2016 Craig Tolley First version
# 1.1 08/03/2016 Craig Tolley Fixed issue where if the whole domain matched the pointer was incorrect
# 1.2 08/03/2017 Craig Tolley Fixed further issues where the whole domain was matched the pointers are incorrect
# Modified outputs and tidied some formatting
# Convert-StringToOpt119Hex option fixed to not return values for null/empty strings
#
# http://tools.ietf.org/html/rfc3397
# https://www.craig-tolley.co.uk/2016/03/07/dhcp-option-119-dns-search-suffix-powershell-array-builder/
# ----------------------------------------------------------------------------------------------------------
function Make-HexDomainSearchSuffix
{
Param
(
[Parameter(Mandatory=$true)]
[ValidateNotNullOrEmpty()]
$Domains
)
# Helper function for converting whole strings to byte arrays.
function Convert-StringToOpt119Hex
{
Param (
[String]$SourceText
)
if ($SourceText -eq $null -or $SourceText.Trim().Length -eq 0) { return }
$Hexed = @()
$SourceText.Split(".") | ForEach {
$Hexed += [String]::Format("0x{0:X2}" -f [int]($_.ToCharArray().Count));
$_.ToCharArray() | ForEach {
$Hexed += [String]::Format("0x{00:X2}" -f [int]$_)
};
}
return $Hexed
}
# Build the list of objects that we want to work with.
$DomListInt = @()
ForEach ($Domain in $Domains)
{
$D = New-Object Object
Add-Member -InputObject $D -MemberType NoteProperty -Name "DomainName" -Value $Domain
Add-Member -InputObject $D -MemberType NoteProperty -Name "LinkedDomainIndex" -Value $null
Add-Member -InputObject $D -MemberType NoteProperty -Name "LinkedDomainStartIndex" -Value $null
Add-Member -InputObject $D -MemberType NoteProperty -Name "HexArray" -Value (New-object System.Collections.Arraylist)
Add-Member -InputObject $D -MemberType NoteProperty -Name "HexLength" -Value 0
$DomListInt += $D
}
# Work out if we can have any links
ForEach ($Domain in $DomListInt)
{
Write-Host "Current Domain: $($Domain.DomainName)"
# Ignore the first domain, must be converted in full
$DIndex = $DomListInt.IndexOf($Domain)
if ($DIndex -eq 0)
{
#Write-Output "First Domain"
$Domain.HexArray = Convert-StringToOpt119Hex -SourceText $Domain.DomainName -Pointer $Null
continue
}
$Matched = $false
$c = $($Domain.DomainName.Split(".").Count)
Write-Host "Parts: $c"
for ($i = 0; $i -lt $c; $i++)
{
$DPart = [String]::Join(".", $Domain.DomainName.Split(".")[$i..$c])
Write-Host "Comparing $DPart"
# If the string can be found in a previous domain, then it can be linked.
$PartMatchDomain = ($DomListInt[0..($DIndex-1)] | Where { $_.DomainName -like "*$($DPart)"} | Select -First 1)
if ($PartMatchDomain -ne $null)
{
Write-Host "Found in $($PartMatchDomain.DomainName)"
Write-Host "Match Index: $($PartMatchDomain.DomainName.ToString().IndexOf($DPart))"
$Domain.LinkedDomainIndex = $DomListInt.IndexOf($PartMatchDomain)
$Domain.LinkedDomainStartIndex = $($PartMatchDomain.DomainName.ToString().IndexOf($DPart))
$UniqueParts = if ($i -gt 0) { $([String]::Join(".",$Domain.DomainName.Split(".")[0..($i-1)])) } else { "" }
Write-Host "Unique Parts: $UniqueParts"
$Domain.HexArray += Convert-StringToOpt119Hex -SourceText $UniqueParts
$i = $c # Causes the loop to stop
$Matched = $true
}
}
# If not matched, then the entry needs including in full
if ($Matched -eq $false)
{
$Domain.HexArray = Convert-StringToOpt119Hex -SourceText $Domain.DomainName -Pointer $Null
}
}
# And finally, lets put it all together
$HexOutput = @()
ForEach ($Domain in $DomListInt)
{
$HexOutput += $Domain.HexArray
# If no linked domain, then null terminate
if ($Domain.LinkedDomainIndex -eq $null)
{
$HexOutput += "0x00"
$Domain.HexLength = $Domain.HexArray.Count + 1
}
# If linked domain index = 0 then, the start point is simply the start index
elseif ($Domain.LinkedDomainIndex -eq 0)
{
$HexOutput += "0xC0" # Compression Link
$HexOutput += [String]::Format("0x{0:X2}" -f [int]($Domain.LinkedDomainStartIndex))
$Domain.HexLength = $Domain.HexArray.Count + 2
}
# If linked domain is not 0, then the start index needs to be calculated
else
{
$HexOutput += "0xC0" # Compression Link
$HexOutput += [String]::Format("0x{0:X2}" -f [int](($DomListInt[0..($Domain.LinkedDomainIndex-1)] | Measure -Sum HexLength).Sum + $Domain.LinkedDomainStartIndex))
$Domain.HexLength = $Domain.HexArray.Count + 2
}
}
Write-Output $HexOutput
}
@aduzsardi
Copy link
Author

How to Use It

Copy the entire function into a PowerShell window. This will create the function. Next, use it like this:

Make-HexDomainSearchSuffix -Domains craig-tolley.co.uk, foobar.co.uk

This will then print out a series of hex values ready for entering into the DHCP console.
However, this is still too much work for me, and still subject to errors creeping in. If your DHCP servers are running Windows 2012, then you have the PowerShell DHCP cmdlets at your disposal, and you can push the output straight into the option like this:
Set-DhcpServerv4OptionValue -ScopeId 192.68.10.0 -OptionId 119 -Value (Make-HexDomainSearchSuffix -Domains craig-tolley.co.uk, foobar.co.uk)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment