【実務・中級編】【上級プロフェッショナル向け】FSOとNTFSオルタネート・データ・ストリーム(ADS)を組み合わせた隠しメタデータの読み書き – VBScript (Visual Basic Scripting Edition)解析バイブル

スポンサーリンク

VBScriptを掌握する極限の知見:FSOとNTFSオルタネート・データ・ストリーム(ADS)による極秘メタデータ管理

こんにちは。プロフェッショナル・自動化エンジニアの私だ。
これまで数々のレガシーシステムやWindows環境における自動化の極限を追求してきたが、今回はVBScriptとNTFSの深淵、オルタネート・データ・ストリーム(Alternate Data Stream: ADS)を組み合わせた高度なファイル管理手法を伝授しよう。

一般的な業務ツール開発では、ファイルに付随するメタデータ(処理ステータスやバージョン情報、最終処理日時など)を保存するために、わざわざ別ファイルのJSONやINIを用意したり、あるいはSQLiteなどのデータベースを同居させたりしがちだ。

だが、それは愚策だ。
ファイルが移動・コピーされた際にメタデータがロストするリスクを抱え、ファイル管理の整合性を自ら崩しているに等しい。

WindowsのNTFSファイルシステムが標準で備えるADSを使用すれば、「見た目はただの1つのファイル」の中に、無限の隠しデータを直接串刺しにして保持できる。今回は、`Scripting.FileSystemObject`(FSO)の限界を超え、このADSをVBScriptで完璧に制御するプロダクションコードを公開する。

—

なぜ通常のFSOだけではADSを扱えないのか?

VBScriptの `Scripting.FileSystemObject` は非常に優秀だが、実は設計が古く、NTFSのADS(例: `file.txt:metadata`)を直接ネイティブに作成・読み込みする専用メソッドを持っていない。

FSOの `CreateTextFile` や `OpenTextFile` に直接ストリーム構文を渡しても、環境やパスの解釈によってエラーを起こすか、通常のファイルとして扱われてしまうことがある。

ここで、我々プロフェッショナルは、FSOのファイルストリーム機能(`OpenAsTextStream`)、あるいはWindows標準のADODBストリーム(`ADODB.Stream`)をFSOによるファイル存在確認と組み合わせることで、この壁を完全に突破する。

堅牢な設計における3つの鉄則

1. ストリーム名の規約化: 自由奔放にストリームを生やすと管理不能になる。`filename.ext:StreamName` の命名規則を厳格化する。
2. 存在しないストリームへの耐性: 存在しないADSを読みに行った際のエラーハンドリングを怠らない。
3. ファイル本体への依存性: 大前提として、親ファイルが削除されればADSも消滅する。この特性を「ゴミを残さない自動クリーンアップ機能」として逆手に取る。

—

プロダクションコード:ADS読み書きエンジン

以下のコードは、実務の現場でそのまま組み込める、堅牢性を極めたVBScriptのモジュールだ。指定したファイルに対し、目に見えないメタデータ(JSON風のキーバリュー)を安全に読み書きする。

Option Explicit

‘ ==============================================================================
‘ 処理名: NTFSオルタネート・データ・ストリーム(ADS) 管理クラス
‘ 概要 : FSOとADODB.Streamを融合させ、ファイル内部に隠しメタデータを刻み込む
‘ ==============================================================================

Dim targetFile, streamKey, metaData
targetFile = “C:\Automation\WorkData.xlsx”
streamKey = “ProcessInfo”

‘ — 1. メタデータの書き込みテスト —
Call WriteMetadataToADS(targetFile, streamKey, “Status=Completed;CheckedBy=SystemAdmin;Timestamp=” & Now)

‘ — 2. メタデータの読み込みテスト —
metaData = ReadMetadataFromADS(targetFile, streamKey)
WScript.Echo “【ADS読み出し成功】” & vbCrLf & metaData

‘ ==============================================================================
‘ 関数名: WriteMetadataToADS
‘ 概要 : 指定ファイルのADSに文字列を書き込む
‘ ==============================================================================
Sub WriteMetadataToADS(filePath, sKey, dataContent)
Dim fso, fullAdsPath, adoStream
Set fso = CreateObject(“Scripting.FileSystemObject”)

‘ 親ファイルが存在しない場合は処理を中断(フェイルファストの原則)
If Not fso.FileExists(filePath) Then
Err.Raise 53, “ADS_Writer”, “対象ファイルが存在しません: ” & filePath
End If

‘ NTFS ADSのパス構文を構築 (例: C:\dir\file.ext:StreamName)
fullAdsPath = filePath & “:” & sKey

‘ VBScript標準のFSOテキスト出力はADSに対して文字コード競合を起こすため、
‘ バイナリ・テキスト制御に強い ADODB.Stream を採用する
Set adoStream = CreateObject(“ADODB.Stream”)
With adoStream
.Type = 2 ‘ 2 = adTypeText (テキストデータ)
.Charset = “UTF-8”
.Open
.WriteText dataContent
.SaveToFile fullAdsPath, 2 ‘ 2 = adSaveCreateOverWrite (上書き保存)
.Close
End With

Set adoStream = Nothing
Set fso = Nothing
End Sub

‘ ==============================================================================
‘ 関数名: ReadMetadataFromADS
‘ 概要 : 指定ファイルのADSから隠しデータを安全に読み出す
‘ ==============================================================================
Function ReadMetadataFromADS(filePath, sKey)
On Error Resume Next

Dim fso, fullAdsPath, adoStream, content
Set fso = CreateObject(“Scripting.FileSystemObject”)

If Not fso.FileExists(filePath) Then
ReadMetadataFromADS = “”
Exit Function
End If

fullAdsPath = filePath & “:” & sKey

‘ ADSが存在するか確認するため、一時的にFSOでファイルとして開けるかチェック
‘ (※ADSは通常のFileExistsでは判定できないため、ADODBのオープン成否で判定)
Set adoStream = CreateObject(“ADODB.Stream”)
With adoStream
.Type = 2
.Charset = “UTF-8”
.Open
.LoadFromFile fullAdsPath

If Err.Number <> 0 Then
‘ ストリームが存在しない、または読み込めない場合
ReadMetadataFromADS = “[No Metadata Found]”
Err.Clear
.Close
Exit Function
End If

content = .ReadText
.Close
End With

On Error GoTo 0
ReadMetadataFromADS = content

Set adoStream = Nothing
Set fso = Nothing
End Function

—

現場で役立つアーキテクトからの助言・注意点

1. ファイルサーバー(NAS)やネットワーク共有フォルダでの挙動

このADSはあくまでNTFSの機能である。
もしあなたの自動化スクリプトが参照する保存先が、LinuxベースのNASやSamba、あるいは exFAT / FAT32 形式のUSBメモリである場合、ADSのデータは完全に消失(または無視)される。
プロダクション環境に導入する際は、必ずストレージのファイルシステムが「NTFS」または「ReFS」であることを前提条件(環境要件)に含めなければならない。

2. セキュリティソフト・ウイルス対策ソフトへの配慮

高度なセキュリティ製品の中には、ファイルに紐づく未知のADS(特に実行可能コードや不審なテキストが隠されている場合)を検知・隔離・削除の対象にするものがある。
メタデータとして平文や暗号化文字列を保存する分には問題ないが、実務で採用する際は、社内のセキュリティチームに「NTFS ADSを独自管理台帳として利用している」旨をあらかじめ共有しておくことが、エンジニアとしてのリスクヘッジだ。

3. エクスプローラーや通常のファイル操作での不可視性

この手法の最大のメリットであり、同時にリスクでもあるのが「ユーザーが普通にファイルを覗いても見えない」という点だ。
意図せずユーザーがファイルをメール添付したり、デスクトップにコピーしたりした際、ADSデータも一緒に運ばれる(※NTFS環境間のコピーであれば保持される)。
しかし、ZIPファイルに圧縮して固めた場合、標準のZIPアーカイバはADSを無視してファイル本体しか圧縮しないケースが多いため、「アーカイブ化するとメタデータが消える」という特性を設計に織り込んでおく必要がある。

—

総括

VBScriptという一見古びた言語であっても、Windowsの深部(NTFS仕様)を正しく理解し、FSOとADODB.Streamを適切に組み合わせれば、モダンなアプリケーション顔負けの高度なメタデータ管理システムを構築できる。

安易に外部ファイルやDBに頼らず、ファイルそのものに文脈(メタデータ)を宿らせるこのテクニックをあなたの武器に加味し、より堅牢でスマートな業務自動化を実現してほしい。

タイトルとURLをコピーしました