目次

ファイル調査:Format-Hexの使い方メモ

2025-09-10
自分用メモ

バイナリデータの確認で「データがでかすぎてテキストエディタで開けない」というからPowerShellのFormat-Hexを使ってみては?と話したら「これでどう確認すればいいかわからない」と言われたので、やり方をサンプルで残す。

項目NAMEを文字列にする方法はファイル調査:バイト配列から文字列に変換を参照。

サンプルデータファイル

事前に確認用のサンプルデータファイル SAMPLEBIN を作る。
レコードフォーマットは固定長で、COBOLイメージだとこんな感じ。

DATA DIVISION.
         WORKING-STORAGE SECTION.
           01 DATARECORD.
              03 ID        PIC 9(4).
              03 NAME      PIC X(8).
              03 TAG       PIC 9(2).

レコード長14バイトで3レコードを格納する。つまりファイルサイズは42バイトになる。
そしてこのサンプルデータファイルはH社のホストコンピュータで作られたファイルとしよう。

E:\WK>dir SAMPLEBIN
 ドライブ E のボリューム ラベルは Backup です
 ボリューム シリアル番号は 6000-4D89 です

 E:\WK のディレクトリ

2025/09/10  20:20                42 SAMPLEBIN
               1 個のファイル                  42 バイト
               0 個のディレクトリ  878,738,391,040 バイトの空き領域

E:\WK>

項目TAGの値の調査をする

プログラムが異常終了したと連絡があり、どうも項目TAGを処理して問題が起きたようだと説明されたとする。

項目TAGはレコード先頭から12バイト目に2バイトで格納される数値項目と分かるので、この内容が正しいか確認する事になる。
また、3レコード有るので、各レコードに問題がないか確認していくことになる。

つまり項目TAGは

となる。

PowerShell 7.5.xの場合

クライアントPCだとPowerShell 7.5.x になっていることが多いのではないだろうかと思う。この場合Format-Hexコマンドレットは必要なオプションを備えているので面倒が少ない。

Format-Hex の -Offset オプションでHexダンプ(16進数ダンプ)の表示開始位置を指定し、-Count オプションで、表示するバイト数を指定する。

つまり項目TAGは

となる。

PS E:\WK> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      7.5.2   ←面倒じゃないバージョンだ!
PSEdition                      Core
GitCommitId                    7.5.2
OS                             Microsoft Windows 10.0.22631
Platform                       Win32NT
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0…}
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1
WSManStackVersion              3.0

PS E:\WK> Format-Hex -Path SAMPLEBIN -Offset 0 -Count 14  ← 1レコード目の表示指定

   Label: E:\WK\SAMPLEBIN

          Offset Bytes                                           Ascii
                 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
          ------ ----------------------------------------------- -----
0000000000000000 F0 F0 F1 F0 8E C4 8C A2 81 40 81 40 F0 F0       ððñð�Ä�¢�@�@ðð  ← 項目TAGの値は 0xF0,0xF0 EBCDICで"00"の意

PS E:\WK> Format-Hex -Path SAMPLEBIN -Offset 14 -Count 14  ← 2レコード目の表示指定

   Label: E:\WK\SAMPLEBIN

          Offset Bytes                                           Ascii
                 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
          ------ ----------------------------------------------- -----
000000000000000E F0 F0 F2 F0 8E C4 8C A2 81 40 81 40 C2 C1       ððòð�Ä�¢�@�@ÂÁ  ← 項目TAGの値は 0xC2,0xC1 EBCDICで"BA"の意

PS E:\WK> Format-Hex -Path SAMPLEBIN -Offset 28 -Count 14  ← 3レコード目の表示指定

   Label: E:\WK\SAMPLEBIN

          Offset Bytes                                           Ascii
                 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F
          ------ ----------------------------------------------- -----
000000000000001C F0 F0 F3 F0 93 79 8D B2 8C A2 81 40 E9 E9       ððóð�y�²�¢�@éé  ← 項目TAGの値は 0xE9,0xE9 EBCDICで"ZZ"の意

PS E:\WK>

2レコード目、3レコード目の項目TAGは数字のみで構成されていないのでエラーの原因はこの2レコードでしょう。

PowerShell 5.1.xの場合

サーバだとこのバージョンになっている物も多いんじゃないかなと思う。この場合Format-Hexコマンドレットだけでは対応できないので工夫する必要がある。

ファイル内容をバイト配列として保存し、配列の範囲を Format-Hex へ与えてHexダンプ(16進数ダンプ)させる。配列の開始インデクス、終了インデクスを与える必要がある。

つまり項目TAGは

となる。

PS E:\WK> $PSVersionTable

Name                           Value
----                           -----
PSVersion                      5.1.22621.5697  ← アー面倒なバージョンだ…
PSEdition                      Desktop
PSCompatibleVersions           {1.0, 2.0, 3.0, 4.0...}
BuildVersion                   10.0.22621.5697
CLRVersion                     4.0.30319.42000
WSManStackVersion              3.0
PSRemotingProtocolVersion      2.3
SerializationVersion           1.1.0.1


PS E:\WK> $bindata = Get-Content -Path SAMPLEBIN -Raw -Encoding Byte  ← ファイルをバイト型配列としてメモリに確保する。
PS E:\WK> $bindata[0..13] | Format-Hex  ← 1レコード目の表示指定


           パス:

           00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000   F0 F0 F1 F0 8E C4 8C A2 81 40 81 40 F0 F0        ððñðÄ¢@@ðð  ← 項目TAGの値は 0xF0,0xF0 EBCDICで"00"の意


PS E:\WK> $bindata[14..27] | Format-Hex  ← 2レコード目の表示指定


           パス:

           00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000   F0 F0 F2 F0 8E C4 8C A2 81 40 81 40 C2 C1        ððòðÄ¢@@ÂÁ  ← 項目TAGの値は 0xC2,0xC1 EBCDICで"BA"の意


PS E:\WK> $bindata[28..41] | Format-Hex  ← 3レコード目の表示指定


           パス:

           00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000   F0 F0 F3 F0 93 79 8D B2 8C A2 81 40 E9 E9        ððóðy²¢@éé  ← 項目TAGの値は 0xE9,0xE9 EBCDICで"ZZ"の意


PS E:\WK>

2レコード目、3レコード目の項目TAGは数字のみで構成されていないのでエラーの原因はこの2レコードでしょう。