2013-07-24 38 views
1

因此,我寫了一個簡單的pinger ping所有的網絡。我正在使用測試連接,但我也得到了設計名稱。電源外殼測試連接,然後獲取計算機名稱或mac-addr

所以我用了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 
} 

回答

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是在你的處置,不只是本地cmdlets和Windows命令
  • 是否使用像$這樣的內置運算符?
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了,並不是因爲我認爲答案是比任何其他的更好或更壞,而是因爲我覺得你證明有很多,很多方法可以做到這(這真是我答案的核心所在)。 –

0

Test-ConnectionTest-NetConnection現在支持返回的更多信息,包括姓名。後者需要電源外殼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

另外,你提到你正在p​​ing整個網絡。這就是發現你的問題的原因之一,因爲我正在嘗試進行ping掃描。我處理這個腳本。這傢伙稱它爲Fast Ping Sweep Asynchronous

即使是Power Shell n00b,我也能夠管輸出,然後修改它的輸出以僅包含我想要的內容。我遇到了其他腳本,但無法破譯他們的腳本來修改它們以達到我的目的。

我不確定Power Shell需要哪個版本,但它適用於v4和v5。

我見過最PowerShell的IP掃描儀,ping掃描腳本 但它們都沒有使用PingASync method.The「問題」與 同步腳本是他們必須要等到一個節點回復或 倍然後繼續下一個地址。使用這種方法可以 ,以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 
}