Add cartographer.ps1
This commit is contained in:
316
cartographer.ps1
Normal file
316
cartographer.ps1
Normal file
@@ -0,0 +1,316 @@
|
||||
# Cartographer - DNS Record Mapping Tool with GUI - Map - IP to DNS record based on subnet
|
||||
# Import required assemblies for GUI
|
||||
Add-Type -AssemblyName System.Windows.Forms
|
||||
Add-Type -AssemblyName System.Drawing
|
||||
|
||||
# Convert IP addresses to integers for comparison
|
||||
function Convert-IPToInt {
|
||||
param (
|
||||
[string]$IPAddress
|
||||
)
|
||||
[array]$octets = $IPAddress.Split('.')
|
||||
return [int]($octets[0]) * 16777216 + [int]($octets[1]) * 65536 + [int]($octets[2]) * 256 + [int]($octets[3])
|
||||
}
|
||||
|
||||
# Convert integer back to IP address
|
||||
function Convert-IntToIP {
|
||||
param (
|
||||
[int64]$Integer
|
||||
)
|
||||
$octet1 = [Math]::Floor($Integer / 16777216)
|
||||
$remainder = $Integer % 16777216
|
||||
$octet2 = [Math]::Floor($remainder / 65536)
|
||||
$remainder = $remainder % 65536
|
||||
$octet3 = [Math]::Floor($remainder / 256)
|
||||
$octet4 = $remainder % 256
|
||||
return "$octet1.$octet2.$octet3.$octet4"
|
||||
}
|
||||
|
||||
# Get subnet range based on IP and mask
|
||||
function Get-SubnetRange {
|
||||
param (
|
||||
[string]$IPAddress
|
||||
)
|
||||
|
||||
# Assuming /24 subnet
|
||||
$octets = $IPAddress.Split('.')
|
||||
$networkPrefix = "$($octets[0]).$($octets[1]).$($octets[2])"
|
||||
$rangeStart = "$networkPrefix.1"
|
||||
$rangeEnd = "$networkPrefix.254"
|
||||
|
||||
return @{
|
||||
Start = $rangeStart
|
||||
End = $rangeEnd
|
||||
}
|
||||
}
|
||||
|
||||
# Get available DNS servers
|
||||
function Get-AvailableDnsServers {
|
||||
# $dnsServers = @("localhost")
|
||||
|
||||
$clientDnsServers = Get-DnsClientServerAddress |
|
||||
Where-Object { $_.ServerAddresses -ne $null } |
|
||||
ForEach-Object {
|
||||
$_.ServerAddresses | Where-Object { $_ -match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$' }
|
||||
} |
|
||||
Select-Object -Unique
|
||||
|
||||
$dnsServers += $clientDnsServers
|
||||
|
||||
# Try to add domain controllers if we're in a domain environment
|
||||
try {
|
||||
$domainControllers = Get-ADDomainController -Filter * |
|
||||
ForEach-Object { $_.HostName }
|
||||
$dnsServers += $domainControllers
|
||||
} catch {
|
||||
# Not in a domain environment or AD module not available, continue without it
|
||||
}
|
||||
|
||||
return $dnsServers | Select-Object -Unique
|
||||
}
|
||||
|
||||
# Query DNS for records
|
||||
function Search-DnsRecords {
|
||||
param (
|
||||
[string]$DnsServer,
|
||||
[string]$IPRangeStart,
|
||||
[string]$IPRangeEnd
|
||||
)
|
||||
|
||||
$StartInt = Convert-IPToInt $IPRangeStart
|
||||
$EndInt = Convert-IPToInt $IPRangeEnd
|
||||
|
||||
$Results = @()
|
||||
|
||||
try {
|
||||
$Zones = Get-DnsServerZone -ComputerName $DnsServer -ErrorAction Stop
|
||||
|
||||
foreach ($Zone in $Zones) {
|
||||
$Records = Get-DnsServerResourceRecord -ZoneName $Zone.ZoneName -ComputerName $DnsServer -ErrorAction SilentlyContinue
|
||||
foreach ($Record in $Records) {
|
||||
if ($Record.RecordType -eq "A") {
|
||||
$IPInt = Convert-IPToInt $Record.RecordData.IPv4Address.ToString()
|
||||
if ($IPInt -ge $StartInt -and $IPInt -le $EndInt) {
|
||||
$Results += [PSCustomObject]@{
|
||||
IPAddress = $Record.RecordData.IPv4Address
|
||||
Hostname = $Record.HostName
|
||||
Zone = $Zone.ZoneName
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} catch {
|
||||
[System.Windows.Forms.MessageBox]::Show("Error querying DNS server: $_", "Error", [System.Windows.Forms.MessageBoxButtons]::OK, [System.Windows.Forms.MessageBoxIcon]::Error)
|
||||
}
|
||||
|
||||
return $Results
|
||||
}
|
||||
|
||||
# Create the main form
|
||||
$form = New-Object System.Windows.Forms.Form
|
||||
$form.Text = "Cartographer - DNS Record Mapping Tool"
|
||||
$form.Size = New-Object System.Drawing.Size(800, 600)
|
||||
$form.StartPosition = "CenterScreen"
|
||||
$form.FormBorderStyle = [System.Windows.Forms.FormBorderStyle]::FixedDialog
|
||||
$form.MaximizeBox = $false
|
||||
|
||||
# DNS Server selection
|
||||
$dnsServerLabel = New-Object System.Windows.Forms.Label
|
||||
$dnsServerLabel.Text = "DNS Server:"
|
||||
$dnsServerLabel.Location = New-Object System.Drawing.Point(20, 20)
|
||||
$dnsServerLabel.Size = New-Object System.Drawing.Size(100, 20)
|
||||
$form.Controls.Add($dnsServerLabel)
|
||||
|
||||
$dnsServerComboBox = New-Object System.Windows.Forms.ComboBox
|
||||
$dnsServerComboBox.Location = New-Object System.Drawing.Point(130, 20)
|
||||
$dnsServerComboBox.Size = New-Object System.Drawing.Size(200, 20)
|
||||
$dnsServerComboBox.DropDownStyle = [System.Windows.Forms.ComboBoxStyle]::DropDownList
|
||||
$form.Controls.Add($dnsServerComboBox)
|
||||
|
||||
# Populate DNS Server dropdown
|
||||
$dnsServers = Get-AvailableDnsServers
|
||||
foreach ($server in $dnsServers) {
|
||||
$dnsServerComboBox.Items.Add($server)
|
||||
}
|
||||
if ($dnsServerComboBox.Items.Count -gt 0) {
|
||||
$dnsServerComboBox.SelectedIndex = 0
|
||||
}
|
||||
|
||||
# IP Range Selection Group
|
||||
$ipRangeGroupBox = New-Object System.Windows.Forms.GroupBox
|
||||
$ipRangeGroupBox.Text = "IP Range Selection"
|
||||
$ipRangeGroupBox.Location = New-Object System.Drawing.Point(20, 50)
|
||||
$ipRangeGroupBox.Size = New-Object System.Drawing.Size(750, 120)
|
||||
$form.Controls.Add($ipRangeGroupBox)
|
||||
|
||||
# Radio buttons for range selection
|
||||
$subnetRadioButton = New-Object System.Windows.Forms.RadioButton
|
||||
$subnetRadioButton.Text = "Scan Full /24 Subnet"
|
||||
$subnetRadioButton.Location = New-Object System.Drawing.Point(20, 20)
|
||||
$subnetRadioButton.Size = New-Object System.Drawing.Size(150, 20)
|
||||
$subnetRadioButton.Checked = $true
|
||||
$ipRangeGroupBox.Controls.Add($subnetRadioButton)
|
||||
|
||||
$customRangeRadioButton = New-Object System.Windows.Forms.RadioButton
|
||||
$customRangeRadioButton.Text = "Custom IP Range"
|
||||
$customRangeRadioButton.Location = New-Object System.Drawing.Point(20, 50)
|
||||
$customRangeRadioButton.Size = New-Object System.Drawing.Size(150, 20)
|
||||
$ipRangeGroupBox.Controls.Add($customRangeRadioButton)
|
||||
|
||||
# Subnet IP entry
|
||||
$subnetIPLabel = New-Object System.Windows.Forms.Label
|
||||
$subnetIPLabel.Text = "Subnet IP Address:"
|
||||
$subnetIPLabel.Location = New-Object System.Drawing.Point(180, 20)
|
||||
$subnetIPLabel.Size = New-Object System.Drawing.Size(120, 20)
|
||||
$ipRangeGroupBox.Controls.Add($subnetIPLabel)
|
||||
|
||||
$subnetIPTextBox = New-Object System.Windows.Forms.TextBox
|
||||
$subnetIPTextBox.Location = New-Object System.Drawing.Point(300, 20)
|
||||
$subnetIPTextBox.Size = New-Object System.Drawing.Size(150, 20)
|
||||
$subnetIPTextBox.Text = "192.168.1.1"
|
||||
$ipRangeGroupBox.Controls.Add($subnetIPTextBox)
|
||||
|
||||
# Custom range IP entries
|
||||
$startIPLabel = New-Object System.Windows.Forms.Label
|
||||
$startIPLabel.Text = "Start IP Address:"
|
||||
$startIPLabel.Location = New-Object System.Drawing.Point(180, 50)
|
||||
$startIPLabel.Size = New-Object System.Drawing.Size(120, 20)
|
||||
$ipRangeGroupBox.Controls.Add($startIPLabel)
|
||||
|
||||
$startIPTextBox = New-Object System.Windows.Forms.TextBox
|
||||
$startIPTextBox.Location = New-Object System.Drawing.Point(300, 50)
|
||||
$startIPTextBox.Size = New-Object System.Drawing.Size(150, 20)
|
||||
$startIPTextBox.Text = "192.168.1.1"
|
||||
$startIPTextBox.Enabled = $false
|
||||
$ipRangeGroupBox.Controls.Add($startIPTextBox)
|
||||
|
||||
$endIPLabel = New-Object System.Windows.Forms.Label
|
||||
$endIPLabel.Text = "End IP Address:"
|
||||
$endIPLabel.Location = New-Object System.Drawing.Point(460, 50)
|
||||
$endIPLabel.Size = New-Object System.Drawing.Size(120, 20)
|
||||
$ipRangeGroupBox.Controls.Add($endIPLabel)
|
||||
|
||||
$endIPTextBox = New-Object System.Windows.Forms.TextBox
|
||||
$endIPTextBox.Location = New-Object System.Drawing.Point(580, 50)
|
||||
$endIPTextBox.Size = New-Object System.Drawing.Size(150, 20)
|
||||
$endIPTextBox.Text = "192.168.1.254"
|
||||
$endIPTextBox.Enabled = $false
|
||||
$ipRangeGroupBox.Controls.Add($endIPTextBox)
|
||||
|
||||
# Radio button event handlers
|
||||
$subnetRadioButton.Add_CheckedChanged({
|
||||
if ($subnetRadioButton.Checked) {
|
||||
$subnetIPTextBox.Enabled = $true
|
||||
$startIPTextBox.Enabled = $false
|
||||
$endIPTextBox.Enabled = $false
|
||||
}
|
||||
})
|
||||
|
||||
$customRangeRadioButton.Add_CheckedChanged({
|
||||
if ($customRangeRadioButton.Checked) {
|
||||
$subnetIPTextBox.Enabled = $false
|
||||
$startIPTextBox.Enabled = $true
|
||||
$endIPTextBox.Enabled = $true
|
||||
}
|
||||
})
|
||||
|
||||
# Auto-calculate subnet range from subnet IP
|
||||
$subnetIPTextBox.Add_TextChanged({
|
||||
if ($subnetRadioButton.Checked -and $subnetIPTextBox.Text -match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$') {
|
||||
$range = Get-SubnetRange -IPAddress $subnetIPTextBox.Text
|
||||
$startIPTextBox.Text = $range.Start
|
||||
$endIPTextBox.Text = $range.End
|
||||
}
|
||||
})
|
||||
|
||||
# Search Button
|
||||
$searchButton = New-Object System.Windows.Forms.Button
|
||||
$searchButton.Text = "Search DNS Records"
|
||||
$searchButton.Location = New-Object System.Drawing.Point(20, 180)
|
||||
$searchButton.Size = New-Object System.Drawing.Size(150, 30)
|
||||
$form.Controls.Add($searchButton)
|
||||
|
||||
# Status Label
|
||||
$statusLabel = New-Object System.Windows.Forms.Label
|
||||
$statusLabel.Text = "Ready"
|
||||
$statusLabel.Location = New-Object System.Drawing.Point(180, 185)
|
||||
$statusLabel.Size = New-Object System.Drawing.Size(590, 20)
|
||||
$form.Controls.Add($statusLabel)
|
||||
|
||||
# Results DataGridView
|
||||
$resultsDataGridView = New-Object System.Windows.Forms.DataGridView
|
||||
$resultsDataGridView.Location = New-Object System.Drawing.Point(20, 220)
|
||||
$resultsDataGridView.Size = New-Object System.Drawing.Size(750, 300)
|
||||
$resultsDataGridView.AutoSizeColumnsMode = [System.Windows.Forms.DataGridViewAutoSizeColumnsMode]::Fill
|
||||
$resultsDataGridView.AllowUserToAddRows = $false
|
||||
$resultsDataGridView.AllowUserToDeleteRows = $false
|
||||
$resultsDataGridView.ReadOnly = $true
|
||||
$resultsDataGridView.MultiSelect = $false
|
||||
$resultsDataGridView.SelectionMode = [System.Windows.Forms.DataGridViewSelectionMode]::FullRowSelect
|
||||
$form.Controls.Add($resultsDataGridView)
|
||||
|
||||
# Export Button
|
||||
$exportButton = New-Object System.Windows.Forms.Button
|
||||
$exportButton.Text = "Export Results"
|
||||
$exportButton.Location = New-Object System.Drawing.Point(20, 530)
|
||||
$exportButton.Size = New-Object System.Drawing.Size(120, 30)
|
||||
$exportButton.Enabled = $false
|
||||
$form.Controls.Add($exportButton)
|
||||
|
||||
# Search button click event
|
||||
$searchButton.Add_Click({
|
||||
$statusLabel.Text = "Searching DNS records..."
|
||||
$resultsDataGridView.DataSource = $null
|
||||
$exportButton.Enabled = $false
|
||||
|
||||
$selectedDnsServer = $dnsServerComboBox.SelectedItem.ToString()
|
||||
|
||||
$ipRangeStart = ""
|
||||
$ipRangeEnd = ""
|
||||
|
||||
if ($subnetRadioButton.Checked) {
|
||||
$range = Get-SubnetRange -IPAddress $subnetIPTextBox.Text
|
||||
$ipRangeStart = $range.Start
|
||||
$ipRangeEnd = $range.End
|
||||
} else {
|
||||
$ipRangeStart = $startIPTextBox.Text
|
||||
$ipRangeEnd = $endIPTextBox.Text
|
||||
}
|
||||
|
||||
$results = Search-DnsRecords -DnsServer $selectedDnsServer -IPRangeStart $ipRangeStart -IPRangeEnd $ipRangeEnd
|
||||
|
||||
if ($results.Count -gt 0) {
|
||||
$dataTable = New-Object System.Data.DataTable
|
||||
$dataTable.Columns.Add("IPAddress", [string])
|
||||
$dataTable.Columns.Add("Hostname", [string])
|
||||
$dataTable.Columns.Add("Zone", [string])
|
||||
|
||||
foreach ($result in $results) {
|
||||
$dataTable.Rows.Add($result.IPAddress.ToString(), $result.Hostname, $result.Zone)
|
||||
}
|
||||
|
||||
$resultsDataGridView.DataSource = $dataTable
|
||||
$statusLabel.Text = "Found $($results.Count) DNS records"
|
||||
$exportButton.Enabled = $true
|
||||
} else {
|
||||
$statusLabel.Text = "No DNS records found in the specified range"
|
||||
}
|
||||
})
|
||||
|
||||
# Export button click event
|
||||
$exportButton.Add_Click({
|
||||
$saveFileDialog = New-Object System.Windows.Forms.SaveFileDialog
|
||||
$saveFileDialog.Filter = "CSV Files (*.csv)|*.csv|All Files (*.*)|*.*"
|
||||
$saveFileDialog.Title = "Export DNS Records"
|
||||
$saveFileDialog.FileName = "DNSRecords_$(Get-Date -Format 'yyyyMMdd_HHmmss').csv"
|
||||
|
||||
if ($saveFileDialog.ShowDialog() -eq [System.Windows.Forms.DialogResult]::OK) {
|
||||
$dataTable = $resultsDataGridView.DataSource
|
||||
$dataTable | Export-Csv -Path $saveFileDialog.FileName -NoTypeInformation
|
||||
$statusLabel.Text = "Exported to $($saveFileDialog.FileName)"
|
||||
}
|
||||
})
|
||||
|
||||
# Show the form
|
||||
[void]$form.ShowDialog()
|
||||
Reference in New Issue
Block a user