「Visual C++ 2015–2022 再頒布可能パッケージ(vcredist)」をサイレント配布したら、意図せず Windows 11 が自動再起動してしまう――現場でよく起きる悩みです。原因はスイッチ指定の誤りと OS 側の再起動保留の継承に集約されます。本記事では /norestart の正解、再起動を抑えるための事前健全化、ログでの原因切り分け、Intune/SCCM での戻りコード設計まで、運用で迷わない実装手順を具体的に解説します。
結論と最短解:強制再起動を防ぐには /norestart を使う
ベンダー指定の vcredist_x86.exe (14.42.34338) を /quiet /noreboot で展開した場合、/noreboot はインストーラが認識しないため、再起動抑止は一切効きません。正しいスイッチは /norestart です。
vcredist_x86.exe /quiet /norestart
まずはこの誤指定を正すことが第一歩です。なお、/q と /quiet は同義ですが、運用設計では可読性の高い /quiet を推奨します。
なぜ再起動が発生するのか:三つの主要因
1) スイッチの誤り(/noreboot は無効)
認識されないスイッチは無視されます。つまり /noreboot 指定は「何も指定していない」のと同じ振る舞いです。
2) OS 側の「再起動保留」を継承
Windows Update やコンポーネント ストア(CBS)が既に再起動待ちの場合、vcredist はその状態を引き継ぎ、結果として再起動要求(戻りコード 3010)を返します。これは vcredist の問題ではなく、OS の状態に起因するものです。
3) DLL が使用中で置換を延期
ランタイム DLL(例:msvcp140.dll など)がプロセスにロックされていると、インストーラは「再起動後に置換」を選択し、やはり 3010 を返します。これは回避不能で、配信の時間帯設計とクライアント側の再起動制御ポリシーで吸収するのが現実解です。
実装ガイド:再起動を抑えた安全なサイレント導入フロー
ステップA:OS の再起動保留を先に解消する
配布前に Windows Update の保留を無くすことが最重要です。GUI なら「設定 > Windows Update」で最新状態にします。自動化する際は、次のレジストリ&状態をチェックし、可能なら解消してから vcredist を投入します。
| チェック対象 | 場所 | 意義 |
|---|---|---|
| Windows Update 再起動保留 | HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired(キーの存在) | WU に再起動待ちがあるか |
| CBS(コンポーネント ベース サービシング) | HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending(キーの存在) | ストアの再起動保留 |
| ファイル置換の保留 | HKLM\SYSTEM\CurrentControlSet\Control\Session Manager\PendingFileRenameOperations(値の有無) | 再起動後置換すべきファイルが残存 |
コマンドラインでの簡易確認:
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired" >nul 2>&1 & echo WU:%errorlevel%
reg query "HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending" >nul 2>&1 & echo CBS:%errorlevel%
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager" /v PendingFileRenameOperations
PowerShell 版(関数化):
function Test-PendingReboot {
$paths = @{
WU = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired'
CBS = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending'
PFN = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager'
}
$pfn = Get-ItemProperty -Path $paths.PFN -Name PendingFileRenameOperations -ErrorAction SilentlyContinue
[pscustomobject]@{
WindowsUpdate = Test-Path $paths.WU
CBS = Test-Path $paths.CBS
PendingFiles = [bool]$pfn.PendingFileRenameOperations
RebootNeeded = (Test-Path $paths.WU) -or (Test-Path $paths.CBS) -or [bool]$pfn.PendingFileRenameOperations
}
}
Test-PendingReboot | Format-List
注意:レジストリの直接削除で「強制的に保留を消す」行為は、システムの不整合や更新失敗を招く恐れがあります。まずは Windows Update の適用・再起動を運用で吸収し、どうしても難しい場合はメンテナンス時間帯に安全に再起動してから導入してください。
ステップB:正しいコマンドで静かに導入する
最小構成は次の通りです。ログを残しておくと、後述の切り分けが容易になります。
vcredist_x86.exe /quiet /norestart /log install_vc2015-2022_x86.log
併せて x64 や ARM64 を配る場合もスイッチ体系は同一です(各アーキテクチャごとに同様のコマンドを実行)。大規模展開では「/quiet /norestart を標準化」「戻りコード 3010 を『再起動保留の成功』として扱う」ルールに揃えると、ユーザー作業を中断させずに済みます。
ステップC:戻りコードの設計(Intune/SCCM)
vcredist は内部で MSI を実行するため、戻りコードは Windows Installer の値に準拠します。配布ツール側での扱いを予め決めておきましょう。
| 戻りコード | 意味 | 推奨の扱い |
|---|---|---|
0 | 成功 | 成功 |
3010 | 成功(再起動が必要) | 成功(再起動保留)として受理。自動再起動は抑止 |
1641 | 成功(再起動を開始) | アプリ側で再起動を開始。原則この発生は稀・要注意 |
1602 | ユーザーキャンセル | サイレントでは通常発生しない。エラー扱いで要調査 |
1603 | 致命的なエラー | 失敗。ログで原因特定 |
1618 | 別のインストールが実行中 | リトライ。メンテナンス枠での直列化を検討 |
Microsoft Intune(Win32 アプリ)での推奨設定
- インストール コマンド:
vcredist_x86.exe /quiet /norestart /log install.log - 戻りコード:
0 = 成功、3010 = Soft reboot(成功)、1641 = Hard reboot - 再起動動作:「特に操作なし」(端末側ポリシー/メンテナンスで制御)
- 検出規則(レジストリ):
HKLM\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86またはHKLM\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x86
値Installed(DWORD)= 1 かつVersionに14.42.34338以上
Configuration Manager(SCCM/MECM)での推奨設定
- アプリケーション > デプロイ タイプ:Script インストーラー
- インストール動作:システム
- ユーザー エクスペリエンス:プログラムの再起動を 抑止
- 戻りコード:
0(成功)、3010(再起動が必要=成功)、1641(再起動開始=要注意) - 検出手段:Intune と同様のレジストリ検出
ログで原因を特定する:どの処理が再起動をトリガーしたか
ログを有効化すると、再起動要求の理由を迅速に判定できます。
vcredist_x86.exe /quiet /norestart /log install.log
ログ上で注目すべきポイント:
- Restart Manager:ロックされた DLL/プロセスの検出結果
- MSI 戻りコード:
3010(再起動保留)や1603(致命的) - ペンディングの有無:
PendingFileRenameOperationsが示す置換予約
現場で効く運用レシピ
メンテナンス時間帯配布+再起動制御ポリシーの併用
システム DLL のロックは完全には避けられません。よって「ユーザー影響が最小の時間帯に配布」「OS の再起動はグループポリシー/MDM ポリシーで抑止・延期」をセットで設計します。代表的なポリシー例:
- ログオンユーザーがいる間の自動再起動を禁止
- アクティブ時間の設定で業務時間中の再起動を抑制
- 必要に応じてメンテナンス期間に計画再起動
「ペンディングがある端末は先送り」の分岐配布
先述の Test-PendingReboot を使い、再起動保留の端末には先に OS 更新・再起動を促す通知のみを配布し、クリーンな端末にだけ vcredist を入れると、無駄な再起動要求を劇的に減らせます。
スクリプト テンプレート:安全なラッパーで 3010 を吸収
以下は、OS の再起動保留をチェックしつつ vcredist を導入し、戻りコード 3010 を「成功(再起動保留)」として正しく終了させる PowerShell の例です。ログと検出規則に合うようバージョン判定も含めています。
param(
[string]$ExePath = ".\vcredist_x86.exe",
[string]$LogPath = "$PSScriptRoot\install_vcredist_x86.log",
[version]$MinVersion = [version]'14.42.34338.0'
)
function Get-VcRedistState {
$keys = @(
'HKLM:\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86',
'HKLM:\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x86'
)
foreach($k in $keys){
$p = Get-ItemProperty -Path $k -ErrorAction SilentlyContinue
if($p -and $p.Installed -eq 1 -and $p.Version){
[pscustomobject]@{ Path=$k; Installed=$true; Version=[version]$p.Version }
return
}
}
[pscustomobject]@{ Path=$null; Installed=$false; Version=[version]'0.0.0.0' }
}
function Test-PendingReboot {
$wu = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\WindowsUpdate\Auto Update\RebootRequired'
$cbs = 'HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Component Based Servicing\RebootPending'
$pfn = 'HKLM:\SYSTEM\CurrentControlSet\Control\Session Manager'
$pfnv = (Get-ItemProperty -Path $pfn -Name PendingFileRenameOperations -ErrorAction SilentlyContinue).PendingFileRenameOperations
[pscustomobject]@{
WindowsUpdate = Test-Path $wu
CBS = Test-Path $cbs
PendingFiles = [bool]$pfnv
RebootNeeded = (Test-Path $wu) -or (Test-Path $cbs) -or [bool]$pfnv
}
}
# 1) 事前判定:すでに所要バージョンなら何もしない
$state = Get-VcRedistState
if($state.Installed -and $state.Version -ge $MinVersion){
Write-Host "vcredist x86 already installed: $($state.Version)"
exit 0
}
# 2) 再起動保留の端末はスキップ(配布リングで後回し)
$pending = Test-PendingReboot
if($pending.RebootNeeded){
Write-Host "Reboot is pending. Skip install to avoid chained reboot."
# Intune/SCCM 側で「検出規則 NG → リトライ」に任せる
exit 1618
}
# 3) インストール実行
$psi = New-Object System.Diagnostics.ProcessStartInfo
$psi.FileName = $ExePath
$psi.Arguments = "/quiet /norestart /log `"$LogPath`""
$psi.UseShellExecute = $false
$proc = [System.Diagnostics.Process]::Start($psi)
$proc.WaitForExit()
$rc = $proc.ExitCode
Write-Host "vcredist exit code: $rc"
switch($rc){
0 { exit 0 } # 成功
3010 { exit 0 } # 成功(再起動保留)→ 成功として扱う
default { exit $rc } # それ以外は配布ツールで失敗扱い
}
バッチ派の方には .cmd 版も用意しておくと便利です。
@echo off
set EXE=vcredist_x86.exe
set LOG=%~dp0install_vcredist_x86.log
"%EXE%" /quiet /norestart /log "%LOG%"
set RC=%errorlevel%
echo ExitCode=%RC%
if %RC%==3010 exit /b 0
exit /b %RC%
よく使うスイッチ一覧(覚えておくとラク)
| スイッチ | 意味 | 備考 |
|---|---|---|
/quiet | 完全サイレント | /q でも可 |
/passive | 進捗のみ表示(操作不要) | ヘルプや調査時に |
/norestart | 自動再起動を抑止 | 本記事の主役。/noreboot ではない |
/log <file> | 詳細ログを出力 | 障害切り分けの生命線 |
/repair | 修復モード | 破損時に有効 |
/uninstall | アンインストール | ロールバック用 |
「どうしても 3010 が出る」時に考えること
最も多いのは「使用中 DLL による『再起動後置換』」です。配布の時間帯を変える、重いアプリ(ブラウザ、Office、IDE など)を閉じた状態で配布する、RDS/VDI ではログオフ制御を組み合わせる等の工夫で発生率を下げられます。とはいえゼロにはできないため、戻りコード設計とポリシーで受け止めるのが現実路線です。
「OS 更新 → 再起動 → vcredist」の順番にする
保留の残る端末では、先に OS 側の更新・再起動を済ませてから導入します。リング配布(第 1 群は OS 更新だけ、翌日に vcredist など)にすると現場負荷が軽くなります。
検出(ディテクション)を堅牢に:レジストリの見るべき値
Visual C++ 2015–2022 は「統合パッケージ」なので、検出は 14.0 系列のランタイム キーを見ます。判定は Installed = 1 と Version の二本立てが堅実です。
| アーキテクチャ | レジストリ キー | 値 | 例 |
|---|---|---|---|
| x86 | HKLM\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86HKLM\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x86 | Installed(DWORD)= 1Version(REG_SZ)>= 14.42.34338.0 | 32bit ランタイム |
| x64 | HKLM\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x64 | 同上 | 64bit ランタイム |
| ARM64 | HKLM\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\ARM64 | 同上 | Windows 11 on ARM 環境など |
トラブルシューティング チェックリスト
- /norestart を指定しているか?(
/norebootではない) - Windows Update / CBS の再起動保留がないか?(事前に解消)
- 同時インストールが走っていないか?(
1618の可能性) - ログにロックされた DLL の記録はあるか?(使用中のアプリを閉じる)
- 戻りコード 3010 を成功扱いにしているか?(配布ツール側の設定)
- 検出規則が厳し過ぎないか?(バージョン文字列の比較ロジック)
FAQ
Q. /norestart でも再起動が勝手に走ることはある?
A. 通常はありません。ただし OS や他のセットアップが 1641 のような「再起動開始」を発生させた場合、vcredist の意思に関係なく再起動します。これはチェーン全体の設計課題です。
Q. そもそも vcredist は必須? Windows 11 なら不要では?
A. UCRT(Universal CRT)の多くは OS に含まれますが、アプリが要求する Visual C++ ランタイムのバージョン次第です。要件に 2015–2022 以降が明記されていれば導入が安全です。
Q. 複数アーキテクチャ(x86/x64/ARM64)を一括で入れたい
A. それぞれのパッケージを個別に /quiet /norestart で呼び出し、戻りコード 3010 を成功扱いに統一すれば、大規模展開でもユーザー影響を最小化できます。
ベスト プラクティス:配布ポリシーの雛形
- 事前健全化:配布対象は「再起動保留なし」の端末に限定。保留端末は OS 更新フローへ振り分け
- 標準コマンド:
/quiet /norestart /logを全アーキテクチャで統一 - 戻りコード:
0と3010を成功、1641は要注意、その他は失敗 - 時間帯:メンテナンス枠で配布。RDS/VDI はログオフ制御と併用
- 検出規則:
Installed=1とVersionの両方で判定 - ロギング:必ず
/log。障害時の MTTR を短縮
付録:安全に「保留」を確認・クリーンアップする手順
保留状態の把握だけを行う(推奨)
$p = Test-PendingReboot
if($p.RebootNeeded){
Write-Output "再起動保留あり:WU=$($p.WindowsUpdate), CBS=$($p.CBS), PFN=$($p.PendingFiles)"
# ここで OS 更新/再起動を誘導する
} else {
Write-Output "保留なし。導入を続行可能。"
}
どうしてもクリーンアップが必要な場合(十分注意)
業務影響と整合性を確認したうえで、メンテナンス時間帯に限定して実施します。OS 再起動を実施するのが最も安全で、レジストリ値の削除は最後の手段です。
:: 情報用途(削除しない)
reg query "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager" /v PendingFileRenameOperations
:: 削除例(非推奨・自己責任)
reg delete "HKLM\SYSTEM\CurrentControlSet\Control\Session Manager" /v PendingFileRenameOperations /f
削除しても原因プロセスが生きていれば再び保留が生まれます。根本はプロセスの停止/OS 再起動です。
まとめ
サイレント導入での強制再起動は、実は「正しいスイッチ」と「OS 事前健全化」と「戻りコード設計」の三点でほぼ制御できます。まずは /norestart に正し、配布前に再起動保留を無くし、3010 を成功として扱う。それでも避けられないケースはメンテナンス運用で吸収し、ログで根拠を残す。この基本形を徹底すれば、vcredist の大規模展開でもユーザー作業を中断させず、安定した配信が実現できます。
実装クックブック(コピー&ペースト用)
最小構成(x86, 14.42.34338)
vcredist_x86.exe /quiet /norestart /log install_vc2015-2022_x86.log
アーキテクチャ別の一括配布例(PowerShell)
$files = @(
@{ Path = ".\vcredist_x86.exe"; Log = "vc_x86.log" },
@{ Path = ".\vcredist_x64.exe"; Log = "vc_x64.log" },
@{ Path = ".\vcredist_arm64.exe";Log = "vc_arm64.log"}
)
foreach($f in $files){
if(Test-Path $f.Path){
Write-Host "Installing $($f.Path)..."
$p = Start-Process -FilePath $f.Path -ArgumentList "/quiet /norestart /log `"$($f.Log)`"" -PassThru -Wait
if($p.ExitCode -eq 0 -or $p.ExitCode -eq 3010){
Write-Host "OK ($($p.ExitCode))"
} else {
Write-Error "Failed with RC=$($p.ExitCode)"
exit $p.ExitCode
}
}
}
exit 0
Intune 検出スクリプト(x86 バージョン閾値)
$Min = [version]'14.42.34338.0'
$keys = @(
'HKLM:\SOFTWARE\Microsoft\VisualStudio\14.0\VC\Runtimes\x86',
'HKLM:\SOFTWARE\WOW6432Node\Microsoft\VisualStudio\14.0\VC\Runtimes\x86'
)
$ok = $false
foreach($k in $keys){
$p = Get-ItemProperty -Path $k -ErrorAction SilentlyContinue
if($p -and $p.Installed -eq 1){
try {
if([version]$p.Version -ge $Min){ $ok = $true }
} catch { }
}
}
if($ok){ exit 0 } else { exit 1 }
ログ有効化と最小化
vcredist_x86.exe /quiet /norestart /log "%ProgramData%\vcredist\%computername%_x86.log"
誤りやすいポイント(再確認)
- /noreboot というスイッチは存在しない(正しくは
/norestart) - OS の再起動保留があると、vcredist は 3010 を返す
- DLL ロックは完全回避できない。時間帯&ポリシーで吸収
- 戻りコード設計と検出規則を「先に決める」と運用が安定
- ログは必ず残す(
/log)。再発防止へ直結
関連メモ
- 2015–2022 は統合パッケージ(14.x 系)。x86/x64/ARM64 でスイッチ体系は同じです。
- 内部的に MSI(例:
VC_RuntimeMinimum_*.msi)が実行され、MSI 標準の戻りコードが反映されます。 - MSI 直呼びで
REBOOT=ReallySuppressを渡す実装もありますが、検証負荷が高く、原則は EXE 既定スイッチでの運用を推奨します。
要点の再掲:
- 使うのは
/quiet /norestart。/norebootは無効。 - Windows Update 等の保留を先に解消してから導入。
- 回避不能なケースでは
3010を「成功(再起動保留)」として処理。 /logで根拠を残し、Intune/SCCM の戻りコード設計を統一。

コメント