かつて山市良と呼ばれたおじさんのブログ

セイテクエンジニアのブログ  かつて山市良と呼ばれたおじさんのブログ  メモ. “WMICが既定で無効”への備えは早いほうがいい、影響を調査するPowerShellスクリプト

 

 

メモ. “WMICが既定で無効”への備えは早いほうがいい、影響を調査するPowerShellスクリプト

2025年06月17日配信
2025年06月17日更新
執筆者:山内 和朗

 少し前のメモで、非推奨になったWScriptが将来廃止されるまでに備えて、使用状況を把握する方法を紹介しました。VBScriptはWindows自身がまだ使用している(C:¥Windows¥System32¥slmgr.vbsなど)ので廃止は当面ないのではと言いましたが、VBScriptよりも優先して対処するべき、非推奨機能がありました。それは、WMICコマンドです。VBscriptファイルを探すスクリプトの例を参考に、今回は、WMICコマンドを使用しているバッチやスクリプトを調査するスクリプトを作ってみました。また、このメモと同様に、Sysmonを使用した監視についても触れます。そのため、今回のメモは、以下のメモを合わせてご覧ください。

メモ. VBScript廃止に備えるのはまだ早い? 使用状況を把握する2つの方法

最新Windows 11とWindows ServerにはWMICコマンドが既定でインストールされない件

 

 「Windows Management Instrumentation(WMI)コマンドラインユーティリティ」(WMIC.exe)は、Windows Server 2012の時点で非推奨になり*1、PowerShellのWMIやCIM関連のコマンドレットや他の方法に置き換えることが推奨されてきた、レガシなWindowsのコンポーネントです。Windows 11バージョン22H2のときにオンデマンド機能(オプション機能)となりましたが、Windows 11バージョン23H2およびWindows Server 2022までは既定でインストールされていました。

*1 一部のドキュメントでは、Windows 10バージョン21H1から非推奨と記載されていますが、最初に非推奨が発表されたのはWindows Server 2012の時です。
"The WMI command-line tool (Wmic) is deprecated. Use PowerShell cmdlets instead."
Features Removed or Deprecated in Windows Server 2012(Microsoft Learn)
WMI command line (WMIC) utility deprecation: Next steps|Windows IT Pro Blog(Tech Community)

 

 しかし、Windows 11バージョン24H2およびWindows Server 2025からは、既定でインストールされなくなりました。旧バージョンからアップグレードした環境では、引き続きWMICコマンドは利用可能ですが、新規インストールではオンデマンド機能を手動で有効化しない限り、利用できません(画面1)。そのため、既存の管理用スクリプトでWMICコマンドを使用している場合、最新OSの環境ではエラーになる可能性があります。

 

 オンデマンド機能であるWMICコマンドの現在の状態、追加、削除は、次のPowerShellコマンドラインで実行できます。ただし、WMICコマンドは非推奨であるため、新たに有効化することはお勧めしません。

 

Get-WindowsCapability -Online -Name WMIC
Add-WindowsCapability -Online -Name WMIC~~~~
Remove-WindowsCapability -Online -Name WMIC~~~~

 

画面1 WMICコマンドは、旧バージョンからアップグレードしたWindows 11バージョン24H2やWindows Server 2025では利用できるが、新規インストールでは既定でインストールされない
画面1 WMICコマンドは、旧バージョンからアップグレードしたWindows 11バージョン24H2やWindows Server 2025では利用できるが、新規インストールでは既定でインストールされない

関連:
vol.61 Windows 11 24H2ではWMICが既定で無効の件|最新OSのここに注目(注意)!
vol.42 Windowsのコンピューター名を変更する|コマンド&スクリプト強化週間

WMICコマンドを含むファイル(バッチ/スクリプト)を再帰的に検索する

 

 前出のメモのVBScriptファイルを検索するスクリプトの例を参考に、WMICコマンドのコマンドラインを含む可能性のあるファイルを再帰的に検索するPowerShellスクリプトを作成してみました。WMICコマンドのコマンドラインを含む可能性のあるファイルとしては、バッチ(.cmd、.bat)とスクリプト(.vbs、.wsf、.ps1、.js)を対象とし、その内容にWMICコマンドを含む(大文字と小文字を区別せず、'wmic 'または'wmic.exe '《後ろに半角スペースあり》にマッチ)場合に、CSVファイルまたはディスプレイにファイル情報を出力するようにしています。検索対象のフォルダーは、$pathsToScanに記述してください。また、$LogPathにCSVファイルのパスを記述すれば、CSVファイルに出力し、$logPathを""にすればディスプレイにファイル一覧を表示します。

WMICファイルを含む可能性のあるファイルを検索するPowerShellスクリプトプレーンテキストで表示)

$pathsToScan = @("C:\Users", "C:\ProgramData", "C:\Scripts", "C:\Windows")
# Output to CSV
$logPath = "$env:Temp\WMICFiles_$(hostname).csv"
# Output to Display
#$logPath = ""
$results = @()

foreach ($path in $pathsToScan) {
  if (Test-Path $path) {
    Get-ChildItem -Path $path -Recurse -File -ErrorAction SilentlyContinue |
      Where-Object { $_.Extension -match '\.bat$|\.cmd$|\.ps1$|\.vbs$|\.wsf$|\.js$' } |
        ForEach-Object {
          Write-Host "Target file: "$_.FullName
          try {
            $content = Get-Content -Path $_.FullName -ErrorAction Stop -Raw
            if ($content -match '(?i)wmic(\.exe)? ') {
              $results += [PSCustomObject]@{
                FullName      = $_.FullName
                LastWriteTime = $_.LastWriteTime
                Length        = $_.Length
              }
            }
         } catch {
           Write-Host "File open failed: "$_.FullName
         }
      }
   }
}
if ($results.Count -gt 0) {
  if ($logPath -eq "") {
    $results
  } else {
    $results | Export-Csv -Path $logPath -NoTypeInformation -Encoding UTF8
    Write-Output "Output to: $logPath"
  }
} else {
    Write-Output "No target file containing the WMIC command was found."
}

 

画面2 WindowsにもWMICコマンドを使用しているスクリプト(SecEdit.wsf)がまだ存在する。WMICコマンドが利用できない場合、このスクリプトの一部の機能はエラーになる
画面2 WindowsにもWMICコマンドを使用しているスクリプト(ただし、SCregEdit.wsfは既に非推奨*2)がまだ存在する。WMICコマンドが利用できない場合、このスクリプトの一部の機能はエラーになる

*2 「SCregedit.wsf」はWindows Server 2016で非推奨になりました。ただし、非推奨リストでは、「scregedit.exe」となっています。これは、ドキュメントのミスと思われます。

 

 上のPowerShellスクリプトは、特定の拡張子を持つテキストファイルを対象にしていますが、バイナリファイル(.exeなど)を含めて、WMICコマンドを使用しているファイルを検索することもできます。それには、Windows SysinternalsのStringsユーティリティを使用できます。

 

Strings|Sysinternals(Microsoft Learn)

 

 例えば、次のコマンドラインをPowerShellで実行すると、大文字と小文字を区別せずに、'wmic 'または'wmic.exe 'を含むファイルを現在のディレクトリで検索します(画面3)。-n 5は5文字以上の文字列を検索する指定です。-sパラメーターを追加すると、サブディレクトリを再帰的に検索します。

 

 strings -n 5 *.* | Select-String -Pattern '(?i)wmic(\.exe)? '

 

memo49_scr05

画面3 バイナリファイルを含めてWMICコマンドを使用しているファイルを探すには、Windows SysinternalsのStringsユーティリティを使用できる(ただし、検索対象が多いと膨大な時間がかかる)

 

SysmonでWMIC.exeの使用を監視する

 バッチやスクリプトの対象が膨大で調査が難しい、あるいはユーザーによるコマンド実行を含めて使用状況を確認したいという場合は、あえて非推奨であるWMICコマンドを有効にし、Windows SysinternalsのSystem Monitor(Sysmon)を使用して、WMIC.exeの使用を監視するという方法もあります。

 

 Sysmonのインストールや構成については、前出のメモで確認してください。前回のメモでは、「vbscript.dll」イメージのロードを監視させましたが、今回はそれに次の太字部分のように「wmic.exe」イメージのロードを追加します。なお、この追加したイベントフィルターは、WMICコマンドが無効な環境(既定)では何も記録しません。

<Sysmon schemaversion="スキーマバージョン">
<EventFiltering>
   <ImageLoad onmatch="include">
     <ImageLoaded condition="contains">vbscript.dll</ImageLoaded>
     <ImageLoaded condition="contains">wmic.exe</ImageLoaded>
   </ImageLoad>
</EventFiltering>
</Sysmon>

 

画面3 前回のメモの「vbscript.dll」(VBScriptの使用の監視用)に加えて、「wmic.exe」イメージのロードを監視させるようにフィルターを構成する

画面4 前回のメモの「vbscript.dll」(VBScriptの使用の監視用)に加えて、「wmic.exe」イメージのロードを監視させるようにフィルターを構成する

 

画面4 WMICコマンドが使用されると、イベントID「7」のイベントが記録される

画面5 WMICコマンドが使用されると、イベントID「7」のイベントが記録される

 

さよならWMIC、代替例

 

 WMIが非推奨になってから、 PowerShellのWMIまたはCIM用コマンドレットを使用することが推奨されています。場合によっては、別のコマンドレットやコマンドラインツールが利用できる場合があります。ぱっと思いついたものだけですが、いくつか紹介します。

 

WMICコマンド 代替策

WMIC OS

WMIC ComputerSystem

WMIC BIOS

Get-ComputerInfo

Get-CimInstance Win32_OperatingSystem

Get-CimInstance Win32_ComputerSystem

Get-ItemProperty "HKLM:\SOFTWARE\Microsoft\Windows NT\CurrentVersion"

WMIC DISKDRIVE

Get-Disk

Get-PhysicalDisk

Get-CimInstance -ClassName Win32_DiskDrive

DISKPART

WMIC VOLUME

Get-Volume

Get-CimInstance -ClassName Win32_Volume

DISKPART

WMIC LOGICALDISK

Get-CimInstance -ClassName Win32_LogicalDisk
DISKPART

WMIC QFE LIST

Get-HotFix

WMIC NTEVENT WHERE "(LogFile='System' and '条件式...')"

Get-WinEvent -LogName System -FilterXPath "条件式(XPath)"
Wevtutil qe System /rd:true /f:text /q:"条件式(XPath)"

Get-WmiObject -Class Win32_NTLogEvent -Filter "LogFile = 'System' AND '条件式...'"

WMIC COMPUTERSYSTEM Where Name="%computername%" Call Rename name="新しいコンピューター名"

Rename-Computer -NewName "新しいコンピューター名" -Restart

(Get-CimInstance Win32_ComputerSystem).Rename("新しいコンピューター名") & Restart-Computer

WMIC USERACCOUNT

NET USER

New/Get/Set/Remove/Enable/Disable-LocalUser

WMIC GROUP

NET LOCALGROUP

New/Get/Set/Remove/Enable/Disable-LocalGroup、Add-LocalGroupMember

WMIC USERACCOUNT WHERE Name="Administrator" SET PasswordExpires=False

Set-LocalUser -Name "Administrator" -PasswordNeverExpires $true

(思い出したら追記するかも)

 

blog_yamanxworld_subscribe

blog_yamanxworld_comment

blog_yamanxworld_WP_ws2025

最新記事