Powershellでの作業記録の取り方

何らかの作業を行うときに、エビデンスや証跡と言われる作業記録を要求されることがある。自分が何をやってどうなったかを記録することは大事だ。取得するデータはおおよそ以下の二種類になる。

* コマンドの実行結果 - コマンドを実行した結果のデータ
* コマンドの履歴 - コマンドを実行した履歴のデータ

もちろん、どのようなデータを取得するのか前もって計画を立てておく必要がある。オペレーションを行った全記録としてコマンドの履歴だけを取ったとしても、後から見直した時に何をやった記録なのか分からなくなる。記録は後から見直して分かるように、目的と取得したデータを紐付けて取得しましょう。

### コマンドの実行結果
コマンドを実行したときに出力された内容をファイルに出力したもの。出力された内容をファイルに保存する方法はいくつかある。

* リダイレクトでファイルに出力する
* コマンドの出力をエクスポートする
* コマンドで出力を記録する

リダイレクトでファイルに出力するのは、主に単発のコマンドのケースだ。プロセスがいくつもあるような作業にはあまり向かない。Powershellでは、標準でデータをCSVやJSONにコンバートできる。また、エクスピートしたデータを再度、インポートして、作業のデータを引き継ぐことができる。

この他に、画面に出力された内容を選択してコピペで保存するというのがあるが、説明は省く。

### コマンドの履歴
Powershell では Bash 等のUnix系のシェルと同様に、コマンドの履歴を自動で保存する機能がある。

・ history.txtへの履歴の自動保存
・ Get-History

Powershellを起動して実行したコマンドは、すべて history.txt に保存される。履歴をコマンドで出力する場合は、Get-History を使用する。コマンドの出力は保存されない。

# コマンドの実行結果を記録するる方法について
### リダイレクトでファイルに出力する
実行した内容をそのままテキストに出力するには > (リダイレクト)を使う。オーソドックスな方法。

```powershell
[コマンド] > [テキストファイル]
```

コマンドの後に > をつけて出力するテキストファイルを指定する。コマンドを実行して画面に出力される内容が、テキストファイルに保存される。Unix系のコマンドとほぼ同じ動きをする。

```powershell
PS > echo "うに" > test.txt
PS > Get-Content test.txt
うに
```

リダイレクトされたテキストファイルは上書きされる。もし追記させたければ、>> でリダイレクトする。もともと保存されているテキストの末尾に、コマンドを実行して画面に出力される内容がファイルに追記される。

```powershell
PS > echo "うに" >> test.txt
```

リダイレクトを使用すると、コマンドの実行結果は画面に表示されない。画面にも表示したい場合は、Tee-Objectを使用する。

```powershell
PS > echo "うに" | Tee-Object test.txt               # 上書き
うに
PS > Get-Content test.txt
うに
PS > echo "ばふんうに" | Tee-Object test.txt -Append # 追記
ばふんうに
PS > Get-Content test.txt
うに
ばふんうに
```

履歴を保存するファイルのパスは、変数に保存したパスで指定することもできる。ファイルが存在しない場合、ファイルが新規に作成される。

```powershell
PS > $Output_File = c:\tmp\History.txt  # 保存するファイルのパスを変数に入れる
PS > echo "うに" > $Output_File         # c:\tmp\History.txt に出力が保存される
PS > Get-Content $Output_File
うに
```
### コマンドの出力をエクスポートする
Powershellには、コマンドを実行した結果をCSV、JSON、XMLなどで出力するコマンドがある。

* Export-CSV
* Export-Clixml

・・・等々、 **Export** から始まるコマンドレットは、コマンドから直接ファイルを生成して、

* ConvertTo-csv
* ConvertTo-Json　

・・・等々 **Convert** から始まるコマンドレットは、文字列でデータを出力するとう違いがある。

コマンドの出力をこれらのコマンドにパイプで渡す。オプションに付けたファイルに出力が保存される。

```powershell
# Export-CSV の例
<コマンド> | Export-Csv <ファイル名>.csv
```

画面に出力されるアウトプットをCSVにフォーマットするので、表示されていないデータは保存されない。出力されたCSVはExcel等でそのまま読み込むことができる。

### コマンドの実行結果をxmlファイルに保存
コマンドの出力を Export-Clixml にパイプで渡すことで、xml型式 のファイルでコマンドの出力内容を保存することができる。出力した xmlファイル をそのまま使用するより、Import-Clixmlでインポートして使う。

Import-Clixml で読み込んだデータを変数に保存すると、Export-Clixml でエクスポートしたコマンドの出力と同じデータが復元できる。用途としては、変数のデータやコマンドの出力をバックアップデータとしてファイルに保存したい時に使用する。

変数やコマンドのデータを再利用したい時や、とりあえずデータだけ取得して、別の端末で加工をしたい場合などにこの方法を使うと便利だ。

```powershell
<コマンド> | Export-Clixml <ファイル名>.xml
```

以下のコマンドで出力した xml ファイルをインポートする。

```powershell
Import-Clixml <ファイル名>.xml
```

インポートすると、エクスポートされた出力が表示される。出力を変数に入れたり、パイプを通して加工して活用する。

### 画面に出力される内容をファイルに記録する

テキストの記録を開始するときと終了するときに以下のコマンドを実行する。

> Start-Transcript → 記録開始
> Stop-Transcript  → 記録終了

**記録開始**

```powershell
> Start-Transcript
トランスクリプトが開始されました。出力ファイル: [カレントパス]\PowerShell_transcript.HORUS.Wm+ZpDyv.[日時].txt
```

コマンドの実行後、記録が開始される。

**記録終了**

```powershell
> Stop-Transcript
トランスクリプトが停止されました。出力ファイル: [カレントパス]\Documents\PowerShell_transcript.HORUS.Wm+ZpDyv.[日時].txt
```

コマンドの実行後、記録が停止される。保存したテキストファイルのヘッダーには色々な情報が記録されている。出力されたファイルのヘッダーは以下のようになっている。

**出力内容**

```Powershell
**********************
Windows PowerShell トランスクリプト開始
開始時刻: 20200111180312
ユーザー名: [ユーザ]
RunAs ユーザー: [ユーザ]
構成名: 
コンピューター: [ホスト名] (Microsoft Windows NT 10.0.18362.)
ホスト アプリケーション: C:\Windows\System32\WindowsPowerShell\v1.0\powershell.exe
プロセス ID: 13508
PSVersion: 5.1.18362.145
PSEdition: Desktop
PSCompatibleVersions: 1.0, 2.0, 3.0, 4.0, 5.0, 5.1.18362.145
BuildVersion: 10.0.18362.145
CLRVersion: 4.0.30319.42000
WSManStackVersion: 3.0
PSRemotingProtocolVersion: 2.3
SerializationVersion: 1.1.0.1
**********************
```
記録の開始時間、終了時間、ホスト名等の情報が自動で記入される。

# コマンドの実行履歴の保存
### 実行履歴が記録されているファイル
Powershellでコマンドを実行すると、実行したコマンドが履歴としてテキストファイルに出力されて保存される。保存されるファイルの場所は、以下のコマンドを実行して確かめることができる。

```powershell
(Get-PSReadLineOption).HistorySavePath
```

また、以下のコマンドで出力場所の変更もできるようです。

```powershell
 Set-PSReadLineOption -HistorySavePath [変更先のファイルパス]
```
ただし、一回プロンプトを閉じると、デフォルトの場所に戻ります。

### コマンドで履歴を表示する
**Get-history**のコマンドで、コマンドの実行履歴を表示できる。

```powershell
PS C:\Users\Main> Get-History

  Id CommandLine
  -- -----------
   1 Get-History
   2 Get-History
```

Get-History のみで取得できる情報として、プロパティを指定することでコマンドの実行履歴や実行時間、終了時間のデータも表示できる。

| 項目               | 内容 |
|:-------------------|:-------------|
| ExecutionStatus    | コマンドの実行結果 |
| StartExecutionTime | コマンドの実行開始時刻 |
| EndExecutionTime   | コマンドの実行終了時刻 |

Select-Object　* で全てのプロパティを表示すると、これらの情報が表示される。

```powershell
PS C:\Users\Main> Get-History | Select-Object *


Id                 : 1
CommandLine        : Get-History | Select-Object *
ExecutionStatus    : Completed
StartExecutionTime : 2020/01/16 19:54:41
EndExecutionTime   : 2020/01/16 19:54:41

Id                 : 2
CommandLine        : Get-History | Select-Object *
ExecutionStatus    : Completed
StartExecutionTime : 2020/01/16 19:54:43
EndExecutionTime   : 2020/01/16 19:54:43
```

Getコマンドの実行履歴と出力の履歴を組み合わせれば、いつどのようなデータを取得したのかを確実に記録することができる。また、PSObjectで出力されるため、CSVデータなどで簡単に保存することができる。