5

I am making a script to set the IP, subnet mask, gateway and DNS server address on a localhost. I have a working script but I would like to make sure that the IP addresses entered are numeric characters and within the range 0-255 for each Octet. Any help would be appreciated.

     $IP = Read-Host -Prompt 'Please enter the Static IP Address.  Format 192.168.x.x'
                $MaskBits = 24 # This means subnet mask = 255.255.255.0
                $Gateway = Read-Host -Prompt 'Please enter the defaut gateway IP Address.  Format 192.168.x.x'
                $Dns = Read-Host -Prompt 'Please enter the DNS IP Address.  Format 192.168.x.x'
                $IPType = "IPv4"

            # Retrieve the network adapter that you want to configure
               $adapter = Get-NetAdapter | ? {$_.Status -eq "up"}

           # Remove any existing IP, gateway from our ipv4 adapter
 If (($adapter | Get-NetIPConfiguration).IPv4Address.IPAddress) {
    $adapter | Remove-NetIPAddress -AddressFamily $IPType -Confirm:$false
}

If (($adapter | Get-NetIPConfiguration).Ipv4DefaultGateway) {
    $adapter | Remove-NetRoute -AddressFamily $IPType -Confirm:$false
}

 # Configure the IP address and default gateway
$adapter | New-NetIPAddress `
    -AddressFamily $IPType `
    -IPAddress $IP `
    -PrefixLength $MaskBits `
    -DefaultGateway $Gateway

# Configure the DNS client server IP addresses
$adapter | Set-DnsClientServerAddress -ServerAddresses $DNS
erik121
  • 301
  • 3
  • 6
  • 11
  • 2
    `$IP = Read-Host -Prompt 'Please enter the Static IP Address. Format 192.168.x.x'; if($($addr=$null; [ipaddress]::TryParse($IP, [ref]$addr) -and $addr.AddressFamily -eq 'InterNetwork')) { 'Valid IPv4 address' } else { 'Not valid IPv4 address' }` – user4003407 Apr 11 '17 at 03:57

3 Answers3

8

Check this link. You can cast the given string to [ipaddress].

PS C:\Windows\system32> [ipaddress]"192.168.1.1"

Above sample does not produce an error. If you're using an invalid ip address:

PS C:\Windows\system32> [ipaddress]"260.0.0.1"
Cannot convert value "260.0.0.1" to type "System.Net.IPAddress". Error: "An 
invalid IP address was specified."
At line:1 char:1
+ [ipaddress]"260.0.0.1"
+ ~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo          : InvalidArgument: (:) [], RuntimeException
+ FullyQualifiedErrorId : InvalidCastParseTargetInvocation

You'll receive an exception that can be caught.

Moerwald
  • 10,448
  • 9
  • 43
  • 83
  • Be aware, if you are using type casting like `[IPAddress] 192.168.1.1` for validation, there might be a case the conversion is wrong. For example: `[IPAddress] 192` will produce `192.0.0.0`. However you might think `192` is not a valid ip. – Luckybug Jun 24 '19 at 18:46
  • If you want to get rid of the case Luckybug mentions you may try to `([ipaddress]$IP).IPAddressToString -eq ("" + $IP)` Note that this breaks some (valid) IPv6 Adresses that would be detected otherwise like `2001:db8:3:4::192.0.2.33` Choose your poison. – Simon Jan 31 '23 at 12:02
5

Here is the aproach that combines the above two answers.
For a basic validation this oneliner could help

[bool]("text" -as [ipaddress])

But user may type something like "100" and it will successfully validate to ip address 0.0.0.100.
That's might be something not what you expect.
So i like to use regex and type validation combined:

function IsValidIPv4Address ($ip) {
    return ($ip -match "^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$" -and [bool]($ip -as [ipaddress]))
}
  • This is nice. The function will gracefully return true/false, whereas other solutions to this question will throw terminating errors. – Ro Yo Mi Jun 23 '23 at 16:29
0

Use regular expressions

$ipRegEx="\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"
if($ip -notmatch $ipRegEx)
{
   #error code
}

You can search online about regular expressions and examples for IP. Just keep in mind that powershell is built on top of .NET, therefore when searching and reading for regular expressions, focus on the .NET or C# ones. For example this.

update As it was pointed out afterwards by comments, the regex is not correct but it was posted as an example for the regular expressions validation. An alternative could be ((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]?)

Community
  • 1
  • 1
Alex Sarafian
  • 634
  • 6
  • 17
  • Hi, `333.444.555.666` is not a valid IP address, this regex is a bit too simple. – sodawillow Apr 11 '17 at 11:27
  • I know that, but regular expressions samples for common values are available online. I just used `"\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}"` as an example for the block. – Alex Sarafian Apr 11 '17 at 11:29
  • 1
    Also, another approach that doesn't try/catch is the using the `TryParse` static functions that many types offer in .NET. `[System.Net.IPAddress]::TryParse()`. [Link](https://msdn.microsoft.com/en-us/library/system.net.ipaddress.tryparse(v=vs.95).aspx) on MSDN – Alex Sarafian Apr 11 '17 at 11:31