インフラ屋とPowerShell

[インストール](http://qiita.com/_norin_/items/599718fb12ca06bb31e7)に引き続きLinuxインフラ屋的な使い方の例です。
普段はWindowsでやっていますが、Linux（のNET Core)にどうポーティングすればいいのかという点のメモも兼ねています。



#Network
##IF、MAC、IP
通常であればipコマンド(noｔ ifconfig)の出力を解析してアドレスを抜き出したりしますが、NETでは関連クラスあるのでこちらを利用します


```
PS /> [System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces() |
 foreach { Write-Host $_.name ", " $_.Addresses ", ” $_.GetPhysicalAddress() }

lo ,  127.0.0.1 ::1 ,  000000000000
eno16780032 ,  192.168.201.4 2001:db8:1::2 fe80::250:56ff:fe83:360c%eno16780032 ,  00505683360C
docker0 ,  172.17.42.1 fe80::42:73ff:fe06:40f6%docker0 ,  0242730640F6
```

System.Net.NetworkInformation.NetworkInterface名前空間の下にIFや統計情報などのクラスがありますので、ipコマンドよりこちらを利用したほうが簡単かと思います。


またGetAllNetworkInterfacesの戻り値はWindowsとLinuxで異なるため取得方法も変わります


```Text:Windows
PS C:\> [System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces().GetType()


IsPublic IsSerial Name                                     BaseType
-------- -------- ----                                     --------
True     True     SystemNetworkInterface[]                 System.Array
```


```Text:Linux
PS /> [System.Net.NetworkInformation.NetworkInterface]::GetAllNetworkInterfaces().GetType()

IsPublic IsSerial Name                                     BaseType                                                
-------- -------- ----                                     --------                                                
True     True     LinuxNetworkInterface[]                  System.Array                                            
```

IPアドレスが取得しやすいLinuxのほうが好みです:-)


#Ping
NET Core側にPingクラスが実装されているのでこちらを使います

```text:正常時
PS /> $ping = [System.Net.NetworkInformation.Ping]::new()
PS /> $ret = $ping.SendPingAsync("192.168.1.9")
PS /> $ret.Result

Status        : Success
Address       : 192.168.1.9
RoundtripTime : 0
Options       : 
Buffer        : {}
```

```Text:タイムアウト時
PS /> $ret = $ping.SendPingAsync("192.168.1.8")
PS /> $ret.Result

Status        : TimedOut
Address       : 0.0.0.0
RoundtripTime : 0
Options       : 
Buffer        : {}
```

非同期で実行されるためうまく使えばPingが並列実行できます。


#プロセス
プロセス関連のコマンドレット(Get-Process)があるのでこれを利用します
##一覧
```
PS /> Get-Process
Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
      0       0        0          0      0.010    841 841 agetty
      0       0        0          0      0.000    264   0 ata_sff
      0       0        0          0      0.570    837 837 atd
      0       0        0          0     68.950    695 695 auditd
      0       0        0          1      0.510  17362 362 bash
・・・・・
```


##名前指定
```
PS /> Get-Process -Name ovs-vswitchd

Handles  NPM(K)    PM(K)      WS(K)     CPU(s)     Id  SI ProcessName
-------  ------    -----      -----     ------     --  -- -----------
      0       0        0          3      1.100  22396 395 ovs-vswitchd
```

##ユーザ時間
```
PS /> (Get-Process -name ovs-vswitchd).TotalProcessorTime.ToString()
00:00:01.1000000
```

#ディスク
ディスクもコマンドレット(Get-PSDrive)があるのでこれを利用します

```
PS /> Get-PSDrive -name /
Name           Used (GB)     Free (GB) Provider      Root                                            CurrentLocation
----           ---------     --------- --------      ----
/                  13.80          0.10 FileSystem    /

PS /> (Get-PSDrive -name /).Used
14815723520

PS /> (Get-PSDrive -name /).Free
105512960
```


#インフラ屋的PowerShell
オブジェクト指向言語を触ったことがあれば学習コストはそれほど高くはないと思います。
逆にプログラミング経験が少なくshや設定ファイルのような従来の管理手法に慣れているととっつきにくいかもしれません。

またOSの監視用途であれば標準のコマンドレットだけでおおかた済みますが、外部コマンドの出力やログの解析などはさすがに既存のコマンド(OSS)に一日の長があります。
PowerShellに閉じた環境であれば非常に強力なのですが、外部コマンドと連携した瞬間に昔ながらの文字列解析スクリプト言語と化してしまうのでメリットが激減してしまいます。
プログラミングが必要になった時点でpythonやrubyなど他の言語を選択したほうがいいかもしれません。




#参考
.NET Frameworkクラスライブラリ
https://msdn.microsoft.com/ja-jp/library/mt472912(v=vs.110).aspx

.NET Core
https://docs.microsoft.com/en-us/dotnet/core/api/index