ken_nogi/PAD/Set-WindowsUiPreferences.ps1
Kenichiro NOGI 88a402ce0f up
2026-07-10 18:13:30 +09:00

333 lines
13 KiB
PowerShell
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#requires -Version 5.1
<#
Windowsユーザーごと/HKCUの UI 設定をまとめて反映するスクリプト。
想定: 各 PC のユーザーが自分で実行(管理者での実行を推奨)。
対象: Windows 11 25H2
反映する内容:
- エクスプローラーのオプション(表示/全般相当)
- 「この PC を表示」(起動時の表示先を この PC に)
- 「全てのフォルダーを表示」
- 「ライブラリの表示」
- 「開いているフォルダーまで展開」
- 「別のプロセスでフォルダーウインドウを開く」
- 「登録されている拡張子は表示しない」→ OFF拡張子を表示
- 個人設定 → テーマ → デスクトップ アイコン
- コンピュータ / コントロールパネル / ユーザープロファイル を表示
- 個人設定 → スタート → フォルダー
- 設定 / エクスプローラー / ドキュメント / ダウンロード を表示
- 個人設定 → タスクバー
- 検索: 非表示
- タスクビュー: オフ
- ウィジット: オフ(主に Windows 11
- システム → 電源とバッテリー
- 電源接続時: 画面オフ 10 分 / スリープ 30 分
- バッテリー駆動時: 画面オフ 4 分 / スリープ 10 分
注意:
- 多くの項目は Explorer 再起動/サインアウトで反映されます。
- 企業ポリシーGPO/Intuneで強制されている場合、反映されないことがあります。
#>
[CmdletBinding(SupportsShouldProcess = $true)]
param(
[switch]$RestartExplorer,
[string]$BackupDirectory = '.\RegistryBackups'
)
Set-StrictMode -Version Latest
$ErrorActionPreference = 'Stop'
function Test-IsAdministrator {
try {
$currentIdentity = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = New-Object Security.Principal.WindowsPrincipal($currentIdentity)
return $principal.IsInRole([Security.Principal.WindowsBuiltInRole]::Administrator)
}
catch {
return $false
}
}
function Ensure-RegistryKey {
param(
[Parameter(Mandatory)] [string]$Path
)
if (-not (Test-Path -LiteralPath $Path)) {
if ($PSCmdlet.ShouldProcess($Path, 'Create registry key')) {
New-Item -Path $Path -Force | Out-Null
}
}
}
function Set-RegistryDword {
param(
[Parameter(Mandatory)] [string]$Path,
[Parameter(Mandatory)] [string]$Name,
[Parameter(Mandatory)] [int]$Value
)
Ensure-RegistryKey -Path $Path
$current = $null
try {
$current = (Get-ItemProperty -LiteralPath $Path -Name $Name -ErrorAction Stop).$Name
}
catch {
$current = $null
}
if ($current -ne $Value) {
$target = "$Path\\$Name"
if ($PSCmdlet.ShouldProcess($target, "Set DWORD to $Value")) {
New-ItemProperty -LiteralPath $Path -Name $Name -Value $Value -PropertyType DWord -Force | Out-Null
}
}
}
function Write-Section {
param([Parameter(Mandatory)][string]$Title)
Write-Host "`n=== $Title ===" -ForegroundColor Cyan
}
function Invoke-PowerCfgChange {
param(
[Parameter(Mandatory)] [string[]]$Arguments,
[Parameter(Mandatory)] [string]$Description
)
$displayCommand = 'powercfg {0}' -f ($Arguments -join ' ')
if ($PSCmdlet.ShouldProcess($Description, $displayCommand)) {
& powercfg @Arguments | Out-Null
if ($LASTEXITCODE -ne 0) {
throw ("powercfg の実行に失敗しました: {0}" -f $displayCommand)
}
}
}
function Backup-RegistryTargets {
param(
[Parameter(Mandatory)] [array]$Targets,
[Parameter(Mandatory)] [string]$BaseDirectory
)
$resolvedBase = $ExecutionContext.SessionState.Path.GetUnresolvedProviderPathFromPSPath($BaseDirectory)
$timestamp = Get-Date -Format 'yyyyMMdd_HHmmss'
$backupRoot = Join-Path -Path $resolvedBase -ChildPath "WindowsUiPreferences_$timestamp"
New-Item -Path $backupRoot -ItemType Directory -Force | Out-Null
$snapshot = @()
foreach ($target in $Targets) {
$safeName = ($target.NativePath -replace '[\\/:*?"<>|]', '_')
$regFile = Join-Path -Path $backupRoot -ChildPath ("{0}.reg" -f $safeName)
try {
& reg.exe export $target.NativePath $regFile /y | Out-Null
}
catch {
Write-Warning ("レジストリキーのエクスポートに失敗しました: {0} ({1})" -f $target.NativePath, $_.Exception.Message)
}
foreach ($valueName in $target.Values) {
$exists = $false
$value = $null
try {
$value = (Get-ItemProperty -LiteralPath $target.PsPath -Name $valueName -ErrorAction Stop).$valueName
$exists = $true
}
catch {
$exists = $false
$value = $null
}
$snapshot += [PSCustomObject]@{
Path = $target.PsPath
NativePath = $target.NativePath
Name = $valueName
Exists = $exists
Value = $value
BackupAt = (Get-Date).ToString('o')
}
}
}
$snapshotFile = Join-Path -Path $backupRoot -ChildPath 'RegistryValuesSnapshot.json'
$snapshot | ConvertTo-Json -Depth 5 | Set-Content -LiteralPath $snapshotFile -Encoding UTF8
return $backupRoot
}
function Test-IsWindows11 {
try {
$os = Get-CimInstance -ClassName Win32_OperatingSystem -ErrorAction Stop
return ($os.Version -like '10.0.*') -and ($os.Caption -match 'Windows 11')
}
catch {
return $false
}
}
# 事前チェック
if (-not (Test-IsWindows11)) {
throw 'このスクリプトは Windows 11 向けです。'
}
if (-not (Test-IsAdministrator)) {
Write-Warning '管理者権限での実行が推奨ですHKCU のみなので必須ではありません)。'
}
$explorerAdvanced = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced'
$searchKey = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Search'
$startKey = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Start'
$hideDesktopIconsNew = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel'
$hideDesktopIconsClassic = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\ClassicStartMenu'
$desktopIconsToShow = @(
# コンピュータThis PC
'{20D04FE0-3AEA-1069-A2D8-08002B30309D}',
# コントロール パネル
'{5399E694-6CE5-4D6C-8FCE-1D8870FDCBA0}',
# ユーザー プロファイルUser''s Files
'{59031a47-3f72-44a7-89c5-5595fe6b30ee}'
)
$backupTargets = @(
@{
PsPath = $explorerAdvanced
NativePath = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced'
Values = @(
'LaunchTo',
'NavPaneShowAllFolders',
'NavPaneShowLibraries',
'NavPaneExpandToCurrentFolder',
'SeparateProcess',
'HideFileExt',
'Start_ShowSettings',
'Start_ShowExplorer',
'Start_ShowDocuments',
'Start_ShowDownloads',
'ShowTaskViewButton',
'TaskbarDa'
)
},
@{
PsPath = $searchKey
NativePath = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Search'
Values = @('SearchboxTaskbarMode', 'SearchboxTaskbarModeCache')
},
@{
PsPath = $startKey
NativePath = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Start'
Values = @('ShowSettings', 'ShowExplorer', 'ShowDocuments', 'ShowDownloads')
},
@{
PsPath = $hideDesktopIconsNew
NativePath = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\NewStartPanel'
Values = $desktopIconsToShow
},
@{
PsPath = $hideDesktopIconsClassic
NativePath = 'HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\HideDesktopIcons\ClassicStartMenu'
Values = $desktopIconsToShow
}
)
if ($WhatIfPreference) {
Write-Host 'WhatIf: バックアップ作成はスキップされます。' -ForegroundColor Yellow
}
else {
Write-Section -Title '事前バックアップ'
$backupPath = Backup-RegistryTargets -Targets $backupTargets -BaseDirectory $BackupDirectory
Write-Host ("バックアップを作成しました: {0}" -f $backupPath) -ForegroundColor Green
}
# --- エクスプローラー オプション相当 ---
Write-Section -Title 'エクスプローラーのオプション(表示/全般)'
# 「この PC の表示」: エクスプローラー起動時の表示先を「この PC」にする
# LaunchTo: 1 = This PC, 2 = Quick access
Set-RegistryDword -Path $explorerAdvanced -Name 'LaunchTo' -Value 1
# 「全てのフォルダーを表示」
Set-RegistryDword -Path $explorerAdvanced -Name 'NavPaneShowAllFolders' -Value 1
# 「ライブラリの表示」
Set-RegistryDword -Path $explorerAdvanced -Name 'NavPaneShowLibraries' -Value 1
# 「開いているフォルダーまで展開」
Set-RegistryDword -Path $explorerAdvanced -Name 'NavPaneExpandToCurrentFolder' -Value 1
# 「別のプロセスでフォルダーウインドウを開く」
Set-RegistryDword -Path $explorerAdvanced -Name 'SeparateProcess' -Value 1
# 「登録されている拡張子は表示しない」→ OFF拡張子を表示
# HideFileExt: 0 = show extensions, 1 = hide
Set-RegistryDword -Path $explorerAdvanced -Name 'HideFileExt' -Value 0
# --- デスクトップ アイコン(テーマ) ---
Write-Section -Title '個人設定 → テーマ → デスクトップ アイコン'
foreach ($clsid in $desktopIconsToShow) {
Set-RegistryDword -Path $hideDesktopIconsNew -Name $clsid -Value 0
Set-RegistryDword -Path $hideDesktopIconsClassic -Name $clsid -Value 0
}
# --- スタート(フォルダー) ---
Write-Section -Title '個人設定 → スタート → フォルダー'
# 「スタートに表示するフォルダー(設定/エクスプローラー/ドキュメント/ダウンロード)」
# Windows 11 の実環境差異に備えて、Explorer\Advanced と Start の両方に設定する。
Set-RegistryDword -Path $explorerAdvanced -Name 'Start_ShowSettings' -Value 1
Set-RegistryDword -Path $explorerAdvanced -Name 'Start_ShowExplorer' -Value 1
Set-RegistryDword -Path $explorerAdvanced -Name 'Start_ShowDocuments' -Value 1
Set-RegistryDword -Path $explorerAdvanced -Name 'Start_ShowDownloads' -Value 1
Set-RegistryDword -Path $startKey -Name 'ShowSettings' -Value 1
Set-RegistryDword -Path $startKey -Name 'ShowExplorer' -Value 1
Set-RegistryDword -Path $startKey -Name 'ShowDocuments' -Value 1
Set-RegistryDword -Path $startKey -Name 'ShowDownloads' -Value 1
# --- タスクバー ---
Write-Section -Title '個人設定 → タスクバー'
# 検索: 非表示
# SearchboxTaskbarMode: 0 = Hidden, 1 = Search icon only, 2 = Search box
Set-RegistryDword -Path $searchKey -Name 'SearchboxTaskbarMode' -Value 0
Set-RegistryDword -Path $searchKey -Name 'SearchboxTaskbarModeCache' -Value 0
# タスクビュー: オフ
Set-RegistryDword -Path $explorerAdvanced -Name 'ShowTaskViewButton' -Value 0
# ウィジット: オフWindows 11 の Widgets
# TaskbarDa: 0 = off, 1 = on
Set-RegistryDword -Path $explorerAdvanced -Name 'TaskbarDa' -Value 0
# --- 電源とバッテリー ---
Write-Section -Title 'システム → 電源とバッテリー'
# 現在アクティブな電源プランに対して、画面オフ/スリープの時間(分)を設定
Invoke-PowerCfgChange -Arguments @('/change', 'monitor-timeout-ac', '10') -Description '電源接続時: 後で画面をオフにする = 10分'
Invoke-PowerCfgChange -Arguments @('/change', 'standby-timeout-ac', '30') -Description '電源接続時: 次の時間経過後にデバイスをスリープ状態にする = 30分'
Invoke-PowerCfgChange -Arguments @('/change', 'monitor-timeout-dc', '4') -Description 'バッテリー駆動時: 後で画面をオフにする = 4分'
Invoke-PowerCfgChange -Arguments @('/change', 'standby-timeout-dc', '10') -Description 'バッテリー駆動時: 次の時間経過後にデバイスをスリープ状態にする = 10分'
Write-Host "`n完了: 設定の書き込みが終了しました。" -ForegroundColor Green
Write-Host '反映されない場合は、Explorer の再起動またはサインアウト/サインインを実施してください。'
if ($RestartExplorer) {
Write-Section -Title 'Explorer 再起動'
if ($PSCmdlet.ShouldProcess('explorer.exe', 'Restart Explorer')) {
try {
Get-Process explorer -ErrorAction SilentlyContinue | Stop-Process -Force -ErrorAction SilentlyContinue
Start-Sleep -Seconds 1
Start-Process explorer.exe | Out-Null
Write-Host 'Explorer を再起動しました。' -ForegroundColor Green
}
catch {
Write-Warning "Explorer の再起動に失敗しました: $($_.Exception.Message)"
}
}
}