前記事もヨロシク

WindowsPowerShellを使ってみる1
http://doplxyz.livedoor.biz/archives/52166964.html



ログ取り実装はバッチ処理の宿命である、コレが出来ないと「で、何が原因だったの?」が突き止められないのだ。
というわけでコレを重点的に調べる。

まず、打ち込んだコマンドだけ出力するだけならコレでいいようだ。
$LogOutputDateはオジリナル変数なので各自適当に。
保存フォルダは各自適当に。

$LogOutputDate = Get-Date -Format "yyyyMMddhhss"
Get-history > ( 'C:\Users\xxx\Desktop\仕事\script\log\' + $LogOutputDate + '.log' )


で、これををそのままps1に書き出して読み込んだらエラー。

out-file : パス 'C:\Users\xxx\Desktop\莉穂コ欺script\log\202105050320.log' の一部が見つかりませんでした。
発生場所 C:\Users\xxx\Desktop\仕事\script\ps1\logoutput.ps1:2 文字:1
+ Get-history > ( 'C:\Users\xxx\Desktop\莉穂コ欺script\log\' + $LogOutputDa ...
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+ CategoryInfo : OpenError: (:) [Out-File], DirectoryNotFoundException
+ FullyQualifiedErrorId : FileOpenFailure,Microsoft.PowerShell.Commands.OutFileCommand


原因は文字化けでピンときた、UTF-8(BOM付き)でコードを保存していなかった。
こんな所で躓くとかWindowsのデフォルト設定でPowerShell使わせる気無いだろって気分になる。

ちなみに関数化してないので直接呼び出せる。
なんかこういう所ってプログラムの良く分からん所だよね。

そもそも関数化する理由はハードコーティングを避けて出来るだけ手直し部分をへらす事だと思う。
別に毎回同じファイル名を指定する作り方でもいいんだけど同じ単語100回使ってると、それを変更する場合死ぬほど置換えないといけないし、不要文字巻き込んだ置換え事故が発生するからね。

尚ココで日付コードがミスりまくってたので修正した。


yyyyMMddhhss
👇
yyyyMMddHHmmss

function global:commandhistory {
$LogOutputDate = Get-Date -Format "yyyyMMddHHmmss"
Get-history > ( 'C:\Users\xxx\Desktop\仕事\script\log\' + $LogOutputDate + '.log' )
}


とりあえず関数化するとこう?
余計な重複を避けるため秒まで数えて保存するという安直さだけどまあ使えるべ。

で、そもそもこんな手間かけなくてもログ取りでは根本的に便利なコマンドがあって超有名どころだと
Start-Transcript
Stop-Transcript
だと思う。
これの制御が全然出来ないので頑張ろう。
企業人は難しく作り杉なんだよ・・

まず、単にコマンドだけ使うとログ吐き出し先がC:\Users\xxx\Documentsと勝手に決められてしまうのでここの制御をする必要がある。安直に組むならこれだけでよい。

Start-Transcript C:\WORK\histry.log

ただしこれだと常に同じファイルを上書きするのでスクリプトが走った時のタイムスタンプを付けて上書き防止を兼ねるならこう。

$LogOutputDate = Get-Date -Format "yyyyMMddHHmmss"
Start-Transcript ( 'C:\WORK\' + $LogOutputDate + '.log' )


もうひと工夫付けて保存先フォルダも関数化するならこう。


$LogOutputDate = Get-Date -Format "yyyyMMddHHmmss"
$HistoryLogDir = "C:\WORK\'"
Start-Transcript ( $HistoryLogDir + $LogOutputDate + '.log' )


あとはこれを関数で括るなりすればOK?
この辺りの挙動で分からないのが、関数で括った処理の中で変数組むとその処理の中でしか変数が使われないんだよね。

ある程度はps1を呼び出す前の段階で変数定義しておかないと言うこと聞いてくれないモノが出来上がりそうで次はこの辺りを制御したい。