PowerShell は スクリプトとして良く利用します。
そのため、場合によっては 「ホスト画面 と ログに出したい!」「ホストには出さずログだけ!」「ログとthrow したい!」などと適宜変えたくなります。
そんな時にどうしようかなーと思って作ったサンプルです。
Filter を利用しよう
出力に渡す内容は、その前のコマンドレット結果全てなわけです。
つまり | %{function} というのはナンセンスで | filter と したいわけです。
function と filter の違いは、 「filter は 入ってきた入力に自動変数 $_ を割り当てて 各入力を同様に処理する」というイメージです。
function だと 入力ごとに処理をするため、| %{function} とする必要がありますが、 filter なら | filter でいいのが楽です。
Foreach-Object (%) のオーバーヘッドが無くなるので大変よろしいです。
サンプル
filter Out-LogHost{
param(
[string]
$logfile,
[switch]
$message,
[switch]
$showdata,
[switch]
$hidedata,
[switch]
$error
)
if($message)
{
Write-Host "$_`n" -ForegroundColor Cyan
"[$(Get-Date)][message][$_]" | Out-File $logfile -Encoding utf8 -Append -Width 1024
}
elseif($showdata)
{
$_
$_ | Out-File $logfile -Encoding utf8 -Append -Width 1024
}
elseif($hidedata)
{
$_ | Out-File $logfile -Encoding utf8 -Append -Width 1024
}
elseif($error)
{
$_ | Out-File $logfile -Encoding utf8 -Append -Width 1024
throw $_
}
}
このような感じでしょうか。
メッセージの例 (host に cyan色で出力しつつ、 ログに書き出す)
$log = "d:\message.log"
"hogehoge" | Out-LogHost -logfile $log -message
ホスト画面にでつつ
[office src="
https://skydrive.live.com/embed?cid=D0D99BE0D6F89C8B&resid=D0D99BE0D6F89C8B%211756&authkey=ABGDmVkIc1nElpM" width="318" height="63"]
ログもでます。
[08/14/2013 07:57:58][message][hogehoge][08/14/2013 08:05:15][message][hogehoge]
データ出力の例 (hostにださず ログだけ書き出す)
$log = "d:\hidedata.log"
ps | select -First 1 | Out-LogHost -logfile $log -hidedata
画面にでませんが、
[office src="
https://skydrive.live.com/embed?cid=D0D99BE0D6F89C8B&resid=D0D99BE0D6F89C8B%211758&authkey=AAo3dEqZUpnFAHw" width="316" height="43"]
ログに出ます。
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
264 26 5456 484 115 0.48 13276 AppleMobileDeviceHelper
データ出力の例 (hostに白文字で出力しつつ、 ログに書き出す)
$log = "d:\showdata.log"
ps | select -First 1 | Out-LogHost -logfile $log -showdata
画面にでつつ、
[office src="
https://skydrive.live.com/embed?cid=D0D99BE0D6F89C8B&resid=D0D99BE0D6F89C8B%211757&authkey=AKRmutabgONO3qI" width="315" height="57"]
ログにも出ます。
Handles NPM(K) PM(K) WS(K) VM(M) CPU(s) Id ProcessName
------- ------ ----- ----- ----- ------ -- -----------
264 26 5456 484 115 0.48 13276 AppleMobileDeviceHelper
エラー出力の例 (hostにthrowしつつ、 ログに書き出す)
$log = "d:\error.log"
try
{
ps -Name hoge -ErrorAction Stop
}
catch
{
$_ | Out-LogHost -logfile $log -error
}
ホストにエラーを表示しつつ
[office src="
https://skydrive.live.com/embed?cid=D0D99BE0D6F89C8B&resid=D0D99BE0D6F89C8B%211759&authkey=ABFXML7ewvDQn5c" width="319" height="115"]
エラーもログ出力されます。
ps : Cannot find a process with the name "hoge". Verify the process name and call the cmdlet again.
At line:4 char:5
+ ps -Name hoge -ErrorAction Stop
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : ObjectNotFound: (hoge:String) [Get-Process], ProcessCommandException
+ FullyQualifiedErrorId : NoProcessFoundForGivenName,Microsoft.PowerShell.Commands.GetProcessCommand
defaultparameterset使うの忘れてましたが、まぁまた今度で。
-Apped などもスイッチ出来るようにすると良いですね。
GitHub
挙げておきます。
https://github.com/guitarrapc/PowerShellUtil/blob/master/Out-LogHost/Out-LogHost.ps1
実はこの制御を楽にするのは意味があります。それは次回の記事で。