Power Shell测试连接然后获取计算机名称或mac-addr

时间:2013-07-24 14:17:45

标签: powershell network-programming ping

所以我写了一个简单的pinger,ping所有的网络。我正在使用测试连接,但我也可以获得设计名称。

所以我使用cmd的nbtstat来获取名称但是(假设它不干净)

有没有办法做得更干净一点?

这就是我所拥有的

$a = New-Object System.Collections.ArrayList

for ($i =0;$i -le 225; $i++){
    if (Test-Connection 192.168.1.$i -Count 1 -Quiet){
        echo "live 192.168.1.$i"
        $a.add("192.168.1.$i")
    }else {
        echo "dead 192.168.1.$i"
    }
}
echo $a
foreach ($i in $a){
    Test-Connection $i -Count 1

}

foreach ($i in $a){
    nbtstat -a $i
}

3 个答案:

答案 0 :(得分:2)

我的做法有点不同。每次联系主机时,都会创建一个ARP条目。为什么不利用它?

Get-WmiObject Win32_PingStatus -Filter "Address='192.168.1.2' AND ResolveAddressNames='true'" | 
Select IPV4Address, ProtocolAddressResolved, @{
    Name="PhysicalAddress";Expression={
        ([regex]::Matches($(arp -a $_.IPV4Address),"[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}-[0-9A-F]{2}",@('MultiLine', 'Ignorecase'))).value
    }
}

答案 1 :(得分:1)

总有很多方法可以做某事,例如:

$Pinger = New-Object system.Net.NetworkInformation.Ping
$PC = "192.168.1.$i"

try{
            $ErrorActionPreference = "Stop"
            $PingResult = $Pinger.send($PC)
            $ResultAddress = $PingResult.Address
            $PingStatus = $PingResult.Status

            $DNSObject = [System.Net.Dns]::GetHostEntry($PC).HostName

    }
    catch
    {

    }
    finally
    {
        Write-Host "$PC $PingStatus $PingHost $? $DNSObject"
    }

这比您要求的更多,但我认为它也可能会给您一些想法:

  • .NET可供您使用,而不仅仅是本机cmdlet和Windows命令
  • 使用像$这样的内置运营商吗?

答案 2 :(得分:1)

Test-ConnectionTest-NetConnection现在支持返回更多信息,包括姓名。后者需要Power Shell 5。

<强>试验连接

EXAMPLES
Example 1: Send echo requests to a remote computer

PS C:\> Test-Connection "Server01"

Source        Destination     IPV4Address     IPV6Address  Bytes    Time(ms)
------        -----------     -----------     -----------  -----    --------
ADMIN1        Server01         10.59.137.44                32       0
ADMIN1        Server01         10.59.137.44                32       0
ADMIN1        Server01         10.59.137.44                32       0
ADMIN1        Server01         10.59.137.44                32       1

Source

<强>试验的NetConnection

Test ping connectivity with detailed results

PS C:\> Test-NetConnection -InformationLevel "Detailed"
ComputerName           : internetbeacon.msedge.net

RemoteAddress          : 2a01:111:2003::52

NameResolutionResults  : 2a01:111:2003::52

                         13.107.4.52

InterfaceAlias         : Ethernet

SourceAddress          : 2001:4898:d8:33:81e8:7b49:8bf5:8710

NetRoute (NextHop)     : fe80::200:5eff:fe00:203

PingSucceeded          : True

PingReplyDetails (RTT) : 6 ms

Source

另外,您提到您正在ping整个网络。那是如何找到你的问题(等等),因为我也试图进行ping扫。我解决了这个剧本。这家伙称之为Fast Ping Sweep Asynchronous

即使是Power Shell n00b,我也可以管道输出,然后将其输出修改为仅包含我想要的内容。我遇到了其他脚本,但无法解密他们的脚本以便为我的目的修改它们。

我不确定Power Shell需要什么版本,但它适用于v4和v5。

  

我见过大多数Powershell IP扫描程序,ping扫描脚本   但它们都没有使用PingASync方法。&#34;问题&#34;同   同步脚本是他们必须等到节点回复或   在继续下一个地址之前超时。使用这种方法   可能需要s

function Global:Ping-IPRange {
    <#
    .SYNOPSIS
        Sends ICMP echo request packets to a range of IPv4 addresses between two given addresses.

    .DESCRIPTION
        This function lets you sends ICMP echo request packets ("pings") to 
        a range of IPv4 addresses using an asynchronous method.

        Therefore this technique is very fast but comes with a warning.
        Ping sweeping a large subnet or network with many swithes may result in 
        a peak of broadcast traffic.
        Use the -Interval parameter to adjust the time between each ping request.
        For example, an interval of 60 milliseconds is suitable for wireless networks.
        The RawOutput parameter switches the output to an unformated
        [System.Net.NetworkInformation.PingReply[]].

    .INPUTS
        None
        You cannot pipe input to this funcion.

    .OUTPUTS
        The function only returns output from successful pings.

        Type: System.Net.NetworkInformation.PingReply

        The RawOutput parameter switches the output to an unformated
        [System.Net.NetworkInformation.PingReply[]].

    .NOTES
        Author  : G.A.F.F. Jakobs
        Created : August 30, 2014
        Version : 6

    .EXAMPLE
        Ping-IPRange -StartAddress 192.168.1.1 -EndAddress 192.168.1.254 -Interval 20

        IPAddress                                 Bytes                     Ttl           ResponseTime
        ---------                                 -----                     ---           ------------
        192.168.1.41                                 32                      64                    371
        192.168.1.57                                 32                     128                      0
        192.168.1.64                                 32                     128                      1
        192.168.1.63                                 32                      64                     88
        192.168.1.254                                32                      64                      0

        In this example all the ip addresses between 192.168.1.1 and 192.168.1.254 are pinged using 
        a 20 millisecond interval between each request.
        All the addresses that reply the ping request are listed.

    .LINK
        http://gallery.technet.microsoft.com/Fast-asynchronous-ping-IP-d0a5cf0e

    #>
    [CmdletBinding(ConfirmImpact='Low')]
    Param(
        [parameter(Mandatory = $true, Position = 0)]
        [System.Net.IPAddress]$StartAddress,
        [parameter(Mandatory = $true, Position = 1)]
        [System.Net.IPAddress]$EndAddress,
        [int]$Interval = 30,
        [Switch]$RawOutput = $false
    )

    $timeout = 2000

    function New-Range ($start, $end) {

        [byte[]]$BySt = $start.GetAddressBytes()
        [Array]::Reverse($BySt)
        [byte[]]$ByEn = $end.GetAddressBytes()
        [Array]::Reverse($ByEn)
        $i1 = [System.BitConverter]::ToUInt32($BySt,0)
        $i2 = [System.BitConverter]::ToUInt32($ByEn,0)
        for($x = $i1;$x -le $i2;$x++){
            $ip = ([System.Net.IPAddress]$x).GetAddressBytes()
            [Array]::Reverse($ip)
            [System.Net.IPAddress]::Parse($($ip -join '.'))
        }
    }

    $IPrange = New-Range $StartAddress $EndAddress

    $IpTotal = $IPrange.Count

    Get-Event -SourceIdentifier "ID-Ping*" | Remove-Event
    Get-EventSubscriber -SourceIdentifier "ID-Ping*" | Unregister-Event

    $IPrange | foreach{

        [string]$VarName = "Ping_" + $_.Address

        New-Variable -Name $VarName -Value (New-Object System.Net.NetworkInformation.Ping)

        Register-ObjectEvent -InputObject (Get-Variable $VarName -ValueOnly) -EventName PingCompleted -SourceIdentifier "ID-$VarName"

        (Get-Variable $VarName -ValueOnly).SendAsync($_,$timeout,$VarName)

        Remove-Variable $VarName

        try{

            $pending = (Get-Event -SourceIdentifier "ID-Ping*").Count

        }catch [System.InvalidOperationException]{}

        $index = [array]::indexof($IPrange,$_)

        Write-Progress -Activity "Sending ping to" -Id 1 -status $_.IPAddressToString -PercentComplete (($index / $IpTotal)  * 100)

        Write-Progress -Activity "ICMP requests pending" -Id 2 -ParentId 1 -Status ($index - $pending) -PercentComplete (($index - $pending)/$IpTotal * 100)

        Start-Sleep -Milliseconds $Interval
    }

    Write-Progress -Activity "Done sending ping requests" -Id 1 -Status 'Waiting' -PercentComplete 100 

    While($pending -lt $IpTotal){

        Wait-Event -SourceIdentifier "ID-Ping*" | Out-Null

        Start-Sleep -Milliseconds 10

        $pending = (Get-Event -SourceIdentifier "ID-Ping*").Count

        Write-Progress -Activity "ICMP requests pending" -Id 2 -ParentId 1 -Status ($IpTotal - $pending) -PercentComplete (($IpTotal - $pending)/$IpTotal * 100)
    }

    if($RawOutput){

        $Reply = Get-Event -SourceIdentifier "ID-Ping*" | ForEach { 
            If($_.SourceEventArgs.Reply.Status -eq "Success"){
                $_.SourceEventArgs.Reply
            }
            Unregister-Event $_.SourceIdentifier
            Remove-Event $_.SourceIdentifier
        }

    }else{

        $Reply = Get-Event -SourceIdentifier "ID-Ping*" | ForEach { 
            If($_.SourceEventArgs.Reply.Status -eq "Success"){
                $_.SourceEventArgs.Reply | select @{
                      Name="IPAddress"   ; Expression={$_.Address}},
                    @{Name="Bytes"       ; Expression={$_.Buffer.Length}},
                    @{Name="Ttl"         ; Expression={$_.Options.Ttl}},
                    @{Name="ResponseTime"; Expression={$_.RoundtripTime}}
            }
            Unregister-Event $_.SourceIdentifier
            Remove-Event $_.SourceIdentifier
        }
    }
    if($Reply -eq $Null){
        Write-Verbose "Ping-IPrange : No ip address responded" -Verbose
    }

    return $Reply
}