验证和比较PowerShell脚本中的传入参数

zc0qhyus  于 2022-11-10  发布在  Shell
关注(0)|答案(4)|浏览(139)

我正在学习PowerShell的基础知识,我有一个任务-创建pwsh脚本,它接受3个传入参数(所有参数都是必需的):
1.第一个参数,值ADDRESS_1,格式为x.x的IP地址
1.第二个参数,值ADDRESS_2,格式为x.x的IP地址
1.第三个参数,值掩码,值格式为x.x或xx(255.0.0.0或8)
此脚本应检查ADDRESS_1ADDRESS_2是否属于同一网络。输出控制台中的结果为是或否。正如我在前面提到的,传入参数不允许接受无效参数,它应该显示错误。
谁能解释一下,我怎么才能做到这一点。我将非常感谢你的帮助。

dgtucam1

dgtucam11#

第一次阅读时,有些文档可能看起来令人印象深刻,所以这里有一个工作框架,可以帮助您学习和入门。[ValidatePattern()][ValidateScript()]属性验证IPv4地址格式和有效值范围,如果不满足它们指定的条件,将抛出错误。
Process块中执行域比较,并对结果进行有条件的分支。我把这个留给你了。

Function AddressTest
{
    Param(
        [Parameter(Mandatory,Position = 0)]
        [ValidatePattern('^(\d{1,3}\.){3}\d{1,3}$')]
        [ValidateScript({[Int[]](($_.Split('.')) -le 255).Count -eq 4})]
        [String]$address_1,

        [Parameter(Mandatory,Position = 1)]
        [ValidatePattern('^(\d{1,3}\.){3}\d{1,3}$')]
        [ValidateScript({[Int[]](($_.Split('.')) -le 255).Count -eq 4})]
        [String]$address_2,

        [Parameter(Mandatory,Position = 2)]
        [ValidatePattern('^((\d{1,3}\.){3})?\d{1,3}$')]
        [ValidateScript({(($_ -match '^\d+$') -and ([Int]$_ -le 255)) -or (($_.Split('.') -le 255).Count -eq 4)})]
        [String]$Mask
    )
    Process
    {
        echo $address_1
        echo $address_2
        echo $mask
    }
}

阅读评论中其他人提供的链接上的文档,同时仔细分析代码以了解其工作原理。

xxhby3vn

xxhby3vn2#

这是一个如何使用正则表达式验证模式来测试两个IP地址和网络掩码是否有效的示例。

param (
    [Parameter(Mandatory, Position=0)][string] $ip1,
    [Parameter(Mandatory, Position=1)] [string] $ip2,
    [Parameter(Mandatory, Position=2)] [string] $mask
)

# you can use [Parameter(Mandatory, Position=0)][IPAddress] $ip1 as input instead of string

# ipaddress param can accept partial ip's like 192.168 and will convert it to 192.0.0.168

# string with test would probably be better

function IsValidIPv4 ($ip) {
    return ($ip -match '^(?:(?: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]?)$' -and [bool]($ip -as [ipaddress]))
}

# Validate IP's as actual IPv4

if (isValidIPv4 $ip1){
    write-host "$($ip1) IS a valid IPv4 Address"
} else {
    write-host "$($ip1) is not a valid IPv4 Address" -ForegroundColor Red
}
if (isValidIPv4 $ip2){
    write-host "$($ip2) IS a valid IPv4 Address"
} else {
    write-host "$($ip2) is not a valid IPv4 Address" -ForegroundColor Red
}
if (isValidIPv4 $mask){
    write-host "$($mask) IS a valid IPv4 Address"
} else {
    write-host "$($mask) is not a valid netmask" -ForegroundColor Red
}

然后使用网络掩码检查IP1和IP2是否在同一网络中

注意:

正如我在上面的评论中指出的,您可以使用[参数(强制,位置=0)][IPAddress]$IP1作为输入,而不是字符串

IP地址参数可以接受类似192.168的部分IP,并将其转换为192.0.0.168,这将导致不正确的验证-请勿使用IT

zpjtge22

zpjtge223#

我找到了一个答案,脚本,带有奇怪的验证模式:

param (
    [parameter(Mandatory = $true, Position = 0)]
    [Net.IPAddress]
    $ip1,

    [parameter(Mandatory = $true, Position = 1)]
    [Net.IPAddress]
    $ip2,

    [parameter(Mandatory = $true, Position = 2)]
    [alias("SubnetMask")]
    [Net.IPAddress]
    $mask
)

if (($ip1.address -band $mask.address) -eq ($ip2.address -band $mask.address)) { $true } else { $false }

工作正常:

./script.ps1 -ip1 192.168.228.110 -ip2 192.168.228.190 -mask 255.255.255.128

但当我使用网络前缀时,它总是给出TRUE。

./script.ps1 -ip1 192.168.228.110 -ip2 192.168.228.190 -mask 30

如何修改脚本,以使用前缀?

6qqygrtg

6qqygrtg4#

根据我的评论。这些东西已经存在多年了,所以没有必要从头开始写,除非这是一项家庭作业,或者你正在强迫自己学习。
搜索是你的朋友。
'powershell ipv4 address range to cidr'
结果中的第一个命中...
https://www.kittell.net/code/powershell-ipv4-range
...和作者的例子:


# IPv4 Range

function New-IPRange ($start, $end)
{
    # created by Dr. Tobias Weltner, MVP PowerShell
    $ip1 = ([System.Net.IPAddress]$start).GetAddressBytes()
    [Array]::Reverse($ip1)
    $ip1 = ([System.Net.IPAddress]($ip1 -join '.')).Address
    $ip2 = ([System.Net.IPAddress]$end).GetAddressBytes()
    [Array]::Reverse($ip2)
    $ip2 = ([System.Net.IPAddress]($ip2 -join '.')).Address

    for ($x=$ip1; $x -le $ip2; $x++)
        {
            $ip = ([System.Net.IPAddress]$x).GetAddressBytes()
            [Array]::Reverse($ip)
            $ip -join '.'
        }
}

# IPv4 Range - Example

New-IPRange 192.168.10.10 192.168.10.20

# broadcast IPv4 address from a CIDR range

function Get-Broadcast ($addressAndCidr)
{
    $addressAndCidr = $addressAndCidr.Split("/")
    $addressInBin = (New-IPv4toBin $addressAndCidr[0]).ToCharArray()
    for($i=0;$i -lt $addressInBin.length;$i++)
        {
            if($i -ge $addressAndCidr[1])
                {
                    $addressInBin[$i] = "1"
                } 
        }
    [string[]]$addressInInt32 = @()
    for ($i = 0;$i -lt $addressInBin.length;$i++)
        {
            $partAddressInBin += $addressInBin[$i] 
            if(($i+1)%8 -eq 0)
                {
                    $partAddressInBin = $partAddressInBin -join ""
                    $addressInInt32 += [Convert]::ToInt32($partAddressInBin -join "",2)
                    $partAddressInBin = ""
                }
        }
    $addressInInt32 = $addressInInt32 -join "."
    return $addressInInt32
}

# IPv4 Broadcast - Example

Get-Broadcast 192.168.10.10/27

# detect if a specified IPv4 address is in the range

function Test-IPinIPRange ($Address,$Lower,$Mask)
{
    [Char[]]$a = (New-IPv4toBin $Lower).ToCharArray()
    if($mask -like "*.*")
        {
            [Char[]]$b = (New-IPv4toBin $Mask).ToCharArray()
        }
    else
        {
            [Int[]]$array = (1..32)
            for($i=0;$i -lt $array.length;$i++)
                {
                    if($array[$i] -gt $mask){$array[$i]="0"}else{$array[$i]="1"}
                }
            [string]$mask = $array -join ""
            [Char[]]$b = $mask.ToCharArray()
        }
    [Char[]]$c = (New-IPv4toBin $Address).ToCharArray()
    $res = $true
    for($i=0;$i -le $a.length;$i++)
        {
            if($a[$i] -ne $c[$i] -and $b[$i] -ne "0")
                {
                    $res = $false
                } 
        }
    return $res
}

# IPv4 In Range - Example

Write-Output "`r`nTest If IP In Range - 192.168.23.128/25"
Test-IPinIPRange "192.168.23.200" "192.168.23.12" "255.255.255.128"
Write-Output "`r`nTest If IP In Range - 192.168.23.127/24"
Test-IPinIPRange "192.168.23.127" "192.168.23.12" "24"

# convert an IPv4 address to a Bin

function New-IPv4toBin ($ipv4)
{
    $BinNum = $ipv4 -split '\.' | ForEach-Object {[System.Convert]::ToString($_,2).PadLeft(8,'0')}
    return $binNum -join ""
}

# IPv4 To Bin - Example

Write-Output "`r`nIP To Bin"
New-IPv4toBin 192.168.10.10

# convert a Bin to an IPv4 address

function New-IPv4fromBin($addressInBin)
{
    [string[]]$addressInInt32 = @()
    $addressInBin = $addressInBin.ToCharArray()
    for ($i = 0;$i -lt $addressInBin.length;$i++)
        {
            $partAddressInBin += $addressInBin[$i]
            if(($i+1)%8 -eq 0)
                {
                    $partAddressInBin = $partAddressInBin -join ""
                    $addressInInt32 += [Convert]::ToInt32($partAddressInBin -join "",2)
                    $partAddressInBin = ""
                }
        }
    $addressInInt32 = $addressInInt32 -join "."
    return $addressInInt32
}

# IPv4 From Bin - Example

Write-Output "`r`nIP From Bin - 192.168.23.250"
New-IPv4fromBin "11000000101010000001011111111010"

Write-Output "`r`nIP From Bin - 192.168.10.10"
New-IPv4fromBin "11000000101010000000101000001010"

# CIDR To IPv4 Range - Example

Write-Output "`r`nIP CIDR to Range"
New-IPRange "192.168.23.120" (Get-Broadcast "192.168.23.120/25")
  • 您当然可以使用其他人已经提供给您的Validate代码来重构上面的代码。*

相关问题