333 lines
13 KiB
PowerShell
333 lines
13 KiB
PowerShell
#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)"
|
||
}
|
||
}
|
||
}
|
||
|