2011-02-28 4 views
2

몇 달 전에이 PowerShell 코드가 블로그에서 발견되었습니다. 외부 프로그램을 사용하지 않고 원하는 MAC 주소로 WOL (Wake-On-LAN) 신호를 보냅니다. 블로그 게시물에 댓글을 달았고 저자가 스크립트에 대한 궁금증 때문에 스크립트 뒤에있는 논리를 설명하도록 요청했습니다. 나중에 블로그 게시물로 돌아가서 작성자가 내 댓글에 답글을 남겼는지 확인합니다. 나는 작가가 충돌로 인해 블로그를 잃어 버렸다 고 말한 페이지로 리다이렉트되었다는 사실에 놀랐다. 나는 그것의 세부 사항을 기억할 수 없다. 그러나 나는 그 블로그를 더 이상 북마크하지 않았다고 생각하지 않는다.이 wake-on-LAN 스크립트의 작동 원리를 설명하십시오.

이제이 코드를 Stack Overflow에서 살펴보고 그 논리를 나에게 설명해달라고 요청하고 싶습니다. 각 줄에 대한 설명은 환상적 일 것입니다. 나는 이것이 어떻게 작동하는지 알고 싶어합니다. 서브넷에서 작동한다는 점에서 다른 스크립트보다 강력합니다. 네트워킹에 대해서는 많이 알지 못합니다.

내가 가장 궁금해하는 점 중 하나는 끝에있는 for 루프입니다. 신호를 여러 번 보내는 이유는 무엇입니까? 왜 다른 포트에 있습니까? 그러나 나는 전체 스크립트 뒤에있는 논리를 정말로 알고 싶습니다.

코드 :

param (
    $targetMac, 
    $network = [net.ipaddress]::Broadcast, 
    $subnet = [net.ipaddress]::Broadcast 
) 
try { 
    if($network.gettype().equals([string])) { 
     $network = [net.ipaddress]::Parse($network); 
    } 
    if($subnet.gettype().equals([string])) { 
     $subnet = [net.ipaddress]::Parse($subnet); 
    } 
    $broadcast = new-object net.ipaddress (([system.net.ipaddress]::parse("255.255.255.255").address -bxor $subnet.address -bor $network.address)) 

    $mac = [Net.NetworkInformation.PhysicalAddress]::Parse($targetMac.toupper().replace(".","")) 

    $u = New-Object net.sockets.udpclient 
    $ep = New-Object net.ipendpoint $broadcast, 0 
    $ep2 = New-Object net.ipendpoint $broadcast, 7 
    $ep3 = New-Object net.ipendpoint $broadcast, 9 

    $payload = [byte[]]@(255,255,255, 255,255,255); 
    $payload += ($mac.GetAddressBytes()*16) 

    for($i = 0; $i -lt 10; $i++) { 
     $u.Send($payload, $payload.Length, $ep) | Out-Null 
     $u.Send($payload, $payload.Length, $ep2) | Out-Null 
     $u.Send($payload, $payload.Length, $ep3) | Out-Null 
     sleep 1; 
    } 
} catch { 
    $Error | Write-Error; 
} 
+0

이 광고 http://thepowershellguy.com/blogs/posh/archive/2007/04/01/powershell-wake-on-lan-script.aspx –

답변

3
#These are the parameters to the script. The only mandatory param here is the mac address 
#[net.ipaddress]::Broadcast will resolve to something like 255.255.255.255 
param (
    $targetMac, 
    $network = [net.ipaddress]::Broadcast, 
    $subnet = [net.ipaddress]::Broadcast 
) 

#We start the try, catch error handling here. 
#if something in try block fails, the catch block will write the error 
try { 

#This will evaludate to False. Hence, $network will have whatever was passed through params or the default value 
#in this case the default value is 255.255.255.255 
    if($network.gettype().equals([string])) { 
     $network = [net.ipaddress]::Parse($network); 
    } 

#This will evaludate to False. Hence, $network will have whatever was passed through params or the default value 
#in this case the default value is 255.255.255.255  
    if($subnet.gettype().equals([string])) { 
     $subnet = [net.ipaddress]::Parse($subnet); 
    } 

    #Not sure if this is really required here. But, assuming that the default value for both $network and $subet is 255.255.255.255, 
    #this will result in $broadcast set to 255.255.255.255 
    $broadcast = new-object net.ipaddress (([system.net.ipaddress]::parse("255.255.255.255").address -bxor $subnet.address -bor $network.address)) 

#This again assumes that you had given . as the delimeter in MAC address and removes that from MAC address  
    $mac = [Net.NetworkInformation.PhysicalAddress]::Parse($targetMac.toupper().replace(".","")) 

#Create a new object of type net.sockets.udpclient 
    $u = New-Object net.sockets.udpclient 

#WOL magic packet can be sent on port 0, 7, or 9  
#Create a end point for the broadcast address at port 0  
    $ep = New-Object net.ipendpoint $broadcast, 0 

#Create a end point for the broadcast address at port 7  
    $ep2 = New-Object net.ipendpoint $broadcast, 7 

#Create a end point for the broadcast address at port 9  
    $ep3 = New-Object net.ipendpoint $broadcast, 9 

#Create a payload packet 
#First, create a byte array 
    $payload = [byte[]]@(255,255,255, 255,255,255); 

#add the mac address to the above byte array  
    $payload += ($mac.GetAddressBytes()*16) 

#Send 10 magic packets for each port number or end point created above. 
#one is more than enough. If everything is congfigured properly 
    for($i = 0; $i -lt 10; $i++) { 
     $u.Send($payload, $payload.Length, $ep) | Out-Null 
     $u.Send($payload, $payload.Length, $ep2) | Out-Null 
     $u.Send($payload, $payload.Length, $ep3) | Out-Null 
     sleep 1; 
    } 
} catch { 
#catch block catches any error from try block 
    $Error | Write-Error; 
} 
+0

정말 고마워요! 나는 또한 마술 패킷 10 개를 보내는 것이 불필요하다고 생각했다. 대본 작성자에게 이유가 있는지 궁금합니다. 오 잘. – Josh

0

위키 백과의 좋은 설명이 웨이크 - 온 - 랜 : 그 기사에서

http://en.wikipedia.org/wiki/Wake-on-LAN

발췌 :

[The Magic Packet] is typically sent as a UDP datagram to port 7 or 9, but actually it can be 
sent on any port.

패킷을 여러 번 전송하는 이유에 대한을 추측하면 비정기적인 네트워크 충돌을 설명합니다. 충돌이 발생하면 패킷을 다시 보내야합니다.

+0

통찰력을 위해 대단히 감사합니다! – Josh

+1

자세히 Wiki 링크를 읽으십시오 : "... 대상 컴퓨터의 48 비트 MAC 주소를 16 번 반복합니다 ...". –

관련 문제