This commit is contained in:
2026-07-29 04:54:08 +09:00
parent 3f35a54e0a
commit c02d6936fa
12 changed files with 704 additions and 5 deletions
+83 -5
View File
@@ -34,8 +34,18 @@ windows/
│
├── system/
│ ├── taskbar.dsc.yaml
│ ├── personalization.dsc.yaml
│ ├── start.dsc.yaml
│ ├── device-usage.dsc.yaml
│ ├── explorer.dsc.yaml
│ ├── ime.dsc.yaml
│ ├── advanced-settings/
│ │ ├── configuration.dsc.yaml
│ │ └── apply.ps1
│ ├── lock-screen/
│ │ └── apply.ps1
│ ├── power/
│ │ └── apply.ps1
│ └── wallpaper/
│ ├── apply.ps1
│ └── wallpaper.theme
@@ -118,10 +128,16 @@ dsc config set --file .\configuration.dsc.yaml
& .\applications\chatgpt\apply.ps1
& .\applications\git\apply.ps1
& .\applications\vscode\apply.ps1
& .\system\advanced-settings\apply.ps1
& .\system\lock-screen\apply.ps1
& .\system\power\apply.ps1
& .\system\wallpaper\apply.ps1
```
The specialized scripts own the details of their own configuration.
The specialized scripts own the details of their own configuration. Only the
advanced-settings script requests elevation, for the protected Explorer policy
and machine-wide long-path setting; Scoop, DSC user settings, and application
configuration stay in the normal user process.
## Packages
@@ -156,7 +172,7 @@ installation requires explicit package/source agreement acceptance.
```powershell
winget install `
--id 9NT1R1C2HH7J `
--id 9PLM9XGG6VKS `
--source msstore `
--accept-package-agreements `
--accept-source-agreements `
@@ -164,8 +180,8 @@ winget install `
--disable-interactivity
```
The Store product ID `9NT1R1C2HH7J` is the ChatGPT Windows app. The previously
used `9PLM9XGG6VKS` ID is not used here.
The Store product ID `9PLM9XGG6VKS` is the ChatGPT Windows app managed here.
ChatGPT Classic (`9NT1R1C2HH7J`) is intentionally not installed.
7-Zip is intentionally installed with its normal Windows installer through
WinGet rather than as a portable Scoop package, because the normal installer
@@ -173,6 +189,35 @@ provides Explorer shell integration.
## Windows settings
### Personalization
`system/personalization.dsc.yaml` configures:
- automatic accent color
- dark Windows and app modes
- picture mode for the lock screen
- lock-screen facts and tips: off
- automatic lock-screen status selection: off
`system/lock-screen/apply.ps1` uses the Windows LockScreen API to select the
built-in `%SystemRoot%\Web\Screen\img100.jpg` image. The script first checks the
current image and only calls the API when the image differs.
### Start
`system/start.dsc.yaml` configures:
- recently added apps: on
- recommended and recent files: off
- recommendations for tips, shortcuts, and new apps: off
- most used apps: on
### Device usage
`system/device-usage.dsc.yaml` explicitly clears both `Intent` and `Priority`
for Development, Gaming, Family, Creativity, School, Entertainment, and
Business.
### Taskbar
`system/taskbar.dsc.yaml` configures:
@@ -187,6 +232,9 @@ provides Explorer shell integration.
`system/explorer.dsc.yaml` configures:
- show known file extensions
- show hidden files and protected operating-system files
- show the full path in the title bar
- show empty drives
7-Zip context-menu integration is left to the official 7-Zip installer. No
unsupported Explorer context-menu patches are applied.
@@ -198,6 +246,31 @@ unsupported Explorer context-menu patches are applied.
- Muhenkan: IME Off
- Henkan: IME On
### Advanced settings and clipboard
`system/advanced-settings/configuration.dsc.yaml` configures:
- End task from the taskbar: on
- clipboard history: on
`system/advanced-settings/apply.ps1` additionally configures:
- "Run as different user" in Start: on
- Win32 long paths: on
The long-path setting is machine-wide. The script enables "Run as different
user" through the protected per-user policy key, passes the original user's SID
through UAC, writes both settings to the intended hives, and verifies their
values. A restart is recommended after changing long-path support because a
process can cache the setting after its first affected file call.
### Power
`system/power/apply.ps1` uses the Windows 11 power-mode API to select Best
performance independently for both AC and battery power. It verifies both
configured modes, then sets the automatic Energy Saver threshold to zero on
every installed power scheme.
## Git
Git's user configuration lives in:
@@ -212,6 +285,8 @@ It currently contains:
[user]
name = moons-14
email = [email protected]
[core]
sshCommand = C:/Windows/System32/OpenSSH/ssh.exe
```
`applications/git/apply.ps1` copies this file to:
@@ -352,9 +427,12 @@ grouped by responsibility:
```text
system/taskbar.dsc.yaml
system/personalization.dsc.yaml
system/start.dsc.yaml
system/device-usage.dsc.yaml
system/explorer.dsc.yaml
system/ime.dsc.yaml
system/privacy.dsc.yaml
system/advanced-settings/configuration.dsc.yaml
```
When adding a new DSC document, include it from `configuration.dsc.yaml`.
+2
View File
@@ -1,3 +1,5 @@
[user]
name = moons-14
email = [email protected]
[core]
sshCommand = C:/Windows/System32/OpenSSH/ssh.exe
+20
View File
@@ -11,11 +11,31 @@ resources:
properties:
configurationFile: system/taskbar.dsc.yaml
- name: Personalization
type: Microsoft.DSC/Include
properties:
configurationFile: system/personalization.dsc.yaml
- name: Start
type: Microsoft.DSC/Include
properties:
configurationFile: system/start.dsc.yaml
- name: Device usage
type: Microsoft.DSC/Include
properties:
configurationFile: system/device-usage.dsc.yaml
- name: Explorer
type: Microsoft.DSC/Include
properties:
configurationFile: system/explorer.dsc.yaml
- name: Advanced settings
type: Microsoft.DSC/Include
properties:
configurationFile: system/advanced-settings/configuration.dsc.yaml
- name: Microsoft IME
type: Microsoft.DSC/Include
properties:
@@ -0,0 +1,78 @@
[CmdletBinding()]
param(
[string] $TargetUserSid = [Security.Principal.WindowsIdentity]::GetCurrent().User.Value
)
$ErrorActionPreference = "Stop"
function Test-Administrator {
$identity = [Security.Principal.WindowsIdentity]::GetCurrent()
$principal = [Security.Principal.WindowsPrincipal]::new($identity)
return $principal.IsInRole(
[Security.Principal.WindowsBuiltInRole]::Administrator
)
}
if (-not (Test-Administrator)) {
$powershell = (Get-Process -Id $PID).Path
$arguments = @(
"-NoProfile"
"-ExecutionPolicy"
"Bypass"
"-File"
('"{0}"' -f $PSCommandPath)
"-TargetUserSid"
$TargetUserSid
)
$process = Start-Process `
-FilePath $powershell `
-ArgumentList $arguments `
-Verb RunAs `
-Wait `
-PassThru
if ($process.ExitCode -ne 0) {
throw "Elevated advanced settings failed with exit code $($process.ExitCode)."
}
return
}
$explorerPolicyKey = Join-Path `
"Registry::HKEY_USERS\$TargetUserSid" `
"Software\Policies\Microsoft\Windows\Explorer"
New-Item -Path $explorerPolicyKey -Force | Out-Null
New-ItemProperty `
-Path $explorerPolicyKey `
-Name "ShowRunAsDifferentUserInStart" `
-PropertyType DWord `
-Value 1 `
-Force | Out-Null
$showRunAsDifferentUser = Get-ItemPropertyValue `
-Path $explorerPolicyKey `
-Name "ShowRunAsDifferentUserInStart"
if ($showRunAsDifferentUser -ne 1) {
throw 'Failed to enable "Run as different user" in Start.'
}
$fileSystemKey = "HKLM:\SYSTEM\CurrentControlSet\Control\FileSystem"
New-ItemProperty `
-Path $fileSystemKey `
-Name "LongPathsEnabled" `
-PropertyType DWord `
-Value 1 `
-Force | Out-Null
$longPathsEnabled = Get-ItemPropertyValue `
-Path $fileSystemKey `
-Name "LongPathsEnabled"
if ($longPathsEnabled -ne 1) {
throw "Failed to enable Win32 long paths."
}
@@ -0,0 +1,20 @@
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Enable End task from the taskbar
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced\TaskbarDeveloperSettings
valueName: TaskbarEndTask
valueData:
DWord: 1
_exist: true
- name: Enable clipboard history
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Clipboard
valueName: EnableClipboardHistory
valueData:
DWord: 1
_exist: true
+128
View File
@@ -0,0 +1,128 @@
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Disable development usage
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\CloudExperienceHost\Intent\developer
valueName: Intent
valueData:
DWord: 0
_exist: true
- name: Clear development priority
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\CloudExperienceHost\Intent\developer
valueName: Priority
valueData:
DWord: 0
_exist: true
- name: Disable gaming usage
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\CloudExperienceHost\Intent\gaming
valueName: Intent
valueData:
DWord: 0
_exist: true
- name: Clear gaming priority
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\CloudExperienceHost\Intent\gaming
valueName: Priority
valueData:
DWord: 0
_exist: true
- name: Disable family usage
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\CloudExperienceHost\Intent\family
valueName: Intent
valueData:
DWord: 0
_exist: true
- name: Clear family priority
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\CloudExperienceHost\Intent\family
valueName: Priority
valueData:
DWord: 0
_exist: true
- name: Disable creativity usage
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\CloudExperienceHost\Intent\creative
valueName: Intent
valueData:
DWord: 0
_exist: true
- name: Clear creativity priority
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\CloudExperienceHost\Intent\creative
valueName: Priority
valueData:
DWord: 0
_exist: true
- name: Disable school usage
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\CloudExperienceHost\Intent\schoolwork
valueName: Intent
valueData:
DWord: 0
_exist: true
- name: Clear school priority
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\CloudExperienceHost\Intent\schoolwork
valueName: Priority
valueData:
DWord: 0
_exist: true
- name: Disable entertainment usage
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\CloudExperienceHost\Intent\entertainment
valueName: Intent
valueData:
DWord: 0
_exist: true
- name: Clear entertainment priority
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\CloudExperienceHost\Intent\entertainment
valueName: Priority
valueData:
DWord: 0
_exist: true
- name: Disable business usage
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\CloudExperienceHost\Intent\business
valueName: Intent
valueData:
DWord: 0
_exist: true
- name: Clear business priority
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\CloudExperienceHost\Intent\business
valueName: Priority
valueData:
DWord: 0
_exist: true
+36
View File
@@ -9,3 +9,39 @@ resources:
valueData:
DWord: 0
_exist: true
- name: Show hidden files
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced
valueName: Hidden
valueData:
DWord: 1
_exist: true
- name: Show protected operating system files
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced
valueName: ShowSuperHidden
valueData:
DWord: 1
_exist: true
- name: Show full path in title bar
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\CabinetState
valueName: FullPath
valueData:
DWord: 1
_exist: true
- name: Show empty drives
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced
valueName: HideDrivesWithNoMedia
valueData:
DWord: 0
_exist: true
+87
View File
@@ -0,0 +1,87 @@
$ErrorActionPreference = "Stop"
function Wait-WinRtOperation {
param(
[Parameter(Mandatory)]
[object] $Operation,
[Parameter(Mandatory)]
[type] $ResultType
)
$asTask = [System.WindowsRuntimeSystemExtensions].GetMethods() |
Where-Object {
$_.Name -eq "AsTask" -and
$_.IsGenericMethod -and
$_.GetParameters().Count -eq 1 -and
$_.GetParameters()[0].ParameterType.Name -eq "IAsyncOperation``1"
} |
Select-Object -First 1
if (-not $asTask) {
throw "The WinRT AsTask adapter was not found."
}
$task = $asTask.MakeGenericMethod($ResultType).Invoke($null, @($Operation))
return $task.GetAwaiter().GetResult()
}
function Wait-WinRtAction {
param(
[Parameter(Mandatory)]
[object] $Action
)
$asTask = [System.WindowsRuntimeSystemExtensions].GetMethods() |
Where-Object {
$_.Name -eq "AsTask" -and
-not $_.IsGenericMethod -and
$_.GetParameters().Count -eq 1 -and
$_.GetParameters()[0].ParameterType.Name -eq "IAsyncAction"
} |
Select-Object -First 1
if (-not $asTask) {
throw "The WinRT action adapter was not found."
}
$task = $asTask.Invoke($null, @($Action))
$task.GetAwaiter().GetResult()
}
Add-Type -AssemblyName System.Runtime.WindowsRuntime
[Windows.Storage.StorageFile, Windows.Storage, ContentType = WindowsRuntime] |
Out-Null
[Windows.System.UserProfile.LockScreen, Windows.System.UserProfile, ContentType = WindowsRuntime] |
Out-Null
$imagePath = Join-Path $env:SystemRoot "Web\Screen\img100.jpg"
if (-not (Test-Path -LiteralPath $imagePath -PathType Leaf)) {
throw "The default Windows lock screen image was not found: $imagePath"
}
$currentImage = [Windows.System.UserProfile.LockScreen]::OriginalImageFile
$currentPath = if ($currentImage) {
$currentImage.AbsolutePath.Replace("/", "\")
}
if ($currentPath -ieq $imagePath) {
return
}
$file = Wait-WinRtOperation `
-Operation ([Windows.Storage.StorageFile]::GetFileFromPathAsync($imagePath)) `
-ResultType ([Windows.Storage.StorageFile])
Wait-WinRtAction `
-Action ([Windows.System.UserProfile.LockScreen]::SetImageFileAsync($file))
$updatedPath = [Windows.System.UserProfile.LockScreen]::OriginalImageFile.AbsolutePath.Replace(
"/",
"\"
)
if ($updatedPath -ine $imagePath) {
throw "Windows did not accept the default lock screen image."
}
+71
View File
@@ -0,0 +1,71 @@
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Use dark app mode
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize
valueName: AppsUseLightTheme
valueData:
DWord: 0
_exist: true
- name: Use dark Windows mode
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\Themes\Personalize
valueName: SystemUsesLightTheme
valueData:
DWord: 0
_exist: true
- name: Choose accent color automatically
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Control Panel\Desktop
valueName: AutoColorization
valueData:
DWord: 1
_exist: true
- name: Disable rotating lock screen
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager
valueName: RotatingLockScreenEnabled
valueData:
DWord: 0
_exist: true
- name: Disable lock screen facts and tips
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager
valueName: RotatingLockScreenOverlayEnabled
valueData:
DWord: 0
_exist: true
- name: Disable lock screen slideshow
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\ContentDeliveryManager
valueName: SlideshowEnabled
valueData:
DWord: 0
_exist: true
- name: Do not automatically select lock screen widgets
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\Lock Screen
valueName: AutoSelectWidgetsOnLockScreen
valueData:
DWord: 0
_exist: true
- name: Clear selected lock screen status
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\Lock Screen\FeedManager\Selected
_exist: false
+138
View File
@@ -0,0 +1,138 @@
$ErrorActionPreference = "Stop"
if (-not ("WindowsPowerMode.NativeMethods" -as [type])) {
Add-Type -TypeDefinition @"
using System;
using System.Runtime.InteropServices;
namespace WindowsPowerMode
{
public static class NativeMethods
{
[DllImport("powrprof.dll")]
public static extern uint PowerSetUserConfiguredACPowerMode(
ref Guid powerModeGuid);
[DllImport("powrprof.dll")]
public static extern uint PowerSetUserConfiguredDCPowerMode(
ref Guid powerModeGuid);
[DllImport("powrprof.dll")]
public static extern uint PowerGetUserConfiguredACPowerMode(
out Guid powerModeGuid);
[DllImport("powrprof.dll")]
public static extern uint PowerGetUserConfiguredDCPowerMode(
out Guid powerModeGuid);
}
}
"@
}
function Assert-Win32Success {
param(
[Parameter(Mandatory)]
[uint32] $Result,
[Parameter(Mandatory)]
[string] $Operation
)
if ($Result -ne 0) {
$message = [ComponentModel.Win32Exception]::new([int] $Result).Message
throw "$Operation failed: $message (error $Result)."
}
}
function Invoke-PowerCfg {
param(
[Parameter(Mandatory)]
[string[]] $Arguments
)
& $script:powerCfg @Arguments | Out-Null
if ($LASTEXITCODE -ne 0) {
throw "powercfg $($Arguments -join ' ') failed with exit code $LASTEXITCODE."
}
}
$bestPerformance = [guid] "ded574b5-45a0-4f42-8737-46345c09c238"
$result = [WindowsPowerMode.NativeMethods]::PowerSetUserConfiguredACPowerMode(
[ref] $bestPerformance
)
Assert-Win32Success $result "Setting the AC power mode"
$result = [WindowsPowerMode.NativeMethods]::PowerSetUserConfiguredDCPowerMode(
[ref] $bestPerformance
)
Assert-Win32Success $result "Setting the DC power mode"
$actualAcMode = [guid]::Empty
$result = [WindowsPowerMode.NativeMethods]::PowerGetUserConfiguredACPowerMode(
[ref] $actualAcMode
)
Assert-Win32Success $result "Reading the AC power mode"
$actualDcMode = [guid]::Empty
$result = [WindowsPowerMode.NativeMethods]::PowerGetUserConfiguredDCPowerMode(
[ref] $actualDcMode
)
Assert-Win32Success $result "Reading the DC power mode"
if ($actualAcMode -ne $bestPerformance -or $actualDcMode -ne $bestPerformance) {
throw "Windows did not retain Best performance for both AC and DC power."
}
$script:powerCfg = Join-Path $env:SystemRoot "System32\powercfg.exe"
$energySaverSubgroup = "de830923-a562-41af-a086-e3a2c6bad2da"
$energySaverThreshold = "e69653ca-cf7f-4f05-aa73-cb833fa90ad4"
$guidPattern = "[0-9a-fA-F]{8}(?:-[0-9a-fA-F]{4}){3}-[0-9a-fA-F]{12}"
$activeSchemeOutput = & $script:powerCfg /getactivescheme
if ($LASTEXITCODE -ne 0) {
throw "Failed to read the active power scheme."
}
$activeScheme = [regex]::Match(
($activeSchemeOutput -join [Environment]::NewLine),
$guidPattern
).Value
if (-not $activeScheme) {
throw "The active power scheme GUID could not be parsed."
}
$schemeOutput = & $script:powerCfg /list
if ($LASTEXITCODE -ne 0) {
throw "Failed to enumerate power schemes."
}
$schemes = [regex]::Matches(
($schemeOutput -join [Environment]::NewLine),
$guidPattern
).Value | Sort-Object -Unique
if (-not $schemes) {
throw "No power schemes were found."
}
foreach ($scheme in $schemes) {
Invoke-PowerCfg @(
"/setacvalueindex"
$scheme
$energySaverSubgroup
$energySaverThreshold
"0"
)
Invoke-PowerCfg @(
"/setdcvalueindex"
$scheme
$energySaverSubgroup
$energySaverThreshold
"0"
)
}
Invoke-PowerCfg @("/setactive", $activeScheme)
+38
View File
@@ -0,0 +1,38 @@
$schema: https://aka.ms/dsc/schemas/v3/bundled/config/document.json
resources:
- name: Show recently added apps
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\Start
valueName: ShowRecentList
valueData:
DWord: 1
_exist: true
- name: Hide recommended and recent files
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced
valueName: Start_TrackDocs
valueData:
DWord: 0
_exist: true
- name: Hide recommendations for tips and new apps
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced
valueName: Start_IrisRecommendations
valueData:
DWord: 0
_exist: true
- name: Show most used apps
type: Microsoft.Windows/Registry
properties:
keyPath: HKCU\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced
valueName: Start_TrackProgs
valueData:
DWord: 1
_exist: true
+3
View File
@@ -12,6 +12,9 @@ try {
& .\applications\chatgpt\apply.ps1
& .\applications\git\apply.ps1
& .\applications\vscode\apply.ps1
& .\system\advanced-settings\apply.ps1
& .\system\lock-screen\apply.ps1
& .\system\power\apply.ps1
& .\system\wallpaper\apply.ps1
}
finally {