簡體   English   中英

解析Powershell陣列中的RegEx IP匹配項

[英]Parse RegEx IP matches in Powershell array

我正在嘗試找出如何解析IP地址數組。 到目前為止,我已經解決了如何將IP解析為DNS主機名的問題:

Function Get-IP-Hostname
{
    Param([string[]]$array)

    $array.length

    foreach ($element in $array) 
    {
        $hname = [System.Net.Dns]::GetHostByAddress($element).HostName 

        $regex = "[regex] (\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"

        @{$element = $hname}
     }
 } 

當我執行

Get-IP-Hostname 192.168.150.xx 192.168.151.xx  

與一堆IP,我必須使用逗號來分隔,將字符串分開-我的RegEx似乎沒有逗號就不會分開。

我正在嘗試獲得以下輸出:

> Name                           Value                                  
> 
> ----                           -----                                                                                                                                                                                                                               
> 192.168.150.xx                 ank70dom07.akgroup.com                                                                                                                                                                                                             
> 192.168.151.xx                 ank70dom07.akgroup.com

我是PowerShell的新手,不勝感激。

謝謝!

如果希望能夠以這種方式傳遞它們(作為額外的參數),請在參數上使用[ValueFromRemainingArguments()]

還有一種比正則表達式更好的方法來驗證IP地址:只需將其轉換為[ipaddress]

function Get-IP-Hostname {
[CmdletBinding()]
param(
    [Parameter(ValueFromRemainingArguments = $true)]
    [String[]]
    $IPAddress
)

    foreach ($element in $IPAddress) {
        $ip = $element -as [Net.IPAddress]
        if ($ip) {
            @{$element = [Net.Dns]::GetHostByAddress($element).HostName}
        } else {
            # handle invalid IP (or don't)
        }
    }
}

您可以通過僅將參數設置為ipaddresses( [ipaddress[]] )數組來進一步簡化此操作,因為從字符串的強制轉換將自動完成:

function Get-IP-Hostname {
[CmdletBinding()]
param(
    [Parameter(ValueFromRemainingArguments = $true)]
    [IPAddress[]]
    $IPAddress
)

    foreach ($ip in $IPAddress) {
        @{$ip = [Net.Dns]::GetHostByAddress($ip.IPAddressToString).HostName}
    }
}

這里的障礙是,即使傳入的地址之一無效,整個調用也會失敗。 因此,這取決於您要做什么。

還有一個建議:不要每次都返回只有一個元素的新哈希表。 它看起來正確在屏幕上,但這並不是您真正想要的。 您可以使用單個哈希表進行修復,但我建議采取更好的方法:返回具有添加的HostName屬性的[IPAddress]對象:

function Get-IP-Hostname {
[CmdletBinding()]
param(
    [Parameter(ValueFromRemainingArguments = $true)]
    [String[]]
    $IPAddress
)

    foreach ($element in $IPAddress) {
        $ip = $element -as [Net.IPAddress]
        if ($ip) {
            $ip |
                Add-Member -NotePropertyName HostName -NotePropertyValue ([Net.Dns]::GetHostByAddress($ip.IPAddressToString).HostName) -PassThru
        } else {
            # handle invalid IP (or don't)
        }
    }
}

$results = Get-IP-Hostname 8.8.4.4 8.8.8.8

$results | fl * # all properties

$results | ft IPAddressToString,HostName # demonstrating what you want

擺脫$Array參數並利用自動變量$Args 它已經是接收到的所有參數的數組。

PS C:\> Function Get-HostnameFromIP { $Args }
PS C:\> Get-HostnameFromIP 134.222.659.0 148.398.388.299
134.222.659.0
148.398.388.299

這種方法的唯一障礙是,您需要將參數[Net.Dns]::GetHostByAddress("$Element")轉換為您想要的參數(字符串) [Net.Dns]::GetHostByAddress("$Element")

編輯:測試了這種方法,並且IPv4地址已經在PSv5.1中解釋為[String]

您可以使用-match參數。 例如

PS C:\> "192.168.0.1" -match "(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})"  
True

如果找到匹配項,則返回True 您可以從$Matches變量中檢索匹配結果:

PS C:\> $Matches

Name                           Value                                                                                                                      
----                           -----                                                                                                                      
1                              192.168.0.1                                                                                                                
0                              192.168.0.1                                                                                                                

$Matches是一個數組(包含正則表達式匹配組),因此您可以通過[] -operator檢索特定值

PS C:\> $Matches[1]
192.168.0.1  

您還可以通過管道傳遞多個字符串,並檢查其中之一是否與正則表達式匹配:

PS C:\>"192.168.0.23", "10.0.0.1" | % { if ($_ -match "(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3})") { $Matches[0]} }

你也應該結帳這個llink解釋-matches的更多細節。

希望能有所幫助。

使用功能“ ResolveIPs”並使用RegEx公式僅提取IP,對RegEx使用“ .matches”,然后使用“ TRY”解析主機名。 最后將結果輸出到數組中。

function ResolveIPs {
    cls #clear console
    $regex = [regex] "\d{1,3}[.]\d{1,3}[.]\d{1,3}[.]\d{1,3}"
    $table = @() 

    foreach ($argument in $args){ 
        if ($argument -match $regex){ 
            $tempstr = $regex.Matches($argument) | %{ $_.value } 

            foreach ($value in $tempstr){
                $tablevalue = "" | select IP, Hostname 
                try {
                    $result = [Net.Dns]::GetHostByAddress($value).HostName

                    $tablevalue.IP = $value 
                    $tablevalue.Hostname = $result 
                    $table = $table + $tablevalue 
                }
                catch [exception] { 
                    $tablevalue.IP = $value 
                    $tablevalue.Hostname = "Error resolving IP address" 
                    $table = $table + $tablevalue
                }
            }  #endof foreach value
        }#end of IF
    }#endof foreach argument

    $table #output of table with results
}#end of function

現在,您可以將此腳本作為模塊(.psm1)導入,並在功能“ ReolveIPs”之后添加任何IP。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM