こんにちは! VBScriptの世界へようこそ。
マクロの記録ボタンを押すだけの世界から一歩抜け出し、WindowsのOS内部を直接コントロールする本格的な自動化の世界へ足を踏み入れたあなたへ、今日はとてもエキサイティングなテーマを用意しました。
今回挑むのは「ファイル共有アクセス権の動的検証」です。
ネットワーク上の共有フォルダに、誰がどんな権限でアクセスできるのか。それをWMI(Windows Management Instrumentation)の力を使って自動で調査・監査するスクリプトを作ります。
「難しそう……」なんて身構えなくて大丈夫です。私と一緒に一つずつ解きほぐしていけば、ここをクリアした瞬間に、あなたのVBScriptのスキルは間違いなく中級者の領域に到達しますよ。
—
1. なぜ「WMI」と「共有アクセス権」なのか?
企業内のファイルサーバーや共有フォルダの管理、本当に頭が痛い問題ですよね。「Everyoneにフルコントロールを与えてしまっていた」「退職者のアカウントがそのまま残っているセキュリティホールがあった」なんてトラブルは絶対に避けたいものです。
しかし、数あるフォルダのアクセス権を一つずつ右クリックして「プロパティ」から確認するのは、気の遠くなる作業です。
ここで WMI の出番です。WMIを使えば、OSの奥深くにあるセキュリティ情報(ACLやDACL)をプログラムから瞬時に引き出し、CSVやログとして出力することができます。
今回のターゲット:`Win32_LogicalShareSecuritySetting`
Windowsの共有フォルダの権限を司る、VBScript使いにとっての強力な武器です。これを使って、共有名と紐づくセキュリティ記述子(Descriptor)を暴いていきましょう。
—
2. 実装コード:共有権限を自動監査するVBScript
まずは、現場でそのままコピー&ペーストして使える実用的なスクリプトを提示します。デスクトップなどに `CheckSharePerms.vbs` という名前で保存し、管理者権限で実行してみてください。
‘ ==============================================================================
‘ スクリプト名: CheckSharePerms.vbs
‘ 概要: WMIを使用してローカル/リモートの共有フォルダのアクセス権を動的に監査する
‘ 著者: 業務自動化チーフアーキテクト
‘ ==============================================================================
Option Explicit
On Error Resume Next
Dim strComputer, objWMIService, colShares, objShare
Dim colSecSettings, objSecSetting, objDescriptor, colDACL, objACE
Dim trusteeName, accessMask, aceType
‘ 接続先コンピュータ名(”.” はローカルコンピューターを指します)
strComputer = “.”
WScript.Echo “=== 共有フォルダ アクセス権監査ツールを開始します ===”
‘ WMIサービスへの接続 (cimv2名前空間)
Set objWMIService = GetObject(“winmgmts:\\” & strComputer & “\root\cimv2”)
If Err.Number <> 0 Then
WScript.Echo “エラー: WMIサービスに接続できませんでした。エラーコード: ” & Hex(Err.Number)
WScript.Quit
End If
‘ すべての共有フォルダを取得
Set colShares = objWMIService.ExecQuery(“Select from Win32_Share”)
For Each objShare in colShares
WScript.Echo vbCrLf & “—————————————-”
WScript.Echo “共有名 (Name): ” & objShare.Name
WScript.Echo “パス (Path) : ” & objShare.Path
WScript.Echo “—————————————-”
‘ 共有名に紐づくセキュリティ設定を取得するためのAssociatedInstanceQuery
Set colSecSettings = objWMIService.ExecQuery( _
“Associators of {Win32_Share.Name='” & objShare.Name & “‘} ” & _
“Where AssocClass=Win32_LogicalShareSecuritySetting”)
For Each objSecSetting in colSecSettings
‘ セキュリティ記述子を取得
Set objDescriptor = objSecSetting.GetSecurityDescriptor()
If Err.Number = 0 And Not IsNull(objDescriptor.Descriptor) Then
‘ DACL(Discretionary Access Control List: 許可・拒否のリスト)を展開
colDACL = objDescriptor.Descriptor.Dacl
If IsArray(colDACL) Then
For Each objACE in colDACL
‘ トルスティ(アクセス権が設定されているユーザー/グループ)の取得
trusteeName = objACE.Trustee.Name
If objACE.Trustee.Domain <> “” Then
trusteeName = objACE.Trustee.Domain & “\” & trusteeName
End If
‘ アクセス権のマスク値とタイプ(許可/拒否)
accessMask = objACE.AccessMask
aceType = objACE.AceType ‘ 0: 許可 (Access Allowed), 1: 拒否 (Access Denied)
Dim typeStr
If aceType = 0 Then
typeStr = “[許可]”
ElseIf aceType = 1 Then
typeStr = “[拒否]”
Else
typeStr = “[その他:” & aceType & “]”
End If
WScript.Echo ” ” & typeStr & ” ユーザー/グループ: ” & trusteeName & ” (AccessMask: ” & accessMask & “)”
Next
Else
WScript.Echo ” (DACLが見つからないか、アクセス権が空です)”
End If
Else
WScript.Echo ” [警告] セキュリティ記述子の取得に失敗しました。”
Err.Clear
End If
Next
Next
WScript.Echo vbCrLf & “=== 監査が完了しました ===”
On Error GoTo 0
—
3. コードの心臓部を紐解く:初心者から脱却するための3つのポイント
このコードには、VBScriptをマスターする上で欠かせない重要なエッセンスが詰まっています。一つずつ噛み砕いて説明しますね。
① `Option Explicit` とエラーハンドリングの美学
スクリプトの2行目にある `Option Explicit`。これ、プロのエンジニアなら必ず書くお約束です。
これを宣言しておくと、変数の宣言忘れ(スペルミスなど)をVBScriptが強制的に検知してエラーにしてくれます。「変数が定義されていません」というエラーに最初はイライラするかもしれませんが、大規模なコードを書くときには命綱になります。
また、`On Error Resume Next` を使って、権限不足でアクセスできない共有フォルダに出くわしても、スクリプトが途中でクラッシュせず、次のフォルダへ華麗にスルーする仕組み(耐障害性)を入れています。
② WMIの「関連付け(Associators)」という魔法
コード内のこの部分に注目してください。
Set colSecSettings = objWMIService.ExecQuery( _
“Associators of {Win32_Share.Name='” & objShare.Name & “‘} ” & _
“Where AssocClass=Win32_LogicalShareSecuritySetting”)
WMIの世界では、オブジェクト同士がリレーショナルデータベースのように紐づいています。「共有フォルダ(Win32_Share)」と「セキュリティ設定(Win32_LogicalShareSecuritySetting)」を `Associators of` というWQL(WMI Query Language)の構文で結ぶことで、「この共有フォルダには、一体どんな鍵(セキュリティ設定)がかかっているのか?」を直接引っ張ってくることができるのです。ここがこのスクリプトの最も知的な部分です。
③ DACLとACEの配列パース
セキュリティの世界では、アクセス権のリストを DACL (Discretionary Access Control List) と呼び、その中に入っている個別のルールを ACE (Access Control Entry) と呼びます。
WMI経由で取得したDACLは、VBScriptから見ると「配列」のデータ構造になっています。
`For Each` ループを使って一つひとつのACEを分解し、誰に(Trustee)、どんな許可(Access Allowed)が与えられているのかをコンソールに描き出しているのです。
—
4. 現場でありがちな「陥りやすい罠」と対策
実際にこのスクリプトや、WMIを使った監査スクリプトを現場に導入する際、初心者が必ずと言っていいほどハマる罠があります。
1. 権限不足(アクセス拒否エラー)
- 原因: スクリプトを実行しているユーザー自身が、そのサーバーのセキュリティ設定やWMI名前空間にアクセスする権限を持っていない場合、エラーになります。
- 対策: スクリプトを実行する際は、必ず「管理者として実行」(Administrator権限)を行ってください。
2. ネットワーク越しのリモート実行の壁
- 原因: ローカルではなく、リモートのファイルサーバー(例: `strComputer = “FileServer01″`)を対象にする場合、Windowsのファイアウォール(WMI / RPCトラフィック)やDCOMのアクセス権に阻まれることがあります。
- 対策: まずは自分のPC(ローカル)で動作確認を完璧にし、リモートへ展開する際はネットワーク管理者にファイアウォールの設定を確認してもらいましょう。
—
最後に:ここをクリアすれば、あなたはもう怖くない!
お疲れ様でした!
「VBScriptでOSのセキュリティ設定を覗き見る」という、一見するとハードルの高そうな処理を、あなたは今コードを通して理解しました。
WMIのクエリを書き換えれば、共有フォルダだけでなく、ディスクの空き容量、インストールされているソフトウェアのリスト、サービスの稼働状態など、Windowsのあらゆる状態をあなたの思い通りに監視・自動化できるようになります。
「マクロの記録」の枠を超え、OSの心臓部に直接アプローチできるVBScriptの快感、ぜひ日々の業務に役立ててください。ここをクリアしたあなたなら、どんな自動化の課題もきっと乗り越えられますよ!
