概要

Wakeup-Computer.ps1は同一ネットワークにあるコンピュータをWake on LAN(WoL)を用いて起動するためのPowerShellスクリプトです。
同梱のExport-MacAddress.ps1を使用することでコンピュータのMACアドレスを収集し、ファイルに保存することができます。このファイルはWakeup-Computer.ps1を実行するのに用いることができます。

リモートシャットダウンはこちらのスクリプトをご利用ください。
http://gallery.technet.microsoft.com/scriptcenter/d578bb1c-380e-4442-b967-4f5f50ca3d49

システム要件

スクリプト

※すべて「各対象をWoLで起動させるコンピュータ」上で作業をおこなってください。
※すべてのファイルは同一フォルダに保存し、実行はそのフォルダをカレントにして行います。
※まずはPowerShellスクリプトを実行可能にしてください。
http://www.atmarkit.co.jp/fwin2k/operation/pshsys01/pshsys01_04.htmlなどを参考にしてください。

 Export-MacAddress.ps1

PowerShell
param($path="macAddresses.txt",$ouDN,$computer,[switch]$append,[switch]$includeSelf,[switch]$includeOtherNetwork,$credentialfunction Get-NetworkAddress 
{ 
    param([string]$ipAddress,[string]$subnetMask) 
    $ip=[int[]]($ipAddress.Split(".")) 
    $mask=[int[]]($subnetMask.Split(".")) 
    $network=@() 
    for($i=0;$i -le 3;$i++) 
    { 
        $network += ($ip[$i-band $mask[$i]) 
    } 
    [string]::join(".",$network) 
} 
 
if($computer -eq $null) 
{ 
    if($ouDN -eq $null) 
    { 
        $ouDN=Read-Host -Prompt "MACアドレスを取得するPCのOUまたはコンテナの識別名(DN)を入力してください(省略するとComputersコンテナの全PCのMACアドレスを取得)"  
    } 
 
    if($ouDN -eq "") 
    { 
        $ouDN="CN=Computers," + ([adsi]"LDAP://rootDSE").defaultNamingContext[0] 
    } 
 
    $computers=[adsi]("LDAP://" + $ouDN) 
    $hostNames=@($computers.Children|?{$_.ObjectClass -eq "computer"}| 
    %{ 
        if($_.dNSHostName[0] -eq $null) 
        { 
            $_.name[0] 
        } 
        else 
        { 
            $_.dNSHostName[0] 
        } 
    }) 
} 
else 
{ 
    $hostNames=@($computer) 
} 
 
if($credential -ne $null) 
{ 
    if($credential -is [System.Management.Automation.PSCredential]) 
    { 
    } 
    elseif($credential -is [string]) 
    { 
        $credential=Get-Credential $credential 
    } 
    else 
    { 
        throw "-credentialには文字列(ユーザー名)またはPSCredentialオブジェクトを指定してください。" 
        exit 
    } 
} 
 
$nics=Get-WmiObject -class Win32_NetworkAdapterConfiguration -Filter "IPEnabled=true" 
 
foreach($nic in $nics) 
{ 
    $myIp=$nic.IPAddress[0] 
    $myMask=$nic.IPSubnet[0] 
    $myNetworkAddress=Get-NetworkAddress $myIp $myMask 
} 
 
$logFile="macAddresses_log.txt" 
$out=@() 
$log=@() 
 
 
foreach($hostName in $hostNames) 
{ 
    $isSelf=[environment]::machinename,".",$myIp,"localhost","127.0.0.1" -contains $hostName 
     
    if($credential -eq $null -or $isSelf ) 
    { 
        $nics=Get-WmiObject -ComputerName $hostName -class Win32_NetworkAdapterConfiguration -Filter "IPEnabled=true"  -errorAction SilentlyContinue -ErrorVariable e  
          
    } 
    else 
    { 
        $nics=Get-WmiObject -ComputerName $hostName -class Win32_NetworkAdapterConfiguration -Filter "IPEnabled=true"  -errorAction SilentlyContinue -ErrorVariable e -credential $credential 
    } 
    
    if($e[0] -ne $null) 
    { 
        $message="," + $hostName + ",,NG," +  $e[0].exception.message 
        $message 
        $log+=$message 
        continue 
    } 
     
    if($nics -ne $null) 
    { 
        foreach($nic in $nics) 
        { 
            $ip=$nic.IPAddress[0] 
            $mask=$nic.IPSubnet[0] 
            $network=Get-NetworkAddress $ip $mask 
            if($myIp -eq $ip -and $myMask -eq $mask -and !$includeSelf) 
            { 
                $message=$ip + "," + $hostName + "," + $nic.MACAddress + ",NG,このコンピュータなので除外します。" 
                $message 
                $log+=$message 
                break 
            } 
            elseif($network -eq $myNetworkAddress -or $includeOtherNetwork) 
            { 
                $macAddress=$hostName + "," + $ip + "," + $nic.MACAddress 
                $message=$ip + "," + $hostName + "," + $nic.MACAddress + ",OK,追加しました。" 
                $message 
                $log+=$message 
                $out+$macAddress 
                break 
            } 
            else 
            { 
                $message=$ip + "," + $hostName + "," + $nic.MACAddress + ",NG,このコンピュータとネットワークアドレスが異なるので除外します。" 
                $message 
                $log+=$message 
            } 
        } 
    } 
} 
 
if($append) 
{ 
    $out|Add-Content $path 
} 
else 
{ 
    $out|Set-Content $path 
} 
$log|Add-Content $logFile 
 
if($out.length -eq 0) 
{ 
    "対象がありませんでした。" 
} 
else 
{ 
    "$path にMACアドレス一覧を出力しました。 $logFile にログを出力しました。" 
} 
 
 
 

構文

Export-MacAddress.ps1 [-path MACアドレスリストファイル] [-ouDN 対象OUのDN] [-append] [-includeSelf] [-includeOtherNetwork] [-credential 資格情報]

Export-MacAddress.ps1 [-path MACアドレスリストファイル] -computer 対象コンピュータ名(複数可) [-append] [-includeSelf] [-includeOtherNetwork] [-credential 資格情報]


説明

MACアドレスの情報をWMIを用いて取得し、結果をテキストファイルに出力します。テキストファイルの書式は以下の通り(文字コードはShift_JIS)。

コンピュータ名,IPアドレス,MACアドレス

WMIが使用できない場合は手動で編集してもOKです。その場合は各コンピュータ上でipconfig /allなどでMACアドレスを調べると良いでしょう。

実行するとログがmacAddresses_log.txtに追記されます。


パラメータ

-path <string>
出力するMACアドレスリストファイルのファイル名を指定します。省略時はmacAddresses.txt。

-ouDN <string>
MACアドレスを収集したいコンピュータが属しているOUのDN(識別名)を指定します。省略時はComputersコンテナ。

-computer <string[]>
MACアドレスを収集したいコンピュータ名を指定します。,で区切って複数指定可能。

-append [<SwitchParameter>]
このパラメータを指定すると-pathで指定したファイルに追記します。省略すると既存のファイルは上書きされます。

-includeSelf [<SwitchParameter>]
このパラメータを指定するとこのスクリプトを実行したコンピュータのMACアドレスも出力します。省略時は出力しません。

-includeOtherNetwork [<SwitchParameter>]
このパラメータを指定するとこのスクリプトを実行したコンピュータと異なるネットワークにあるコンピュータのMACアドレスも出力します。。省略時は出力しません。

-credential <object>
WMIでMACアドレスを取得するのに必要な資格情報を指定します。PSCredentialオブジェクトもしくはユーザー名の文字列を指定可能です。文字列の場合はパスワードを入力するダイアログが表示されます。


使用例

PowerShell
PS> .\Export-MacAddress.ps1 -path out.txt -ouDN "OU=test,DC=winscript,DC=local" -includeSelf 
 
 

winscript.localドメイン内のtestというOUに属するコンピュータのMACアドレスをout.txtに出力します。testにこのスクリプトを実行したコンピュータが含まれていた場合、そのコンピュータのMACアドレスも出力します。

PowerShell
PS> .\Export-MacAddress.ps1 -computer server01,pc01,pc02 -append -credential user 
 
 

server01,pc01,pc02という名前のコンピュータのMACアドレスを取得します。その際userというユーザー名でアクセスを試みます。なお、これらの対象コンピュータは電源が入っている必要があります。結果はmacAddresses.txtに保存され、既存の場合は追記されます。

 Wakeup-Computer.ps1

PowerShell
param($path="macAddresses.txt",$macAddress,[switch]$broadCast) 
 
if($macAddress -eq $null) 
{ 
    $lines=@(Get-Content $path) 
} 
else 
{ 
    $lines=@() 
    @($macAddress)| 
    %{ 
        $lines+",," + $_ 
    } 
    $broadCast=$true 
} 
 
$header=[byte[]](@(0xFF)*6) 
 
$lines|?{$_ -ne ""}| 
%{ 
    $cols=$_.split(",") 
    $macAddress=[byte[]]($cols[2].split(":")|%{ [Convert]::ToInt32($_, 16)}) 
    $magicPacket=$header + $macAddress * 16 
     
    $client=new-object System.Net.Sockets.UdpClient 
    if($broadCast) 
    { 
        $target=[System.Net.IPAddress]::Broadcast 
    } 
    else 
    { 
        $target=[System.Net.IPAddress]::Parse($cols[1]) 
    } 
    $client.Connect($target,2304) 
 
    $client.Send($magicPacket,$magicPacket.Length)|out-null 
    $client.Close() 
    $target.ToString() + " に "  + $cols[0] + " ("  + $cols[2] +  ") 宛のマジックパケットを送信しました。" 
} 
"終了しました。" 
 
 

構文

Wakeup-Computer.ps1 [[-path] MACアドレスリストファイル] [-broadCast]

Wakeup-Computer.ps1 -macAddress MACアドレス(複数指定可)


説明

指定したMACアドレスに対応するマジックパケットを送信し、対象のコンピュータのWake on LANでの起動を試みます。
Export-MacAddress.ps1で作成したMACアドレスリストファイルを指定するか、直接MACアドレスを指定します。
-broadCastパラメータを使用することでブロードキャストアドレスに対してマジックパケットを送信することができます。
-broadCastパラメータを使用しない場合は-pathで指定されたファイルに記述されているIPアドレスに送信します。この場合、対応ルーターを用いてWAN越しにWoLすることができます。UDP2304番をブロードキャストアドレスにポートフォワードしてください。


パラメータ

-path <string>
MACアドレスリストファイルのファイル名を指定します。省略時はmacAddresses.txt。

-broadCast [<SwitchParameter>]
このパラメータを指定すると、マジックパケットをブロードキャストアドレスに対して送信します。省略時は-pathで指定されたファイルに記述されているIPアドレスに対して送信します。

-macAddress <string[]>
マジックパケットを送信したいMACアドレスを指定します。,で区切って複数指定可能。このパラメータを指定した場合は常にマジックパケットをブロードキャストアドレスに対して送信します。


使用例

PowerShell
PS> .\Wakeup-Computer.ps1 -path out.txt -broadCast 
 
 

out.txtに含まれるMACアドレスに対応するマジックパケットをブロードキャストアドレスに対して送信します。

PowerShell
PS> .\Wakeup-Computer.ps1 -macAddress "00:00:00:FF:FF:FF","00:00:00:00:FF:FF" 
 
 

"00:00:00:FF:FF:FF"と"00:00:00:00:FF:FF"に対応するマジックパケットをブロードキャストアドレスに対して送信します。

ダウンロード

wakeup-computer.zip