Add Network Adapter Configuration Tool and Presets Management
- Created NetworkAdapter.psm1 module for managing network adapters. - Implemented functions for displaying adapter information, setting DHCP/manual configurations, and managing DNS settings. - Added functionality to save and load network presets in JSON format. - Introduced a schema for validating the presets structure. - Added a .gitignore file to exclude local network presets from version control. - Created a test-syntax.ps1 script to validate PowerShell syntax for the main script files.
This commit is contained in:
parent
905789c3ad
commit
d006870d96
5 changed files with 842 additions and 461 deletions
778
NetworkAdapter.psm1
Normal file
778
NetworkAdapter.psm1
Normal file
|
|
@ -0,0 +1,778 @@
|
|||
function Show-Header {
|
||||
Clear-Host
|
||||
Write-Host "============================================" -ForegroundColor Cyan
|
||||
Write-Host " Network Adapter Configuration Tool" -ForegroundColor Cyan
|
||||
Write-Host "============================================" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
}
|
||||
|
||||
function Get-AdapterChoice {
|
||||
Show-Header
|
||||
Write-Host "Available Network Adapters:" -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
|
||||
while ($true) {
|
||||
$adapters = Get-NetAdapter | Where-Object { $_.Status -ne 'Disabled' }
|
||||
|
||||
if ($adapters.Count -eq 0) {
|
||||
Write-Host "No active network adapters found!" -ForegroundColor Red
|
||||
Read-Host "Press Enter to exit"
|
||||
exit
|
||||
}
|
||||
|
||||
$index = 1
|
||||
foreach ($adapter in $adapters) {
|
||||
$status = if ($adapter.Status -eq 'Up') {
|
||||
"[CONNECTED]"
|
||||
} else {
|
||||
"[" + $adapter.Status.ToUpper() + "]"
|
||||
}
|
||||
|
||||
# Get IP address
|
||||
$ipv4 = Get-NetIPAddress -InterfaceIndex $adapter.InterfaceIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue
|
||||
$ipAddress = if ($ipv4) { $ipv4.IPAddress } else { "No IP" }
|
||||
|
||||
# Get MAC address in both formats
|
||||
$macWindows = $adapter.MacAddress
|
||||
$macLinux = $macWindows -replace '-', ':'
|
||||
|
||||
Write-Host "$index. $($adapter.Name)" -ForegroundColor White
|
||||
|
||||
# Colored description + status
|
||||
$statusLabel = if ($adapter.Status -eq 'Up') { 'CONNECTED' } else { $adapter.Status.ToUpper() }
|
||||
if ($adapter.Status -eq 'Up') { $statusColor = 'Green' }
|
||||
elseif ($adapter.Status -in @('Down','NotPresent','Not Present')) { $statusColor = 'Red' }
|
||||
else { $statusColor = 'Yellow' }
|
||||
|
||||
Write-Host " $($adapter.InterfaceDescription) " -ForegroundColor Gray -NoNewline
|
||||
Write-Host "[$statusLabel]" -ForegroundColor $statusColor
|
||||
|
||||
# Colored IP and MAC display
|
||||
if ($ipv4) {
|
||||
Write-Host " IP: $ipAddress" -ForegroundColor Cyan -NoNewline
|
||||
} else {
|
||||
Write-Host " IP: No IP" -ForegroundColor DarkYellow -NoNewline
|
||||
}
|
||||
Write-Host " | MAC: $macWindows ($macLinux)" -ForegroundColor DarkGray
|
||||
$index++
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "R. Refresh list" -ForegroundColor White
|
||||
Write-Host "P. Add/Remove from System PATH" -ForegroundColor White
|
||||
Write-Host "0. Exit" -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
|
||||
do {
|
||||
$choice = Read-Host "Select adapter number"
|
||||
if ($choice -eq '0') {
|
||||
exit
|
||||
}
|
||||
if ($choice -in @('P','p')) {
|
||||
Add-ToSystemPath
|
||||
return $null
|
||||
}
|
||||
if ($choice -in @('R','r')) {
|
||||
break
|
||||
}
|
||||
|
||||
if ($choice -match '^[0-9]+$') {
|
||||
$choiceNum = [int]$choice
|
||||
} else {
|
||||
$choiceNum = -1
|
||||
}
|
||||
} while ($choiceNum -lt 1 -or $choiceNum -gt $adapters.Count)
|
||||
|
||||
if ($choice -in @('R','r')) {
|
||||
Clear-Host
|
||||
Show-Header
|
||||
continue
|
||||
}
|
||||
|
||||
return $adapters[$choiceNum - 1]
|
||||
}
|
||||
}
|
||||
|
||||
function Show-AdapterInfo {
|
||||
param (
|
||||
[Parameter(Mandatory=$true)]
|
||||
$Adapter
|
||||
)
|
||||
|
||||
Show-Header
|
||||
Write-Host "Adapter: $($Adapter.Name)" -ForegroundColor Green
|
||||
Write-Host "Description: $($Adapter.InterfaceDescription)" -ForegroundColor White
|
||||
Write-Host "Status: $($Adapter.Status)" -ForegroundColor $(if ($Adapter.Status -eq 'Up') { 'Green' } else { 'Yellow' })
|
||||
Write-Host ""
|
||||
|
||||
Write-Host "Hardware Information:" -ForegroundColor Yellow
|
||||
$macWindows = $Adapter.MacAddress
|
||||
$macLinux = $macWindows -replace '-', ':'
|
||||
Write-Host " MAC Address: $macWindows (Windows)" -ForegroundColor White
|
||||
Write-Host " MAC Address: $macLinux (Linux/Unix)" -ForegroundColor White
|
||||
Write-Host " Link Speed: $($Adapter.LinkSpeed)" -ForegroundColor White
|
||||
Write-Host ""
|
||||
|
||||
$ipConfig = Get-NetIPConfiguration -InterfaceIndex $Adapter.InterfaceIndex -ErrorAction SilentlyContinue
|
||||
$ipv4 = Get-NetIPAddress -InterfaceIndex $Adapter.InterfaceIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue
|
||||
|
||||
Write-Host "IPv4 Configuration:" -ForegroundColor Yellow
|
||||
|
||||
if ($ipv4) {
|
||||
Write-Host " IP Address: $($ipv4.IPAddress)" -ForegroundColor White
|
||||
Write-Host " Subnet Prefix Length: $($ipv4.PrefixLength) ($(Convert-PrefixToSubnetMask $ipv4.PrefixLength))" -ForegroundColor White
|
||||
Write-Host " DHCP Enabled: $($ipv4.PrefixOrigin -eq 'Dhcp')" -ForegroundColor White
|
||||
} else {
|
||||
Write-Host " IP Address: Not configured" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
if ($ipConfig.IPv4DefaultGateway) {
|
||||
Write-Host " Default Gateway: $($ipConfig.IPv4DefaultGateway.NextHop)" -ForegroundColor White
|
||||
} else {
|
||||
Write-Host " Default Gateway: Not configured" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
$dnsServers = Get-DnsClientServerAddress -InterfaceIndex $Adapter.InterfaceIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue
|
||||
if ($dnsServers -and $dnsServers.ServerAddresses) {
|
||||
Write-Host " DNS Servers:" -ForegroundColor White
|
||||
foreach ($dns in $dnsServers.ServerAddresses) {
|
||||
Write-Host " - $dns" -ForegroundColor White
|
||||
}
|
||||
} else {
|
||||
Write-Host " DNS Servers: Not configured" -ForegroundColor Gray
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
|
||||
# Adapter details menu: include DHCP, manual IP, lease refresh, DNS flush and presets
|
||||
while ($true) {
|
||||
Write-Host "Options:" -ForegroundColor Yellow
|
||||
Write-Host "1. Set DHCP (enable DHCP on adapter)" -ForegroundColor White
|
||||
Write-Host "2. Set Manual IP" -ForegroundColor White
|
||||
Write-Host "3. Refresh DHCP lease (release/renew)" -ForegroundColor White
|
||||
Write-Host "4. Flush DNS cache" -ForegroundColor White
|
||||
Write-Host "5. Presets" -ForegroundColor White
|
||||
Write-Host "0. Back" -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
|
||||
$sel = Read-Host "Select option"
|
||||
switch ($sel) {
|
||||
'0' { break }
|
||||
'1' {
|
||||
Set-DHCPConfiguration -Adapter $Adapter
|
||||
# refresh adapter object
|
||||
$Adapter = Get-NetAdapter -InterfaceIndex $Adapter.InterfaceIndex -ErrorAction SilentlyContinue
|
||||
Clear-Host
|
||||
Show-Header
|
||||
Write-Host "Adapter: $($Adapter.Name)" -ForegroundColor Green
|
||||
continue
|
||||
}
|
||||
'2' {
|
||||
Set-ManualConfiguration -Adapter $Adapter
|
||||
$Adapter = Get-NetAdapter -InterfaceIndex $Adapter.InterfaceIndex -ErrorAction SilentlyContinue
|
||||
Clear-Host
|
||||
Show-Header
|
||||
Write-Host "Adapter: $($Adapter.Name)" -ForegroundColor Green
|
||||
continue
|
||||
}
|
||||
'3' {
|
||||
Refresh-DHCPLease -Adapter $Adapter
|
||||
$Adapter = Get-NetAdapter -InterfaceIndex $Adapter.InterfaceIndex -ErrorAction SilentlyContinue
|
||||
Clear-Host
|
||||
Show-Header
|
||||
Write-Host "Adapter: $($Adapter.Name)" -ForegroundColor Green
|
||||
continue
|
||||
}
|
||||
'4' {
|
||||
Flush-DNS
|
||||
Clear-Host
|
||||
Show-Header
|
||||
Write-Host "Adapter: $($Adapter.Name)" -ForegroundColor Green
|
||||
continue
|
||||
}
|
||||
'5' {
|
||||
Show-PresetsMenu -Adapter $Adapter
|
||||
$Adapter = Get-NetAdapter -InterfaceIndex $Adapter.InterfaceIndex -ErrorAction SilentlyContinue
|
||||
Clear-Host
|
||||
Show-Header
|
||||
Write-Host "Adapter: $($Adapter.Name)" -ForegroundColor Green
|
||||
continue
|
||||
}
|
||||
default {
|
||||
Write-Host "Invalid selection" -ForegroundColor Red
|
||||
Start-Sleep -Seconds 1
|
||||
Clear-Host
|
||||
Show-Header
|
||||
Write-Host "Adapter: $($Adapter.Name)" -ForegroundColor Green
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
function Convert-PrefixToSubnetMask {
|
||||
param([int]$PrefixLength)
|
||||
|
||||
$mask = ([Math]::Pow(2, 32) - [Math]::Pow(2, (32 - $PrefixLength)))
|
||||
$bytes = [BitConverter]::GetBytes([UInt32]$mask)
|
||||
[Array]::Reverse($bytes)
|
||||
return ($bytes -join '.')
|
||||
}
|
||||
|
||||
function Convert-SubnetMaskToPrefix {
|
||||
param([string]$SubnetMask)
|
||||
|
||||
$octets = $SubnetMask -split '\.'
|
||||
$binaryString = ''
|
||||
foreach ($octet in $octets) {
|
||||
$binaryString += [Convert]::ToString([int]$octet, 2).PadLeft(8, '0')
|
||||
}
|
||||
return ($binaryString.ToCharArray() | Where-Object { $_ -eq '1' }).Count
|
||||
}
|
||||
|
||||
function Add-ToSystemPath {
|
||||
Write-Host ""
|
||||
Write-Host "Add NetworkConfig to System PATH" -ForegroundColor Yellow
|
||||
Write-Host "="*50 -ForegroundColor Yellow
|
||||
Write-Host ""
|
||||
|
||||
$scriptPath = Split-Path -Parent $MyInvocation.MyCommand.Path
|
||||
|
||||
# Check current PATH
|
||||
$userPath = [Environment]::GetEnvironmentVariable('Path', 'User')
|
||||
$machinePath = [Environment]::GetEnvironmentVariable('Path', 'Machine')
|
||||
|
||||
$isInUserPath = $userPath -split ';' | Where-Object { $_ -eq $scriptPath }
|
||||
$isInMachinePath = $machinePath -split ';' | Where-Object { $_ -eq $scriptPath }
|
||||
|
||||
Write-Host "Script Location: $scriptPath" -ForegroundColor Cyan
|
||||
Write-Host ""
|
||||
|
||||
if ($isInUserPath) {
|
||||
Write-Host "✓ Already in User PATH" -ForegroundColor Green
|
||||
}
|
||||
if ($isInMachinePath) {
|
||||
Write-Host "✓ Already in System PATH" -ForegroundColor Green
|
||||
}
|
||||
|
||||
if ($isInUserPath -or $isInMachinePath) {
|
||||
Write-Host ""
|
||||
Write-Host "Options:" -ForegroundColor Yellow
|
||||
Write-Host "1. Remove from User PATH" -ForegroundColor White
|
||||
Write-Host "2. Remove from System PATH" -ForegroundColor White
|
||||
Write-Host "0. Cancel" -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
|
||||
$choice = Read-Host "Select option"
|
||||
|
||||
switch ($choice) {
|
||||
'1' {
|
||||
if ($isInUserPath) {
|
||||
try {
|
||||
$newPath = ($userPath -split ';' | Where-Object { $_ -ne $scriptPath }) -join ';'
|
||||
[Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
|
||||
Write-Host "Successfully removed from User PATH!" -ForegroundColor Green
|
||||
Write-Host "You may need to restart your terminals for changes to take effect." -ForegroundColor Yellow
|
||||
}
|
||||
catch {
|
||||
Write-Host "Error removing from User PATH: $($_.Exception.Message)" -ForegroundColor Red
|
||||
}
|
||||
} else {
|
||||
Write-Host "Not found in User PATH." -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
'2' {
|
||||
if ($isInMachinePath) {
|
||||
try {
|
||||
$newPath = ($machinePath -split ';' | Where-Object { $_ -ne $scriptPath }) -join ';'
|
||||
[Environment]::SetEnvironmentVariable('Path', $newPath, 'Machine')
|
||||
Write-Host "Successfully removed from System PATH!" -ForegroundColor Green
|
||||
Write-Host "You may need to restart your terminals for changes to take effect." -ForegroundColor Yellow
|
||||
}
|
||||
catch {
|
||||
Write-Host "Error removing from System PATH: $($_.Exception.Message)" -ForegroundColor Red
|
||||
}
|
||||
} else {
|
||||
Write-Host "Not found in System PATH." -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Write-Host "Not currently in PATH." -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
Write-Host "Where would you like to add it?" -ForegroundColor Yellow
|
||||
Write-Host "1. User PATH (current user only)" -ForegroundColor White
|
||||
Write-Host "2. System PATH (all users - requires admin)" -ForegroundColor White
|
||||
Write-Host "0. Cancel" -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
|
||||
$choice = Read-Host "Select option"
|
||||
|
||||
switch ($choice) {
|
||||
'1' {
|
||||
try {
|
||||
$newPath = $userPath.TrimEnd(';') + ';' + $scriptPath
|
||||
[Environment]::SetEnvironmentVariable('Path', $newPath, 'User')
|
||||
Write-Host "Successfully added to User PATH!" -ForegroundColor Green
|
||||
Write-Host "You can now run 'NetworkConfig' from any terminal." -ForegroundColor Green
|
||||
Write-Host "You may need to restart your terminals for changes to take effect." -ForegroundColor Yellow
|
||||
}
|
||||
catch {
|
||||
Write-Host "Error adding to User PATH: $($_.Exception.Message)" -ForegroundColor Red
|
||||
}
|
||||
}
|
||||
'2' {
|
||||
try {
|
||||
$newPath = $machinePath.TrimEnd(';') + ';' + $scriptPath
|
||||
[Environment]::SetEnvironmentVariable('Path', $newPath, 'Machine')
|
||||
Write-Host "Successfully added to System PATH!" -ForegroundColor Green
|
||||
Write-Host "You can now run 'NetworkConfig' from any terminal." -ForegroundColor Green
|
||||
Write-Host "You may need to restart your terminals for changes to take effect." -ForegroundColor Yellow
|
||||
}
|
||||
catch {
|
||||
Write-Host "Error adding to System PATH: $($_.Exception.Message)" -ForegroundColor Red
|
||||
Write-Host "Make sure you're running as administrator." -ForegroundColor Yellow
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Read-Host "Press Enter to continue"
|
||||
}
|
||||
|
||||
function Refresh-DHCPLease {
|
||||
param (
|
||||
[Parameter(Mandatory=$false)]
|
||||
$Adapter
|
||||
)
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Refreshing DHCP lease..." -ForegroundColor Yellow
|
||||
try {
|
||||
# Attempt a client-side release/renew. This may act on all adapters on some systems.
|
||||
Start-Process -FilePath ipconfig -ArgumentList '/release' -NoNewWindow -Wait
|
||||
Start-Process -FilePath ipconfig -ArgumentList '/renew' -NoNewWindow -Wait
|
||||
Write-Host "DHCP lease refreshed (client-side)." -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Host "Error refreshing DHCP lease: $($_.Exception.Message)" -ForegroundColor Red
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Read-Host "Press Enter to continue"
|
||||
}
|
||||
|
||||
function Flush-DNS {
|
||||
param ()
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Flushing DNS cache..." -ForegroundColor Yellow
|
||||
try {
|
||||
# Use native cmdlet when available
|
||||
if (Get-Command -Name Clear-DnsClientCache -ErrorAction SilentlyContinue) {
|
||||
Clear-DnsClientCache -ErrorAction Stop
|
||||
}
|
||||
|
||||
# Also run ipconfig flushdns for broad compatibility
|
||||
Start-Process -FilePath ipconfig -ArgumentList '/flushdns' -NoNewWindow -Wait
|
||||
|
||||
Write-Host "DNS cache flushed." -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Host "Error flushing DNS cache: $($_.Exception.Message)" -ForegroundColor Red
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Read-Host "Press Enter to continue"
|
||||
}
|
||||
|
||||
function Set-DHCPConfiguration {
|
||||
param (
|
||||
[Parameter(Mandatory=$true)]
|
||||
$Adapter
|
||||
)
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Setting adapter to DHCP..." -ForegroundColor Yellow
|
||||
|
||||
try {
|
||||
# Remove existing IP configuration
|
||||
Remove-NetIPAddress -InterfaceIndex $Adapter.InterfaceIndex -Confirm:$false -ErrorAction SilentlyContinue
|
||||
Remove-NetRoute -InterfaceIndex $Adapter.InterfaceIndex -Confirm:$false -ErrorAction SilentlyContinue
|
||||
|
||||
# Set to DHCP
|
||||
Set-NetIPInterface -InterfaceIndex $Adapter.InterfaceIndex -Dhcp Enabled -ErrorAction Stop
|
||||
Set-DnsClientServerAddress -InterfaceIndex $Adapter.InterfaceIndex -ResetServerAddresses -ErrorAction Stop
|
||||
|
||||
Write-Host "Successfully configured adapter for DHCP!" -ForegroundColor Green
|
||||
Write-Host "The adapter will now obtain IP settings automatically." -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Host "Error configuring DHCP: $($_.Exception.Message)" -ForegroundColor Red
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Read-Host "Press Enter to continue"
|
||||
}
|
||||
|
||||
function Set-ManualConfiguration {
|
||||
param (
|
||||
[Parameter(Mandatory=$true)]
|
||||
$Adapter
|
||||
)
|
||||
|
||||
Write-Host ""
|
||||
Write-Host "Manual IP Configuration" -ForegroundColor Yellow
|
||||
Write-Host "Leave fields blank to skip configuration for that setting" -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
|
||||
# Get IP Address
|
||||
do {
|
||||
$ipAddress = Read-Host "Enter IP Address (e.g., 192.168.1.100)"
|
||||
if ([string]::IsNullOrWhiteSpace($ipAddress)) {
|
||||
Write-Host "IP Address is required for manual configuration!" -ForegroundColor Red
|
||||
}
|
||||
} while ([string]::IsNullOrWhiteSpace($ipAddress))
|
||||
|
||||
# Validate IP Address
|
||||
try {
|
||||
[System.Net.IPAddress]::Parse($ipAddress) | Out-Null
|
||||
}
|
||||
catch {
|
||||
Write-Host "Invalid IP Address format!" -ForegroundColor Red
|
||||
Read-Host "Press Enter to return to menu"
|
||||
return
|
||||
}
|
||||
|
||||
# Get Subnet Mask
|
||||
do {
|
||||
$subnetMask = Read-Host "Enter Subnet Mask (e.g., 255.255.255.0) or prefix length (e.g., 24)"
|
||||
if ([string]::IsNullOrWhiteSpace($subnetMask)) {
|
||||
Write-Host "Subnet Mask is required for manual configuration!" -ForegroundColor Red
|
||||
}
|
||||
} while ([string]::IsNullOrWhiteSpace($subnetMask))
|
||||
|
||||
# Convert subnet mask to prefix length
|
||||
if ($subnetMask -match '^\d{1,2}$') {
|
||||
$prefixLength = [int]$subnetMask
|
||||
} else {
|
||||
try {
|
||||
$prefixLength = Convert-SubnetMaskToPrefix $subnetMask
|
||||
}
|
||||
catch {
|
||||
Write-Host "Invalid Subnet Mask format!" -ForegroundColor Red
|
||||
Read-Host "Press Enter to return to menu"
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
# Get Default Gateway (optional)
|
||||
$gateway = Read-Host "Enter Default Gateway (press Enter to skip)"
|
||||
if (![string]::IsNullOrWhiteSpace($gateway)) {
|
||||
try {
|
||||
[System.Net.IPAddress]::Parse($gateway) | Out-Null
|
||||
}
|
||||
catch {
|
||||
Write-Host "Invalid Gateway format!" -ForegroundColor Red
|
||||
Read-Host "Press Enter to return to menu"
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
# Get DNS Servers (optional)
|
||||
$dnsServers = @()
|
||||
$dns1 = Read-Host "Enter Primary DNS Server (press Enter to skip)"
|
||||
if (![string]::IsNullOrWhiteSpace($dns1)) {
|
||||
try {
|
||||
[System.Net.IPAddress]::Parse($dns1) | Out-Null
|
||||
$dnsServers += $dns1
|
||||
}
|
||||
catch {
|
||||
Write-Host "Invalid DNS Server format!" -ForegroundColor Red
|
||||
Read-Host "Press Enter to return to menu"
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
$dns2 = Read-Host "Enter Secondary DNS Server (press Enter to skip)"
|
||||
if (![string]::IsNullOrWhiteSpace($dns2)) {
|
||||
try {
|
||||
[System.Net.IPAddress]::Parse($dns2) | Out-Null
|
||||
$dnsServers += $dns2
|
||||
}
|
||||
catch {
|
||||
Write-Host "Invalid DNS Server format!" -ForegroundColor Red
|
||||
Read-Host "Press Enter to return to menu"
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
# Confirm configuration
|
||||
Write-Host ""
|
||||
Write-Host "Configuration Summary:" -ForegroundColor Cyan
|
||||
Write-Host " IP Address: $ipAddress/$prefixLength" -ForegroundColor White
|
||||
if (![string]::IsNullOrWhiteSpace($gateway)) {
|
||||
Write-Host " Gateway: $gateway" -ForegroundColor White
|
||||
}
|
||||
if ($dnsServers.Count -gt 0) {
|
||||
Write-Host " DNS Servers: $($dnsServers -join ', ')" -ForegroundColor White
|
||||
}
|
||||
Write-Host ""
|
||||
|
||||
$confirm = Read-Host "Apply this configuration? (Y/N)"
|
||||
if ($confirm -ne 'Y' -and $confirm -ne 'y') {
|
||||
Write-Host "Configuration cancelled." -ForegroundColor Yellow
|
||||
Read-Host "Press Enter to continue"
|
||||
return
|
||||
}
|
||||
|
||||
# Apply configuration
|
||||
Write-Host ""
|
||||
Write-Host "Applying configuration..." -ForegroundColor Yellow
|
||||
|
||||
try {
|
||||
# Remove existing IP configuration
|
||||
Remove-NetIPAddress -InterfaceIndex $Adapter.InterfaceIndex -Confirm:$false -ErrorAction SilentlyContinue
|
||||
Remove-NetRoute -InterfaceIndex $Adapter.InterfaceIndex -Confirm:$false -ErrorAction SilentlyContinue
|
||||
|
||||
# Disable DHCP
|
||||
Set-NetIPInterface -InterfaceIndex $Adapter.InterfaceIndex -Dhcp Disabled -ErrorAction Stop
|
||||
|
||||
# Set IP Address
|
||||
New-NetIPAddress -InterfaceIndex $Adapter.InterfaceIndex `
|
||||
-IPAddress $ipAddress `
|
||||
-PrefixLength $prefixLength `
|
||||
-DefaultGateway $(if (![string]::IsNullOrWhiteSpace($gateway)) { $gateway } else { $null }) `
|
||||
-ErrorAction Stop | Out-Null
|
||||
|
||||
# Set DNS Servers
|
||||
if ($dnsServers.Count -gt 0) {
|
||||
Set-DnsClientServerAddress -InterfaceIndex $Adapter.InterfaceIndex `
|
||||
-ServerAddresses $dnsServers `
|
||||
-ErrorAction Stop
|
||||
}
|
||||
|
||||
Write-Host "Configuration applied successfully!" -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Host "Error applying configuration: $($_.Exception.Message)" -ForegroundColor Red
|
||||
}
|
||||
|
||||
Write-Host ""
|
||||
Read-Host "Press Enter to continue"
|
||||
}
|
||||
|
||||
# Presets helpers
|
||||
function Get-PresetsFilePath {
|
||||
return Join-Path $PSScriptRoot 'network-presets.json'
|
||||
}
|
||||
|
||||
function Load-Presets {
|
||||
$file = Get-PresetsFilePath
|
||||
if (-not (Test-Path $file)) {
|
||||
return @()
|
||||
}
|
||||
|
||||
try {
|
||||
$raw = Get-Content -Path $file -Raw -ErrorAction Stop
|
||||
if ([string]::IsNullOrWhiteSpace($raw)) { return @() }
|
||||
return $raw | ConvertFrom-Json -ErrorAction Stop
|
||||
}
|
||||
catch {
|
||||
Write-Host "Error loading presets file: $($_.Exception.Message)" -ForegroundColor Red
|
||||
return @()
|
||||
}
|
||||
}
|
||||
|
||||
function Save-Presets($data) {
|
||||
$file = Get-PresetsFilePath
|
||||
try {
|
||||
$json = $data | ConvertTo-Json -Depth 10
|
||||
$json | Set-Content -Path $file -Encoding UTF8 -Force
|
||||
return $true
|
||||
}
|
||||
catch {
|
||||
Write-Host "Error saving presets file: $($_.Exception.Message)" -ForegroundColor Red
|
||||
return $false
|
||||
}
|
||||
}
|
||||
|
||||
function Get-PresetsForAdapter($adapterGuid) {
|
||||
$all = Load-Presets
|
||||
if ($null -eq $all) { return @() }
|
||||
$entry = $all | Where-Object { $_.adapterGuid -eq $adapterGuid }
|
||||
if ($entry) { return $entry.presets }
|
||||
return @()
|
||||
}
|
||||
|
||||
function Add-OrUpdate-Preset($adapter, $preset) {
|
||||
$all = Load-Presets
|
||||
if (-not $all) { $all = @() }
|
||||
|
||||
$entry = $all | Where-Object { $_.adapterGuid -eq $adapter.InterfaceGuid }
|
||||
if (-not $entry) {
|
||||
$entry = [PSCustomObject]@{
|
||||
adapterGuid = $adapter.InterfaceGuid
|
||||
adapterName = $adapter.Name
|
||||
adapterDescription = $adapter.InterfaceDescription
|
||||
presets = @()
|
||||
}
|
||||
$all += $entry
|
||||
}
|
||||
|
||||
# Replace existing preset with same name
|
||||
$existing = $entry.presets | Where-Object { $_.name -eq $preset.name }
|
||||
if ($existing) {
|
||||
$entry.presets = ($entry.presets | Where-Object { $_.name -ne $preset.name }) + $preset
|
||||
}
|
||||
else {
|
||||
$entry.presets += $preset
|
||||
}
|
||||
|
||||
Save-Presets $all | Out-Null
|
||||
}
|
||||
|
||||
function Remove-Preset($adapterGuid, $presetName) {
|
||||
$all = Load-Presets
|
||||
if (-not $all) { return $false }
|
||||
$entry = $all | Where-Object { $_.adapterGuid -eq $adapterGuid }
|
||||
if (-not $entry) { return $false }
|
||||
$entry.presets = $entry.presets | Where-Object { $_.name -ne $presetName }
|
||||
Save-Presets $all | Out-Null
|
||||
return $true
|
||||
}
|
||||
|
||||
function Apply-Preset($adapter, $preset) {
|
||||
if ($preset.type -eq 'DHCP') {
|
||||
Set-DHCPConfiguration -Adapter $adapter
|
||||
return
|
||||
}
|
||||
|
||||
try {
|
||||
Remove-NetIPAddress -InterfaceIndex $adapter.InterfaceIndex -Confirm:$false -ErrorAction SilentlyContinue
|
||||
Remove-NetRoute -InterfaceIndex $adapter.InterfaceIndex -Confirm:$false -ErrorAction SilentlyContinue
|
||||
|
||||
Set-NetIPInterface -InterfaceIndex $adapter.InterfaceIndex -Dhcp Disabled -ErrorAction Stop
|
||||
|
||||
New-NetIPAddress -InterfaceIndex $adapter.InterfaceIndex -IPAddress $preset.ipAddress -PrefixLength $preset.prefixLength -DefaultGateway $(if ($preset.gateway) { $preset.gateway } else { $null }) -ErrorAction Stop | Out-Null
|
||||
|
||||
if ($preset.dns -and $preset.dns.Count -gt 0) {
|
||||
Set-DnsClientServerAddress -InterfaceIndex $adapter.InterfaceIndex -ServerAddresses $preset.dns -ErrorAction Stop
|
||||
}
|
||||
|
||||
Write-Host "Preset '$($preset.name)' applied successfully." -ForegroundColor Green
|
||||
}
|
||||
catch {
|
||||
Write-Host "Error applying preset: $($_.Exception.Message)" -ForegroundColor Red
|
||||
}
|
||||
Read-Host "Press Enter to continue"
|
||||
}
|
||||
|
||||
function Show-PresetsMenu {
|
||||
param([Parameter(Mandatory=$true)] $Adapter)
|
||||
|
||||
while ($true) {
|
||||
Clear-Host
|
||||
Show-Header
|
||||
Write-Host "Presets for adapter: $($Adapter.Name)" -ForegroundColor Yellow
|
||||
$presets = Get-PresetsForAdapter $Adapter.InterfaceGuid
|
||||
if ($presets.Count -eq 0) {
|
||||
Write-Host " (No presets saved)" -ForegroundColor Gray
|
||||
}
|
||||
else {
|
||||
$i = 1
|
||||
foreach ($p in $presets) {
|
||||
Write-Host " $i. $($p.name) - $($p.type)" -ForegroundColor White
|
||||
$i++
|
||||
}
|
||||
}
|
||||
|
||||
Write-Host "";
|
||||
Write-Host "A. Add current config as preset" -ForegroundColor White
|
||||
Write-Host "L. Load/apply a preset" -ForegroundColor White
|
||||
Write-Host "D. Delete a preset" -ForegroundColor White
|
||||
Write-Host "E. Export presets file location" -ForegroundColor White
|
||||
Write-Host "0. Back" -ForegroundColor Gray
|
||||
Write-Host ""
|
||||
|
||||
$sel = Read-Host "Select option"
|
||||
switch ($sel) {
|
||||
'0' { break }
|
||||
'A' { 'A' } 'a' { 'A' } default { }
|
||||
}
|
||||
|
||||
if ($sel -in @('A','a')) {
|
||||
# Capture current IPv4 config
|
||||
$ipConfig = Get-NetIPConfiguration -InterfaceIndex $Adapter.InterfaceIndex -ErrorAction SilentlyContinue
|
||||
$ipv4 = Get-NetIPAddress -InterfaceIndex $Adapter.InterfaceIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue
|
||||
|
||||
$presetName = Read-Host "Preset name"
|
||||
if ([string]::IsNullOrWhiteSpace($presetName)) { Write-Host "Name required" -ForegroundColor Red; Start-Sleep -Seconds 1; continue }
|
||||
|
||||
if ($ipv4) {
|
||||
$presetObj = [PSCustomObject]@{
|
||||
name = $presetName
|
||||
type = 'Manual'
|
||||
ipAddress = $ipv4.IPAddress
|
||||
prefixLength = $ipv4.PrefixLength
|
||||
gateway = (if ($ipConfig.IPv4DefaultGateway) { $ipConfig.IPv4DefaultGateway.NextHop } else { $null })
|
||||
dns = (Get-DnsClientServerAddress -InterfaceIndex $Adapter.InterfaceIndex -AddressFamily IPv4 -ErrorAction SilentlyContinue).ServerAddresses
|
||||
}
|
||||
}
|
||||
else {
|
||||
$presetObj = [PSCustomObject]@{
|
||||
name = $presetName
|
||||
type = 'DHCP'
|
||||
}
|
||||
}
|
||||
|
||||
Add-OrUpdate-Preset -adapter $Adapter -preset $presetObj
|
||||
Write-Host "Preset saved." -ForegroundColor Green
|
||||
Start-Sleep -Seconds 1
|
||||
continue
|
||||
|
||||
}
|
||||
|
||||
if ($sel -in @('L','l')) {
|
||||
if ($presets.Count -eq 0) { Write-Host "No presets." -ForegroundColor Yellow; Start-Sleep -Seconds 1; continue }
|
||||
$idx = Read-Host "Enter preset number to apply"
|
||||
if ($idx -match '^[0-9]+$') {
|
||||
$num = [int]$idx
|
||||
if ($num -ge 1 -and $num -le $presets.Count) {
|
||||
$preset = $presets[$num - 1]
|
||||
Apply-Preset -Adapter $Adapter -preset $preset
|
||||
}
|
||||
else { Write-Host "Invalid selection" -ForegroundColor Red; Start-Sleep -Seconds 1 }
|
||||
}
|
||||
else { Write-Host "Invalid input" -ForegroundColor Red; Start-Sleep -Seconds 1 }
|
||||
continue
|
||||
}
|
||||
|
||||
if ($sel -in @('D','d')) {
|
||||
if ($presets.Count -eq 0) { Write-Host "No presets." -ForegroundColor Yellow; Start-Sleep -Seconds 1; continue }
|
||||
$idx = Read-Host "Enter preset number to delete"
|
||||
if ($idx -match '^[0-9]+$') {
|
||||
$num = [int]$idx
|
||||
if ($num -ge 1 -and $num -le $presets.Count) {
|
||||
$name = $presets[$num - 1].name
|
||||
Remove-Preset -adapterGuid $Adapter.InterfaceGuid -presetName $name | Out-Null
|
||||
Write-Host "Deleted preset '$name'" -ForegroundColor Green
|
||||
}
|
||||
else { Write-Host "Invalid selection" -ForegroundColor Red }
|
||||
}
|
||||
else { Write-Host "Invalid input" -ForegroundColor Red }
|
||||
Start-Sleep -Seconds 1
|
||||
continue
|
||||
}
|
||||
|
||||
if ($sel -in @('E','e')) {
|
||||
$file = Get-PresetsFilePath
|
||||
Write-Host "Presets file: $file" -ForegroundColor Cyan
|
||||
Read-Host "Press Enter to continue"
|
||||
continue
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Export-ModuleMember -Function Show-Header, Get-AdapterChoice, Show-AdapterInfo, Convert-PrefixToSubnetMask, Convert-SubnetMaskToPrefix, Add-ToSystemPath, Set-DHCPConfiguration, Set-ManualConfiguration, Get-PresetsFilePath, Load-Presets, Save-Presets, Get-PresetsForAdapter, Add-OrUpdate-Preset, Remove-Preset, Apply-Preset, Show-PresetsMenu, Refresh-DHCPLease, Flush-DNS
|
||||
Loading…
Add table
Add a link
Reference in a new issue