categories/ExplorerStart.ps1
|
# Explorer/Start menu tweaks: show file extensions, disable Start menu "Recommended" section, # Explorer startup location, hide OneDrive/3D Objects/Music from "This PC", hide "Include in # library"/"Give access to"/"Share" context menu entries. All per-user (HKCU/HKCR-user-scope) # values, so this category does not require elevation. # # ponytail: "add custom folders to This PC" and drive-letter ordering were both in scope per the # original ask, but dropped here - the former needs a user-chosen folder path (doesn't fit the # fixed-target toggle shape every other Action uses), the latter has no confirmed registry # mechanism (specs/006-win11debloat-parity/research.md). Add either only with a real, verified # mechanism in hand, not a guess. # # "Hide from This PC" and "hide context menu entry" actions delete a whole registry key rather # than set a value - the TargetIdentifier's value-name half is the literal sentinel "(delete)" # so Set-OctaExplorerStartAction knows to Remove-Item the key instead of Set-ItemProperty. The # existing Registry snapshot mechanism (export-before-change) already handles this correctly # with no changes needed: it exports the whole key before deleting it, and re-importing that # export on undo recreates it. function Get-OctaExplorerStartCategory { [CmdletBinding()] param() return [pscustomobject]@{ Id = 'explorer-start' DisplayName = 'Explorer/Start' Description = 'Show file extensions, disable Start menu recommendations' RequiresElevation = $false ContainsIrreversibleActions = $false GetActionsFunction = 'Get-OctaExplorerStartActions' ApplyActionFunction = 'Set-OctaExplorerStartAction' } } function Get-OctaExplorerStartActions { [CmdletBinding()] param() $actions = @() $regPath = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Advanced' $current = (Get-ItemProperty -Path $regPath -Name 'HideFileExt' -ErrorAction SilentlyContinue).HideFileExt if ($null -eq $current -or $current -ne 0) { $displayCurrent = if ($null -eq $current) { '(not set)' } else { $current } $actions += New-OctaAction -TargetType Registry -TargetIdentifier "$regPath|HideFileExt" ` -CurrentValue $displayCurrent -PlannedValue 0 -Reversible $true } $recommended = (Get-ItemProperty -Path $regPath -Name 'Start_IrisRecommendations' -ErrorAction SilentlyContinue).Start_IrisRecommendations if ($null -eq $recommended -or $recommended -ne 0) { $displayCurrent = if ($null -eq $recommended) { '(not set)' } else { $recommended } $actions += New-OctaAction -TargetType Registry -TargetIdentifier "$regPath|Start_IrisRecommendations" ` -CurrentValue $displayCurrent -PlannedValue 0 -Reversible $true } $launchTo = (Get-ItemProperty -Path $regPath -Name 'LaunchTo' -ErrorAction SilentlyContinue).LaunchTo if ($null -eq $launchTo -or $launchTo -ne 1) { $displayCurrent = if ($null -eq $launchTo) { '(not set)' } else { $launchTo } $actions += New-OctaAction -TargetType Registry -TargetIdentifier "$regPath|LaunchTo" ` -CurrentValue $displayCurrent -PlannedValue 1 -Reversible $true } # "Hide from This PC" via each folder's FolderDescriptions ThisPCPolicy value (String, not # DWord - the actual type this specific value uses). $thisPcFolders = @( @{ Guid = '{0DB7E03F-FC29-4DC6-9020-FF41B59E513A}'; Name = '3D Objects' }, @{ Guid = '{1CF1260C-4DD0-4ebb-811F-33C572699FDE}'; Name = 'Music' } ) foreach ($folder in $thisPcFolders) { $fdPath = "HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\FolderDescriptions\$($folder.Guid)" $policy = (Get-ItemProperty -Path $fdPath -Name 'ThisPCPolicy' -ErrorAction SilentlyContinue).ThisPCPolicy if ($policy -ne 'Hide') { $displayCurrent = if ($null -eq $policy) { '(not set)' } else { $policy } $actions += New-OctaAction -TargetType Registry -TargetIdentifier "$fdPath|ThisPCPolicy" ` -CurrentValue $displayCurrent -PlannedValue 'Hide' -Reversible $true } } # Whole-key-delete-to-hide actions - see file header comment for the "(delete)" sentinel. $hideKeys = @( @{ Path = 'HKCU:\Software\Microsoft\Windows\CurrentVersion\Explorer\Desktop\NameSpace\{018D5C66-4533-4307-9B53-224DE2ED1FE6}'; Label = 'OneDrive from Explorer navigation pane' }, @{ Path = 'HKCR:\Folder\ShellEx\ContextMenuHandlers\Library Location'; Label = '"Include in library" context menu entry' }, @{ Path = 'HKCR:\*\shellex\ContextMenuHandlers\Sharing'; Label = '"Give access to" context menu entry' }, @{ Path = 'HKCR:\*\shellex\ContextMenuHandlers\ModernSharing'; Label = '"Share" context menu entry' } ) foreach ($hk in $hideKeys) { # -LiteralPath: "*" in HKCR:\*\... is a literal key name (HKEY_CLASSES_ROOT's real # "all file types" key), not a wildcard - without -LiteralPath, Test-Path enumerates # every one of HKCR's tens of thousands of subkeys trying to match it (found by hanging # for minutes during this feature's own implementation). if (Test-Path -LiteralPath $hk.Path) { $actions += New-OctaAction -TargetType Registry -TargetIdentifier "$($hk.Path)|(delete)" ` -CurrentValue 'present' -PlannedValue 'removed' -Reversible $true } } return $actions } function Set-OctaExplorerStartAction { [CmdletBinding()] param([Parameter(Mandatory)]$Action) $keyPath, $valueName = $Action.TargetIdentifier -split '\|', 2 if ($valueName -eq '(delete)') { Remove-Item -LiteralPath $keyPath -Recurse -Force -ErrorAction SilentlyContinue return } if (-not (Test-Path -LiteralPath $keyPath)) { New-Item -Path $keyPath -Force | Out-Null } $type = if ($Action.PlannedValue -is [string]) { 'String' } else { 'DWord' } Set-ItemProperty -Path $keyPath -Name $valueName -Value $Action.PlannedValue -Type $type } |