Windowsサーバー

Windows Server の CPU 使用率が高い・メモリ不足・ディスク高負荷の原因を特定:タスクマネージャーと PowerShell

6 ステップ 13 分で読めます 19 回閲覧 0
目次

Windows サーバーの動作が重い、リモートデスクトップが固まる、CPU が常に 100% になるといった症状は、多くの場合、特定のプロセス、メモリ不足、ディスクの高負荷のいずれかが原因です。この記事では Windows Server 2016・2019・2022・2025 でタスクマネージャー、リソースモニター、PowerShell を使って原因を特定する方法、正常なシステムの動作と本当の問題の見分け方、そしてマイニングマルウェア(仮想通貨マイナー)などの不審なプログラムを見つける方法を解説します。

見覚えのないプロセスでも、確認が済むまでは終了しないでください。csrss.exe、lsass.exe、winlogon.exe などのシステムプロセスを停止すると、サーバーがクラッシュしたりサインアウトされたりします。まずプロセス名、PID、ファイルパスを控えておきましょう。

ステップ1:タスクマネージャーで全体を把握

Ctrl+Shift+Esc を押します(リモートデスクトップ内では Ctrl+Alt+End を押してタスクマネージャーを選択)。詳細(More details)をクリックし、プロセス(Processes)タブまたは詳細(Details)タブを CPU、メモリ、ディスクのいずれかで並べ替えます。詳細(Details)タブで列見出しを右クリックし、列の選択(Select columns)からコマンド ライン(Command line)を追加すると、各プロセスが実際に何を実行しているかを確認できます。

さらに詳しく調べるにはリソースモニター(resmon)を開きます。CPU タブでは各 svchost.exe の中で動いているサービス、ディスクタブでは読み書きされているファイル、ネットワークタブではどのプロセスがどのリモートアドレスと通信しているかを確認できます。

ステップ2:PowerShell で負荷の高いプロセスを特定

PowerShell はデスクトップの操作が重くて快適に使えない状態でも動作します。管理者として実行してください。

# Overall CPU usage, 5 samples 2 seconds apart
Get-Counter '\Processor(_Total)\% Processor Time' -SampleInterval 2 -MaxSamples 5

# Processes using the most CPU right now (percentage of total CPU)
Get-Counter '\Process(*)\% Processor Time' -ErrorAction SilentlyContinue |
  Select-Object -ExpandProperty CounterSamples |
  Where-Object { $_.InstanceName -notin '_total','idle' } |
  Sort-Object CookedValue -Descending | Select-Object -First 10 InstanceName,
  @{n='CPU%';e={[math]::Round($_.CookedValue / $env:NUMBER_OF_PROCESSORS, 1)}}

# Processes using the most memory
Get-Process | Sort-Object WorkingSet64 -Descending | Select-Object -First 10 Name, Id,
  @{n='RAM(MB)';e={[math]::Round($_.WorkingSet64 / 1MB)}}

# Which services run inside a busy svchost.exe (replace 1234 with its PID)
tasklist /svc /fi "PID eq 1234"

ステップ3:メモリとディスクを確認

# Free physical memory and committed memory
Get-CimInstance Win32_OperatingSystem |
  Select-Object @{n='TotalGB';e={[math]::Round($_.TotalVisibleMemorySize/1MB,1)}},
                @{n='FreeGB';e={[math]::Round($_.FreePhysicalMemory/1MB,1)}}

# Disk activity per drive (sustained % Idle Time near 0 means the disk is the bottleneck)
Get-Counter '\LogicalDisk(*)\% Idle Time','\LogicalDisk(*)\Avg. Disk sec/Transfer' -SampleInterval 2 -MaxSamples 3

# Free space per drive
Get-PSDrive -PSProvider FileSystem | Select-Object Name,
  @{n='FreeGB';e={[math]::Round($_.Free/1GB,1)}}, @{n='UsedGB';e={[math]::Round($_.Used/1GB,1)}}

メモリの「使用中」が 100% 近くで、ディスクへのアクセスが続いている場合、サーバーはディスクへのページングを起こしています。メモリを増設するか、サーバー上で動かすものを減らしてください。システムドライブの空き容量がほとんどない場合も Windows の動作が遅くなり、更新プログラムを適用できなくなることがあります。C ドライブの拡張を参照してください。

ステップ4:正常な動作を知っておく

  • TiWorker.exe / TrustedInstaller.exe:Windows Update によるコンポーネントのインストールやクリーンアップです。更新後 10~60 分ほど CPU 使用率が高いのは正常なので、終わるまで待ちましょう(Windows Update の管理を参照)。
  • MsMpEng.exe:Microsoft Defender によるスキャンです。スキャン中に負荷が高くなるのは想定どおりです。負荷の高いアプリケーションが繰り返しスキャンを引き起こす場合は、Defender を無効にするのではなく、そのデータフォルダーに限定した除外を追加してください。
  • スタンバイ(キャッシュ)メモリ:Windows は空いているメモリをファイルキャッシュとして使い、プログラムが必要とすればすぐに解放します。気にすべきなのは「使用中」のメモリだけです。
  • sqlservr.exe、w3wp.exe、java.exe、node.exe:データベースやアプリケーションのプロセスです。これらの使用率が高い場合は、アクセスの増加、遅いクエリ、またはアプリケーション自体のリークが考えられます。

ステップ5:不審なプログラムがないか確認

名前がランダムなプロセス、C:\Users\Public や C:\ProgramData、一時フォルダーから実行されているプロセス、CPU を使い切っている署名のない実行ファイルは、詳しく調べる必要があります。マイニングマルウェアは、本来とは異なるフォルダーに置かれた svchost.exe に偽装していることがよくあります。本物は C:\Windows\System32 からしか実行されません。

# Path, command line and digital signature of a suspicious process (replace 1234)
Get-CimInstance Win32_Process -Filter "ProcessId=1234" | Select-Object Name, ExecutablePath, CommandLine
Get-AuthenticodeSignature (Get-Process -Id 1234).Path | Select-Object Status, SignerCertificate

# svchost.exe copies running from anywhere other than System32 or SysWOW64
Get-CimInstance Win32_Process -Filter "Name='svchost.exe'" |
  Where-Object { $_.ExecutablePath -notmatch 'C:\\Windows\\(System32|SysWOW64)\\' } |
  Select-Object ProcessId, ExecutablePath

# Network connections per process
Get-NetTCPConnection -State Established | Group-Object OwningProcess |
  Sort-Object Count -Descending | Select-Object -First 10 Count, Name

# Persistence: scheduled tasks, auto-start services and startup entries
Get-ScheduledTask | Where-Object { $_.State -ne 'Disabled' -and $_.TaskPath -notlike '\Microsoft\*' } |
  Select-Object TaskName, TaskPath, @{n='Action';e={$_.Actions.Execute}}
Get-CimInstance Win32_Service | Where-Object { $_.StartMode -eq 'Auto' -and $_.PathName -notmatch 'Windows' } |
  Select-Object Name, State, PathName
Get-CimInstance Win32_StartupCommand | Select-Object Name, Command, Location

# Update signatures and run a full Microsoft Defender scan
Update-MpSignature
Start-MpScan -ScanType FullScan
Get-MpThreatDetection

マルウェアが見つかった場合は、まずスケジュールタスクやサービスを削除し、次にプロセスを終了してファイルを削除します。そのうえですべてのパスワードを変更し、侵入経路を塞いでください。最も多い侵入経路は推測されやすいリモートデスクトップのパスワードです。Windows VPS のセキュリティ強化とRDP ポートの変更を参照してください。判断に迷う場合は、データをバックアップしてから OS を再インストールしてください。

ステップ6:パフォーマンスモニターで長時間の記録を取る

出たり消えたりする問題は、記録を取ると捉えやすくなります。perfmon を実行し、データ コレクター セット → システム(Data Collector Sets → System)を開いて System Performance を右クリックし、開始(Start)を選択します。記録が終わると(約 1 分)、レポート → システム(Reports → System)の下のレポートに、CPU、ディスク、ネットワークの使用量が多いプロセスが一覧表示されます。

よくある質問

CPU が 100% なのにタスクマネージャーに負荷の高いプロセスが表示されない

Show processes from all users を有効にして詳細(Details)タブを確認してください。システムサービスや他のユーザーのプロセスはここに表示されます。また、タスクマネージャーを開くと動作を止めるマルウェアもあります。上記の PowerShell コマンドを使うか、ご利用の製品で提供されている場合は IMIDC クライアントエリアのリソースグラフを確認してください。

リモートデスクトップのときだけ動作が遅い

CPU、メモリ、ディスクが正常に見える場合、原因はたいていお客様とサーバーの間のネットワーク経路です。リモートデスクトップのトラブルシューティングを参照し、ping と tracert で経路をテストしてください。

チューニングではなくアップグレードすべきなのはどんなときですか?

通常のアクセス量でもご自身のアプリケーションが正当に CPU やメモリの大半を使っている場合、チューニングしても長くはもちません。プランをアップグレードするか、データベースを別のサーバーに移してください。

上記の手順で解決しない場合は、サポートチケットを送信して IMIDC の 24 時間 365 日対応テクニカルサポートへご連絡ください。サーバー IP、Windows Server のバージョン、負荷の高いプロセス名、タスクマネージャーまたは PowerShell の出力のスクリーンショットを添えていただくと、より迅速に調査できます。

この回答はお役に立ちましたか?

関連チュートリアル