こんにちは!現場でバリバリ自動化ツールを作っていると、「動的にコードを組み立てて実行したいけれど、ディスクに一時ファイルを残したくないな……」という壁にぶつかることありませんか?
特にセキュリティが厳しい企業環境だと、VBScriptやPowerShellのファイルをHDDに書き出した瞬間に、セキュリティソフト(アンチウイルス)が「怪しいファイルだ!」と検診して勝手に削除したり、隔離したりして頭を悩ませることも多いはずです。
「ファイルを作らず、メモリ上だけでスマートにコードを組み立てて実行できたらどんなに楽か……」
今回は、そんな現場の悩みを鮮やかに解決する【オンメモリ動的コード組み立て】(`Execute`メソッドを活用したインメモリ実行技術)について、基礎から実践まで優しく、そしてディープに解説していきます。ここをクリアすれば、あなたのVBScriptの引き出しはグッとプロフェッショナルなものになりますよ。バッチリマスターしていきましょう!
—
なぜ「ファイルを作らない」ことが重要なのか?
通常、プログラムの動的生成というと「`Scripting.FileSystemObject`(FSO)を使って、適当なフォルダに `temp.vbs` なんて名前のファイルを作って、それを `WshShell.Run` で実行する」というアプローチを思い浮かべがちです。
しかし、この手法にはいくつかの「現場の罠」が潜んでいます。
1. セキュリティソフトの誤検知リスク: ディスク上の`.vbs`ファイルは、作成された瞬間にリアルタイムスキャンのターゲットになります。
2. I/O(入出力)のオーバーヘッド: わざわざハードディスクやSSDに書き込んで読み直すのは、コンピュータにとって無駄な負荷です。
3. 消し忘れの恐怖: スクリプトが途中で異常終了したとき、一時ファイルがゴミとして残ってしまうストレス。
これらをすべて解決するのが、メモリ(RAM)上だけでコードを組み立てて、そのまま実行エンジンに放り込むというアプローチです。ディスクに痕跡を残さないため、セキュリティ的にも非常にクリーンで高速です。
—
魔法のメソッド:`Execute` とは何か?
VBScriptには、文字列として渡したプログラムコードを、その場でコンパイルして実行してしまう強力な組み込み関数(ステートメント)が用意されています。それが `Execute` です。
図解的にイメージしてみましょう。
[文字列変数 (Code)]
│ “Sub ShowMessage() : WScript.Echo “Hello” : End Sub”
▼
┌─────────────────────────┐
│ Execute メソッド │ ──> メモリ上で即座にパース・コンパイル!
└─────────────────────────┘
│
▼
[スクリプトの空間(スコープ)に常駐し、呼び出し可能になる]
文字の羅列にすぎなかった文字列が、`Execute` を通ることで「本物の実行可能コード」に生まれ変わる瞬間です。この仕組みを使いこなせば、ユーザーの入力や外部からのデータに応じて、無限に振る舞いを変えるプログラムが作れます。
—
実践!オンメモリ動的コード組み立てスクリプト
百聞は一見にしかず。実際にディスクへファイルを一切作成せず、メモリ上でコードを組み立てて実行するサンプルコードを見てみましょう。
メモ帳を開いて、以下のコードを `MemoryExec.vbs` という名前で保存して実行してみてください。(※実行するファイル自体は本体ですが、処理の途中で動的ファイルは一切作りません)
‘ =================================================================0
‘ テーマ: オンメモリ動的コード組み立ての基本実装
‘ 概要: 文字列として変数定義やプロシージャを組み立て、Executeで実行する
‘ =================================================================0
Option Explicit
Sub Main
WScript.Echo “=== オンメモリ動的コード実行デモを開始します ===”
‘ 1. 実行したいVBScriptコードを「文字列」として変数に組み立てる
‘ ※今回は例として、動的に挨拶をする関数と変数を組み立てます
Dim dynamicCode
dynamicCode = “” & _
“Dim targetName” & vbCrLf & _
“targetName = “”エンジニア”” & vbCrLf & _
“Sub DynamicGreeting()” & vbCrLf & _
” WScript.Echo “”こんにちは、”” & targetName & “”さん!メモリ上からのご挨拶です。””” & vbCrLf & _
“End Sub”
‘ 2. 現時点では、dynamicCode は「ただの長い文字列」にすぎない
WScript.Echo “[確認] まだコードは実行されていません。文字列の長さ: ” & Len(dynamicCode) & “文字”
‘ 3. Execute メソッドでメモリ上にコードを展開・コンパイルする
Execute dynamicCode
‘ 4. 展開されたおかげで、文字列の中にあったはずの関数や変数が呼び出せるようになる!
WScript.Echo “[確認] Execute完了。動的生成された関数を呼び出します…”
‘ 動的生成したプロシージャを実行
DynamicGreeting
WScript.Echo “=== デモが正常に終了しました(ディスクへの書き込みはゼロです) ===”
End Sub
‘ メイン処理のキック
Main
このコードのポイント
- `dynamicCode` というただの文字列変数の中に、VBScriptの構文(変数宣言、代入、サブルーチン定義)を詰め込んでいます。
- `Execute dynamicCode` を実行した瞬間、VBScriptのランタイムエンジンがその文字列を解釈し、現在のスコープに `targetName` 変数や `DynamicGreeting` サブルーチンを誕生させます。
- その後、何食わぬ顔で `DynamicGreeting` を呼び出せば、メモリ上で見事にコードが機能します。
—
さらに高度な活用:`ExecuteGlobal` との違い
VBScriptには、似たような仲間に `ExecuteGlobal` というメソッドもあります。ここを理解しておくと、チーフアーキテクトとしてのレイヤーにグッと近づけます。
- `Execute`:
- 実行した「ローカルスコープ(関数やサブルーチンの中)」にコードを展開します。関数の中で呼び出した場合、その関数が終了すると動的コードも消えてなくなります。
- `ExecuteGlobal`:
- グローバルスコープにコードを展開します。どこで呼び出そうとも、スクリプト全体のグローバル領域に変数や関数が登録されます。
動的に汎用的なライブラリ関数を読み込ませたい場合などは、`ExecuteGlobal` が重宝します。用途に合わせて使い分けましょう。
—
陥りやすい罠とエラー回避の知見
オンメモリ実行は強力ですが、初心者や中級者が必ずハマる「落とし穴」があります。現場で泣きを見ないために、以下の注意点を頭に刻んでおいてください。
1. 構文エラー(Syntax Error)の特定が難しい
通常のファイルであれば、エラーが起きたときに「〇行目」と教えてくれますが、オンメモリで組み立てた文字列の中で構文エラー(スペルミスや `End If` の忘れなど)が起きると、文字列の何行目なのか、あるいは全体のどこが悪いのかが非常に分かりにくくなります。
- 対策: 複雑なコードをいきなり `Execute` するのではなく、一度 `WScript.Echo dynamicCode` でコンソールに出力させるなどして、文字列の組み立てミスがないかを目視・デバッグする習慣をつけましょう。
2. クォーテーション(”)のエスケープ地獄
文字列の中に文字列を埋め込むため、ダブルクォーテーションの重ね方に頭がウニになります。
‘ 駄目な例(ダブルクォーテーションが衝突する)
Dim code = “WScript.Echo “Hello””
‘ 正しい例(VBScriptではダブルクォーテーションは “” と重ねる)
Dim code
code = “WScript.Echo “”Hello”””
長文を組み立てる際は、`vbCrLf` を上手に使い、コードの可読性を保つ工夫が必要です。
—
まとめ
今回は、ファイル作成を行わないセキュリティに配慮した動的スクリプト実行技術【オンメモリ動的コード組み立て】について解説しました。
- 一時ファイルを作らないことで、セキュリティソフトの誤検知やI/O負荷、ゴミファイルの残骸を防げる。
- `Execute`(または `ExecuteGlobal`)メソッドを使うことで、ただの文字列をその場でコンパイルして実行プログラムに昇華させることができる。
- コード組み立て時のクォーテーションの扱いや、デバッグの仕方に工夫が必要。
ここをクリアできれば、あなたのVBScriptのスキルは単なる「マクロの延長」から、洗練された「システム自動化エンジニア」の領域へとステップアップします。ぜひ、日々の業務自動化やツール開発に取り入れてみてくださいね。
それでは、また次の知見でお会いしましょう!バッチリ使いこなしてください!
