From 1b4144f76f800ef4a95fee27711b14913d68572e Mon Sep 17 00:00:00 2001 From: Stephan Yelle Date: Sat, 31 Jan 2026 18:48:31 -0500 Subject: [PATCH] Add docs/# samy.functions.ps1 --- docs/# samy.functions.ps1 | 259 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 259 insertions(+) create mode 100644 docs/# samy.functions.ps1 diff --git a/docs/# samy.functions.ps1 b/docs/# samy.functions.ps1 new file mode 100644 index 0000000..6533eab --- /dev/null +++ b/docs/# samy.functions.ps1 @@ -0,0 +1,259 @@ +# samy.functions.ps1 (3-in-1) + +This file groups three core categories of functionality used by SAMY: + +1. **Bootstrap**: prepares PowerShell package tooling (NuGet provider, PowerShellGet, PackageManagement, PSGallery). +2. **Registry Helpers**: reusable functions to write registry values for current user, default user (future profiles), and existing user profiles. +3. **UI Handlers**: endpoint/task handlers invoked by the web UI (e.g., install 1Password, apply tweaks). + +The goal of this file is to provide “daily driver” functions SAMY needs across onboarding/offboarding workflows. + +> Encoding rule: save as **UTF-8 without BOM**. + +--- + +## Contents overview + +- Bootstrap + - `Initialize-NuGetProvider` +- Registry helpers + - `Set-RegistryValueInHkuRoot` + - `Set-RegistryValueForCurrentAndAllUsers` + - `Restart-ExplorerIfInteractive` +- UI Handlers (examples included in file) + - `Invoke-Install1Password` + - `Invoke-DisableAnimations` + - `Invoke-EnableNumLock` + - `Invoke-ClassicContextMenu` + +--- + +## Bootstrap + +### Initialize-NuGetProvider +**Purpose** +Ensures SAMY can install/update PowerShell modules and providers without interactive prompts (critical for unattended runs and `iwr | iex` style execution). + +**Key behaviors** +- Forces TLS 1.2 for network operations. +- Silences progress + confirmation prompts to keep runs unattended. +- Ensures provider folder paths exist: + - Current user provider assemblies path + - All users provider assemblies path (may fail without admin; handled) +- Ensures the **NuGet package provider** is installed at a minimum version. +- Imports NuGet provider after install. +- Imports/updates: + - `PackageManagement` + - `PowerShellGet` +- Optionally marks `PSGallery` as trusted to prevent prompts. + +**Why it matters** +Many PowerShell module installs trigger interactive prompts, especially on fresh machines. This function makes module installation reliable for SAMY’s automation. + +**Common failure modes** +- No internet / proxy blocks PSGallery or NuGet endpoints. +- Running under restricted execution policy or locked-down environment. +- Running without elevation when trying to write to system-wide locations (handled as “warning” for folder creation). + +**Logging** +Uses `Write-LogHybrid` with `-LogToEvent` to record bootstrap state and failures. + +**Modification notes** +- If you need stricter behavior: choose whether to `throw` in the final catch block (PackageManagement/PowerShellGet setup). +- If you need TLS 1.3+: be careful, many older environments still require TLS 1.2 compatibility. + +--- + +## Registry Helpers + +### Set-RegistryValueInHkuRoot +**Purpose** +Writes a registry value relative to a given `HKEY_USERS` hive root. + +**Parameters** +- `HkuRoot`: registry root path (e.g. `Registry::HKEY_USERS\S-1-5-21-...`) +- `RelativeKeyPath`: relative key path under the root +- `Name`: value name +- `Type`: value type (String, DWord, etc.) +- `Value`: value data + +**Behavior** +- Ensures the key exists. +- Uses `New-ItemProperty` with `-Force` so it can create or overwrite. + +**When to use** +When you already have the target user hive loaded and you want a consistent writer. + +--- + +### Set-RegistryValueForCurrentAndAllUsers +**Purpose** +Applies the same registry setting to: +1. **Current user** (HKCU) if meaningful/available +2. **Default user profile hive** (`C:\Users\Default\NTUSER.DAT`) so future users inherit the setting +3. **All existing user profiles** by enumerating ProfileList and mounting each `NTUSER.DAT` as needed + +**High-level flow** +1. Try write to HKCU (best-effort; may be skipped under SYSTEM). +2. Default User: + - Loads `C:\Users\Default\NTUSER.DAT` into `HKEY_USERS\SVS_DefaultUser` (if not already loaded) + - Writes the setting + - Unloads the hive (only if this function loaded it) +3. Existing profiles: + - Enumerates `HKLM:\...\ProfileList` + - Identifies user SIDs (`S-1-5-21-...`) + - If hive already loaded under `HKEY_USERS\`, writes directly + - Otherwise mounts `NTUSER.DAT` to a temporary key, writes, then unloads + +**Why it matters** +Many Windows customizations are stored per-user. To make onboarding consistent, SAMY must update: +- the active user (if running interactively) +- the default profile (future logins) +- every existing profile on the machine (shared devices, re-used devices) + +**Important safety notes** +- Loading/unloading hives is sensitive: + - A loaded hive can’t always be unloaded if something else is holding a handle. + - The function tracks whether it loaded the hive (`$didLoad`) to avoid unloading someone else’s mount. +- Profile iteration excludes non-standard SIDs by regex filter. +- Some profiles may not have `NTUSER.DAT` (system profiles, corrupt profiles, etc.). Those are skipped safely. + +**Logging** +Uses `Write-LogHybrid` to record default hive load/unload outcomes and per-setting success. + +**Modification notes** +- If you add more settings, prefer calling this helper rather than duplicating hive logic. +- If you need to write to HKLM machine-wide instead, do that outside this helper. +- If you ever see “unload failed”, it’s usually because something still holds a handle to the loaded hive. + +--- + +### Restart-ExplorerIfInteractive +**Purpose** +Restarts Explorer to apply UI-related registry changes (taskbar, context menu, shell tweaks). + +**Behavior** +- Skips restart when running as `SYSTEM` to avoid breaking non-interactive phases. +- Stops `explorer.exe` and restarts it. + +**Modification notes** +- If this ever runs during OOBE/Autopilot contexts, you may want stronger checks than `$env:USERNAME -ne 'SYSTEM'`. + +--- + +## UI Handlers + +These functions are designed to be invoked by the SAMY web UI through task routing. +Each handler: +- parses optional JSON POST body (e.g., selected options) +- executes the requested action +- logs results via `Write-LogHybrid` +- returns a response to the UI via `Send-Text` + +### Invoke-Install1Password +**Purpose** +Installs 1Password desktop app and optionally forces browser extension install for Chrome and/or Edge. + +**Inputs** +- Defaults to installing the desktop app if no UI selection is provided. +- If POST JSON contains `checkedValues`, uses that list. + +**Actions** +- Desktop app via `winget` (`AgileBits.1Password`) +- Chrome extension by setting policy: + - `HKLM:\SOFTWARE\Policies\Google\Chrome\ExtensionInstallForcelist` +- Edge extension by setting policy: + - `HKLM:\SOFTWARE\Policies\Microsoft\Edge\ExtensionInstallForcelist` + +**Notes** +- Forcelist policy requires admin to write HKLM policies. +- Browser extension IDs must remain correct; update if vendor changes. + +--- + +### Invoke-DisableAnimations +**Purpose** +Applies UI “reduced motion” style tweaks by writing registry values across all users. + +**Default selection** +If no options are provided, defaults to enabling all: +- `window`, `taskbar`, `menus` + +**Settings applied** +- Window animation: `MinAnimate` +- Taskbar animations: `TaskbarAnimations` +- Menu delay: `MenuShowDelay` + +**Post-action** +- Restarts Explorer if taskbar changes were applied. + +--- + +### Invoke-EnableNumLock +**Purpose** +Turns NumLock on by default (affects logon screen + default profile behavior). + +**Where it writes** +- `Registry::HKEY_USERS\.DEFAULT\Control Panel\Keyboard` + - `InitialKeyboardIndicators = "2"` (string) + +**Notes** +- Uses `.DEFAULT` so it impacts the logon screen and baseline behavior. +- This does not guarantee every vendor keyboard/BIOS setting, but covers the Windows side. + +--- + +### Invoke-ClassicContextMenu +**Purpose** +Enables Windows 11 classic right-click context menu behavior. + +**Where it writes** +- `HKCU:\Software\Classes\CLSID\{86ca1aa0-34aa-4e8b-a509-50c905bae2a2}\InprocServer32` + - Default value set to blank + +**Post-action** +- Restarts Explorer to apply immediately. + +**Notes** +- This is per-user (HKCU). If you want it for all users, use the registry helpers to apply across profiles. + +--- + +## Logging expectations + +All functions log via `Write-LogHybrid` using categories like: +- `Bootstrap` +- `Tweaks` +- `SVSApps` +- `UI` + +When `-LogToEvent` is enabled, events are also written to the configured Windows Event Log (e.g., `SVSMSP Events`) using the project’s Event Log binding logic. + +--- + +## Common maintenance tasks + +### Add a new UI handler +1. Create `Invoke-` function. +2. Parse POST JSON if needed (`checkedValues` pattern). +3. Use `Write-LogHybrid` for logging. +4. Use `Send-Text` for responses. +5. Ensure the router maps a route/task name to this handler. + +### Add a new per-user tweak +- Prefer using `Set-RegistryValueForCurrentAndAllUsers` to apply it to: + - current user (HKCU) + - Default User hive + - existing profiles + +### Debug “it works the second time” issues +That often means initialization happens after first use (especially Event Logs and provider bootstrap). +Ensure bootstrap/init happens before first call site that depends on it. + +--- + +## Quick troubleshooting commands + +### Check Event Log source binding +```powershell +[System.Diagnostics.EventLog]::LogNameFromSourceName('SVMSP_Module','.')