しばたテックブログ

気分で書いている技術ブログです。

PowerShellでNICチーミング(NetLBFO)を操作する

Windows ServerでNICチーミングを利用することがあったので調べた結果をブログにまとめます。
検証環境はWindows Server 2012 R2ですがWindows Server 2012でも同様だと思います。

NICチーミング(NetLBFO)の基本

NICチーミング(NetLBFO)の基本的な話は以下の記事に詳しいので参考にしてください。

www.atmarkit.co.jp

PowerShellでNICチーミング(NetLBFO)を操作する

PowerShellからNICチーミングを操作するにはNIC Teaming Cmdletsを使用します。
モジュールはNetLbfoですがデフォルトでロード済みなのでImport-Module NetLbfoせずに使う事ができます。

NIC Teaming Cmdletsの基本

最初にコマンドレットの一覧を出してみるとこんな感じになります。

PS C:\> Get-Command -Module NetLbfo

CommandType     Name                                               ModuleName
-----------     ----                                               ----------
Function        Add-NetLbfoTeamMember                              NetLbfo
Function        Add-NetLbfoTeamNic                                 NetLbfo
Function        Get-NetLbfoTeam                                    NetLbfo
Function        Get-NetLbfoTeamMember                              NetLbfo
Function        Get-NetLbfoTeamNic                                 NetLbfo
Function        New-NetLbfoTeam                                    NetLbfo
Function        Remove-NetLbfoTeam                                 NetLbfo
Function        Remove-NetLbfoTeamMember                           NetLbfo
Function        Remove-NetLbfoTeamNic                              NetLbfo
Function        Rename-NetLbfoTeam                                 NetLbfo
Function        Set-NetLbfoTeam                                    NetLbfo
Function        Set-NetLbfoTeamMember                              NetLbfo
Function        Set-NetLbfoTeamNic                                 NetLbfo

似た様な名前のコマンドレットが多く、初見では覚えにくいと思います。

NICチーミングの各要素がコマンドレットの名称と紐づいていますので、以下の表を参考にするとどのコマンドレットが何をするものかわかりやすくなると思います。

用語 コマンドレット上の名称 説明
インターフェイス Nic チーム上に構成される論理的なNIC。
VLANトランクのために1チームに複数インターフェイス構成可能
チーム Team 物理NICをまとめたチーム
ネットワークアダプター Member 物理NIC

また、各要素を図にするとこんな感じです。

f:id:stknohg:20160413182000p:plain

チームの作成

チームの作成にはNew-NetLbfoTeamを使います。
-Nameにチーム名、-TeamMembersにメンバーとなる物理NIC名、-TeamingModeでチーミングモード、-LoadBalancingAlgorithmで負荷分散モードを指定するのが基本です。

-TeamingModeには、

  • Lacp : LACP(Link Aggregation Control Protocol)
  • Static : 静的チーミング
  • SwitchIndependent : スイッチに依存しない

が指定できます。

-LoadBalancingAlgorithmには、

  • Dynamic : ダイナミック
  • HyperVPort : Hyper-Vのポート
  • TransportPorts : アドレスのハッシュ
  • IPAddresses : IPアドレス (GUIでは設定できず、PowerShellからのみ設定可能)
  • MacAddresses: MACアドレス (GUIでは設定できず、PowerShellからのみ設定可能)

が指定できます。

実行例は以下。

New-NetLbfoTeam -Name "Public-TEAM" -TeamMembers ("イーサネット 2", "イーサネット 3") -TeamingMode SwitchIndependent -LoadBalancingAlgorithm Dynamic

実行するとチームが作成され、同時に既定のインターフェイス(同名のインターフェイス)も作成されます。

# チームを作成
PS C:\> New-NetLbfoTeam -Name "Public-TEAM" -TeamMembers ("イーサネット 2", "イーサネット 3") -TeamingMode SwitchIndependent -LoadBalancingAlgorithm Dynamic -Confirm:$false

Name                   : Public-TEAM
Members                : {イーサネット 3, イーサネット 2}
TeamNics               : Public-TEAM
TeamingMode            : SwitchIndependent
LoadBalancingAlgorithm : Dynamic
Status                 : Down

# チーム作成と同時に同名のインターフェイスも作成される 
PS C:\> Get-NetLbfoTeamNic

Name                    : Public-TEAM
InterfaceDescription    : Microsoft Network Adapter Multiplexor Driver
Team                    : Public-TEAM
VlanID                  :
Primary                 : True
Default                 : True
TransmitLinkSpeed(Gbps) : 2
ReceiveLinkSpeed(Gbps)  : 2

# ネットワークアダプターの取得
PS C:\> Get-NetLbfoTeamMember

Name                    : イーサネット 3
InterfaceDescription    : Intel(R) PRO/1000 MT Desktop Adapter #3
Team                    : Public-TEAM
AdministrativeMode      : Active
OperationalStatus       : Active
TransmitLinkSpeed(Gbps) : 1
ReceiveLinkSpeed(Gbps)  : 1
FailureReason           : NoFailure

Name                    : イーサネット 2
InterfaceDescription    : Intel(R) PRO/1000 MT Desktop Adapter #2
Team                    : Public-TEAM
AdministrativeMode      : Active
OperationalStatus       : Active
TransmitLinkSpeed(Gbps) : 1
ReceiveLinkSpeed(Gbps)  : 1
FailureReason           : NoFailure

インターフェイスにVLAN IDを設定する

既定のインターフェイスはVLAN無しのインターフェイスになります。
このインターフェイスにVLAN IDを付与する場合はSet-NetLbfoTeamNicを使います。

以下の様に-Nameにインターフェイス名を、-VlanIDにVLAN IDを指定します。

Set-NetLbfoTeamNic -Name "Public-TEAM" -VlanID 1
# チーム名指定も可能
# Set-NetLbfoTeamNic -Team "Public-TEAM" -VlanID 1

実行するとインターフェイスにVLAN IDがセットされ、インターフェイス名も変わります。

PS C:\> Get-NetLbfoTeamNic

Name                    : Public-TEAM - VLAN 1
InterfaceDescription    : Microsoft Network Adapter Multiplexor Driver
Team                    : Public-TEAM
VlanID                  : 1
Primary                 : True
Default                 : False
TransmitLinkSpeed(Gbps) : 2
ReceiveLinkSpeed(Gbps)  : 2

VLAN IDを消したい場合は、-Defaultパラメーターを使用します。

Set-NetLbfoTeamNic -Name "Public-TEAM - VLAN 1" -Default
# チーム名指定も可能 
# Set-NetLbfoTeamNic -Team "Public-TEAM" -Default

VLANトランクを利用する(複数VLAN IDの設定)

チームに新しいインターフェイスを追加する場合はAdd-NetLbfoTeamNICを使います。
-Teamにチーム名を、-VlanIDに新しいVLAN IDを設定します。

Add-NetLbfoTeamNIC -Team "Public-TEAM" -VlanID 2

実行結果を確認すると以下の様に新しいインターフェイスが増えていることがわかります。

PS C:\> Get-NetLbfoTeamNic

Name                    : Public-TEAM - VLAN 2
InterfaceDescription    : Microsoft Network Adapter Multiplexor Driver #2
Team                    : Public-TEAM
VlanID                  : 2
Primary                 : False
Default                 : False
TransmitLinkSpeed(Gbps) : 2
ReceiveLinkSpeed(Gbps)  : 2

Name                    : Public-TEAM
InterfaceDescription    : Microsoft Network Adapter Multiplexor Driver
Team                    : Public-TEAM
VlanID                  :
Primary                 : True
Default                 : True
TransmitLinkSpeed(Gbps) : 2
ReceiveLinkSpeed(Gbps)  : 2

そして、増やしたインターフェイスを削除するにはRemove-NetLbfoTeamNicを使います。 チーム名と削除したいVLAN IDを指定します。

実行例は以下。

Remove-NetLbfoTeamNic -Team "Public-TEAM" -VlanID 2

チーミングモードや負荷分散アルゴリズムを変更する

チーミングモードや負荷分散アルゴリズムを変更するにはSet-NetLbfoTeamを使います。
パラメーターについてはNew-NetLbfoTeamと同様な感じです。

Set-NetLbfoTeam -Name "Public-TEAM" -TeamingMode Static  -LoadBalancingAlgorithm IPAddresses

実行結果の確認

PS C:\> Get-NetLbfoTeam

Name                   : Public-TEAM
Members                : {イーサネット 3, イーサネット 2}
TeamNics               : {Public-TEAM - VLAN 2, Public-TEAM}
TeamingMode            : Static
LoadBalancingAlgorithm : IPAddresses
Status                 : Degraded

チーム名を変更する

チーム名を変更するにはRename-NetLbfoTeamを使います。
こちらは説明不要でしょう。

Rename-NetLbfoTeam -Name "Public-TEAM" -NewName "Public-TEAM-New"

ネットワークアダプターの設定変更

チームの各ネットワークアダプターの設定変更(アクティブ/スタンバイ)を行うにはSet-NetLbfoTeamMemberを使います。 -AdministrativeModeActiveStandByを指定して設定変更することができます。

Set-NetLbfoTeamMember -Name "イーサネット 3" -AdministrativeMode Standby

ネットワークアダプターの追加と解除

あまり使う事はないかもしれませんが、チームにネットワークアダプターを追加するにはAdd-NetLbfoTeamMemberを、ネットワークアダプターを解除するにはRemove-NetLbfoTeamMemberを使います。

# ネットワークアダプターの追加
Add-NetLbfoTeamMember -Team "Public-TEAM" -Name "イーサネット 3" -AdministrativeMode Active
# ネットワークアダプターの解除
Remove-NetLbfoTeamMember -Team "Public-TEAM" -Name "イーサネット 3"

チームを削除する

最後にチームを削除するにはRemove-NetLbfoTeamを使います。
チームを削除すると全てのインターフェイスが削除され、ネットワークアダプターも解除されてしまうので注意してください。

Remove-NetLbfoTeam -Name "Public-TEAM"

IPアドレスの設定について

IPアドレスの設定はインターフェイスに対して行う形になりますので、各コマンドレットで指定する名称にはインターフェイス名を指定してください。

以下に適当な設定例を記載しておきます。

# IPアドレスの設定
Get-NetAdapter -Name "Public-TEAM - VLAN 2" | New-NetIPAddress -IPAddress "192.168.133.14" -PrefixLength 24 -DefaultGateway "192.168.133.1"
# DNSの指定
Set-DnsClientServerAddress -InterfaceAlias "Public-TEAM - VLAN 2" -ServerAddresses "192.168.133.2"
# IPv6のバインド停止
Get-NetAdapterBinding -Name "Public-TEAM - VLAN 2" -ComponentID ms_tcpip6 | Disable-NetAdapterBinding

最後に

NIC Teaming Cmdletsの使い方についてざっと説明しました。
GUIだと少し癖のあるチーミングの設定ですが、PowerShellからだとかなり直感的に設定できるのではないかと思います。

PowerShellでしか設定できない部分もありますので、機会があればぜひ使ってみてください。

グループポリシーオブジェクトにコメントをつける方法

グループポリシーオブジェクト(GPO)にコメントをつける事ができるのを今日初めて知りました...
凄くわかりにくかったのでメモしておきます。

はじめに

本日ちょっと複雑なポリシー設定の検証をしてて、「これを本番環境で運用するならGPOにコメント入れておきたいなー、なんとか上手い方法ないかなー?」と調べてみたら普通にコメント欄がありました。

結構昔からポリシーの設定をしてきましたが、これまでまったくその存在に気が付きませんでしたw

MSDNでの手順はグループ ポリシー オブジェクトにコメントを付けるに載っています。
これを見ればすぐわかるのですが、せっかくなので今回はスクリーンショット付きで手順を紹介することにします。

グループポリシーオブジェクトにコメントつ付ける

環境はWindows Server 2012 R2です。
まず、GPOのコメントはgpmcでGPOを選択した「詳細」タブで確認することができます。

f:id:stknohg:20160401205749p:plain

すごく、わかりにくいです...

で、このコメントはどこから付けるのかというと、グループポリシー管理エディタから設定することができます。
コメントを入れたいGPOを編集するとグループポリシー管理エディタが起動しますので、メニューの操作からプロパティを選択します。

f:id:stknohg:20160401210018p:plain

プロパティダイアログが表示され、一番右にあるコメントタブを選択するとGPOに対してコメントを設定することができます。

f:id:stknohg:20160401210118p:plain

コメントを設定すると以下の様にgpmcから確認することができます。

f:id:stknohg:20160401210157p:plain

せっかくコメントを入れることができても見つけにくいのであまり役に立たないかもしれませんね...orz

PowerShellからグループポリシーオブジェクトにコメントをつける

PowerShellからGPOにコメントを入れるのはNew-GPOコマンドレットでGPOを作成する時だけ可能です。
GPOを編集するコマンドレットが存在しないためどうしようもないのですが、たいして使う機能でもないので問題ないと思います。

以下の様にしてコメントを入れることができます。

Import-Module GroupPolicy
New-GPO -Name "開発部Policy" -Comment "適当なコメント"

各ポリシーにコメントをつける

こちらはみなさんご存知かと思いますがGPO内の各ポリシーにコメントを入れることができます。
以下設定例です。

f:id:stknohg:20160401210516p:plain

コメントを入れるとgpmcの設定欄から確認できます。

f:id:stknohg:20160401210550p:plain

こちらの方が見つけやすいので実用的ですね。

powershell.exe -Commandパラメーターの謎挙動について (解決編)

stknohg.hatenablog.jp

前のエントリの謎挙動についてですが、やっと何が起きてるかわかったので追記エントリを書きます。

解決のヒント

解決のヒントは以下の記事にありました。

Escaping in PowerShell

この記事ではPowerShellからADSIの機能を呼び出した場合について触れています。
内容を要約すると、PowerShellで文字列のエスケープが行われた後にADSI側でもエスケープされるので文字列に対してADSIのエスケープキャラクタも設定する必要があるよ、ということを言っています。

-Commandオプションの挙動について

このヒントをベースに改めてpowershell.exe -Commandオプションの挙動を調べてみたところ、-Commandパラメーターに渡された文字列は以下の流れで解釈されることがわかりました。


  1. powershell.exe -Commandを呼び出す。

  2. -Commandに指定された文字列に対しPowerShellの文字列展開および特殊文字のエスケープが行われる。

  3. エスケープ後powershell.exeが起動する。

  4. powershell.exeに引き渡された文字列は(恐らく)コンソールホストの仕様に基づいてさらに特殊文字のエスケープが行われる。

  5. エスケープ後の文字列が新しいプロセスのPowerShellエンジンによって解釈され処理の実行に移る。


4.の処理については予測が入っているのですが、挙動としてはコマンドプロンプト(cmd.exe)のエスケープ処理と同じになっています。
この点からコマンドプロントとPowerShellに共通するコンソールホスト(conhost.exe)の仕様に基づくものと予測しています。

挙動を確認してみる

前エントリの例を元に再度挙動を確認してみます。
元なるコードは変更せず以下となります。

$word='PowerShell'; Write-Output "Windows $word"

謎挙動を示すコードは以下でした。

# PowerShellコンソールからさらにPowerShellを起動
powershell.exe -Command "`$word='PowerShell'; Write-Output `"Windows `$word`""

このコードが実行されると先ずPowerShellの文字列展開およびエスケープがなされ、powershell.exeに引き渡される-Commandの内容は以下になります。

"$word='PowerShell'; Write-Output "Windows $word""

これがコンソールホストの仕様に基づいてさらに処理されます。

その内容を直接確認することは出来ないので、コマンドプロンプトからpowershell.exeを起動することで間接的にどの様な挙動をするか確認してみます。

REM コマンドプロンプトから起動
powershell.exe -Command "$word='PowerShell'; Write-Output "Windows $word""

結果は以下。

f:id:stknohg:20160330194019p:plain

見事に文字列が分割されてしまいました。

そして、コンソールホストの仕様では空白付きの文字列を\でエスケープすることができます。
"Windows $word"の部分に対して\"Windows $word"とすることで空白付き文字列を正しく認識させることがます。
この仕様については正直よくわかりません...

コマンドプロンプトから以下のコードを実行してこの動作を確認してみます。

REM コマンドプロンプトから起動
powershell.exe -Command "$word='PowerShell'; Write-Output \"Windows $word""

結果下図の様になり期待した動作をします。

f:id:stknohg:20160330194056p:plain

ですので、最終的にPowerShellで呼び出すコードは、コンソールホストによるエスケープを考慮して以下になります。

# PowerShellコンソールからさらにPowerShellを起動
powershell.exe -Command "`$word='PowerShell'; Write-Output \`"Windows `$word`""

実行するときちんと期待した動作をしてくれます。

f:id:stknohg:20160330194231p:plain

謎挙動が解決できたので嬉しい限りです。

補足

コマンドプロンプト(コンソールホスト)の文字列の展開やエスケープについてはこちらのサイトが詳しいです。

thinca.hatenablog.com

一読した印象ですが謎だらけですね...
あまり考えたくない感じです。