Private/Network.psm1
|
using module .\Config.psm1 using module .\Console.psm1 using module .\Models.psm1 using module .\Utilities.psm1 class HostsEntry { [int]$LineNumber [string]$IPAddress [bool]$IsValidIP [string]$Hostname [string]$Comment HostsEntry([int]$LineNumber, [string]$IPAddress, [string]$Hostname, [string]$Comment) { $this.LineNumber = $LineNumber $this.IPAddress = $IPAddress $this.Hostname = $Hostname $this.Comment = $Comment.Trim() $testIP = $null $this.IsValidIP = [Net.IPAddress]::TryParse($IPAddress, [ref]$testIP) } [string] ToString() { if ([string]::IsNullOrWhiteSpace($this.Comment)) { return "$($this.IPAddress) $($this.Hostname)" } return "$($this.IPAddress) $($this.Hostname) # $($this.Comment)" } } class HostsFile { static [string] $DefaultPath = (Join-Path $Env:SystemRoot 'System32\drivers\etc\hosts') [string] $Path [System.Collections.Generic.List[HostsEntry]] $Entries hidden [string[]] $RawLines HostsFile([string]$Path) { if (!(Test-Path $Path)) { throw "Hosts file does not exist: $Path" } $this.Path = $Path $this.Entries = [System.Collections.Generic.List[HostsEntry]]::new() $this.Load() } static [HostsFile] Create() { return [HostsFile]::new([HostsFile]::DefaultPath) } static [HostsFile] Create([string]$Path) { return [HostsFile]::new($Path) } hidden [void] Load() { $this.RawLines = Get-Content $this.Path -ErrorAction Stop $commentLine = '^\s*#' $hostLine = '^\s*(?<IPAddress>\S+)\s+(?<Hostname>\S+)(\s*|\s+#(?<Comment>.*))$' for ($i = 0; $i -lt $this.RawLines.Length; $i++) { $line = $this.RawLines[$i] if (!($line -match $commentLine) -and ($line -match $hostLine)) { $comment = '' if ($Matches['Comment']) { $comment = $Matches['Comment'] } $entry = [HostsEntry]::new($i, $Matches['IPAddress'], $Matches['Hostname'], $comment) $this.Entries.Add($entry) } } } [HostsEntry[]] GetEntries() { return $this.Entries.ToArray() } [HostsEntry] GetByHostname([string]$Hostname) { foreach ($entry in $this.Entries) { if ($entry.Hostname -eq $Hostname) { return $entry } } return $null } [HostsEntry[]] GetByIPAddress([string]$IPAddress) { $results = [System.Collections.Generic.List[HostsEntry]]::new() foreach ($entry in $this.Entries) { if ($entry.IPAddress -eq $IPAddress) { $results.Add($entry) } } return $results.ToArray() } [void] Add([string]$IPAddress, [string]$Hostname) { $this.Add($IPAddress, $Hostname, "") } [void] Add([string]$IPAddress, [string]$Hostname, [string]$Comment) { $existing = $this.GetByHostname($Hostname) $newEntry = [HostsEntry]::new(-1, $IPAddress, $Hostname, $Comment) if ($existing) { $this.RawLines[$existing.LineNumber] = $newEntry.ToString() $existing.IPAddress = $IPAddress $existing.Comment = $Comment $existing.IsValidIP = [Net.IPAddress]::TryParse($IPAddress, [ref]([ipaddress]::Any)) } else { $this.RawLines += $newEntry.ToString() $newEntry.LineNumber = $this.RawLines.Length - 1 $this.Entries.Add($newEntry) } } [void] RemoveByHostname([string]$Hostname) { $remainingLines = [System.Collections.Generic.List[string]]::new() $newEntries = [System.Collections.Generic.List[HostsEntry]]::new() $lineNumber = 0 foreach ($entry in $this.Entries) { if ($entry.Hostname -ne $Hostname) { $remainingLines.Add($entry.ToString()) $entry.LineNumber = $lineNumber $newEntries.Add($entry) $lineNumber++ } } $this.RawLines = $remainingLines.ToArray() $this.Entries = $newEntries } [void] RemoveByIPAddress([string]$IPAddress) { $remainingLines = [System.Collections.Generic.List[string]]::new() $newEntries = [System.Collections.Generic.List[HostsEntry]]::new() $lineNumber = 0 foreach ($entry in $this.Entries) { if ($entry.IPAddress -ne $IPAddress) { $remainingLines.Add($entry.ToString()) $entry.LineNumber = $lineNumber $newEntries.Add($entry) $lineNumber++ } } $this.RawLines = $remainingLines.ToArray() $this.Entries = $newEntries } [void] Save() { $this.RawLines | Out-File -Encoding ascii -FilePath $this.Path -ErrorAction Stop } [void] Show() { notepad $this.Path } [string] ToString() { return $this.Path } } class NetworkManager { [string] $HostName static [System.Net.IPAddress[]] $IPAddresses static [string] $caller NetworkManager([string]$HostName) { $this.HostName = $HostName $this::IPAddresses = [System.Net.Dns]::GetHostAddresses($HostName) } static [string] GetResponse([string]$URL) { [System.Net.HttpWebRequest]$Request = [System.Net.HttpWebRequest]::Create($URL) $Request.Method = "GET" $Request.Timeout = 10000 [System.Net.HttpWebResponse]$Response = [System.Net.HttpWebResponse]$Request.GetResponse() if ($Response.StatusCode -eq [System.Net.HttpStatusCode]::OK) { [System.IO.Stream]$ReceiveStream = $Response.GetResponseStream() [System.IO.StreamReader]$ReadStream = [System.IO.StreamReader]::new($ReceiveStream) [string]$Content = $ReadStream.ReadToEnd() $ReadStream.Close() $Response.Close() return $Content } else { throw "The request failed with status code: $($Response.StatusCode)" } } static [void] BlockAllOutbound() { if ([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform([System.Runtime.InteropServices.OSPlatform]::Linux)) { & sudo iptables -P OUTPUT DROP } else { netsh advfirewall set allprofiles firewallpolicy blockinbound, blockoutbound } } static [void] UnblockAllOutbound() { if ([System.Runtime.InteropServices.RuntimeInformation]::IsOSPlatform([System.Runtime.InteropServices.OSPlatform]::Linux)) { & sudo iptables -P OUTPUT ACCEPT } else { netsh advfirewall set allprofiles firewallpolicy blockinbound, allowoutbound } } static [void] UploadFile([string]$SourcePath, [string]$DestinationURL) { Invoke-RestMethod -Uri $DestinationURL -Method Post -InFile $SourcePath } static [bool] TestConnection([string]$HostName) { [ValidateNotNullOrEmpty()][string]$HostName = $HostName if () { Add-Type -AssemblyName System.Net.NetworkInformation } $cs = $null; $cc = [NetworkManager]::caller $re = @{ true = @{ m = "Success"; c = "Green" }; false = @{ m = "Failed"; c = "Red" } } Write-Host "$cc Testing Connection ... " -ForegroundColor Blue -NoNewline try { [System.Net.NetworkInformation.PingReply]$PingReply = [System.Net.NetworkInformation.Ping]::new().Send($HostName) $cs = $PingReply.Status -eq [System.Net.NetworkInformation.IPStatus]::Success } catch [System.Net.Sockets.SocketException], [System.Net.NetworkInformation.PingException] { $cs = $false } catch { $cs = $false Write-Error $_ } $re = $re[$cs.ToString()] Write-Host $re.m -ForegroundColor $re.c return $cs } static [bool] IsIPv6AddressValid([string]$IP) { $IPv4Regex = '(((25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2})\.){3}(25[0-5]|2[0-4][0-9]|[0-1]?[0-9]{1,2}))' $G = '[a-f\d]{1,4}' $Tail = @(":", "(:($G)?|$IPv4Regex)", ":($IPv4Regex|$G(:$G)?|)", "(:$IPv4Regex|:$G(:$IPv4Regex|(:$G){0,2})|:)", "((:$G){0,2}(:$IPv4Regex|(:$G){1,2})|:)", "((:$G){0,3}(:$IPv4Regex|(:$G){1,2})|:)", "((:$G){0,4}(:$IPv4Regex|(:$G){1,2})|:)") [string] $IPv6RegexString = $G $Tail | ForEach-Object { $IPv6RegexString = "${G}:($IPv6RegexString|$_)" } $IPv6RegexString = ":(:$G){0,5}((:$G){1,2}|:$IPv4Regex)|$IPv6RegexString" $IPv6RegexString = $IPv6RegexString -replace '\(' , '(?:' [regex] $IPv6Regex = $IPv6RegexString return ($IP -imatch "^$IPv6Regex$") } static [bool] IsMACAddressValid([string]$mac) { $RegEx = "^([0-9A-Fa-f]{2}[:-]){5}([0-9A-Fa-f]{2})|([0-9A-Fa-f]{2}){6}$" return ($mac -match $RegEx) } static [bool] IsSubNetMaskValid([string]$IP) { $RegEx = "^(254|252|248|240|224|192|128).0.0.0$|^255.(254|252|248|240|224|192|128|0).0.0$|^255.255.(254|252|248|240|224|192|128|0).0$|^255.255.255.(255|254|252|248|240|224|192|128|0)$" return ($IP -match $RegEx) } static [bool] IsIPv4AddressValid([string]$IP) { $RegEx = "^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$" return ($IP -match $RegEx) } } |