Release v4.0.0 - src/ layout, SPSUpdate.Common module, psd1 config + DPAPI secrets#18
Merged
Conversation
…gs, gitignore) Align SPSUpdate tooling with SPSWeather/SPSUserSync: - .editorconfig: UTF-8 (BOM+CRLF for ps1/psm1/psd1), LF elsewhere - .gitattributes: enforce encoding/line-ending policy for WinPS 5.1 - PSScriptAnalyzerSettings.psd1: Error/Warning severity baseline - .gitignore: ignore secrets.psd1, real src/Config/*.psd1, logs and generated *-ContentDBs.json runtime output Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Introduce src/Modules/SPSUpdate.Common with a manifest (v4.0.0) and a dot-sourcing loader, splitting the former util.psm1 + sps.util.psm1 into one file per function: Public (17): Add-SPSScheduledTask, Add-SPSUpdateEvent, Copy-SPSSideBySideFilesRemote, Get-SPSInstalledProductVersion, Get-SPSSecret, Get-SPSServersPatchStatus, Initialize-SPSContentDbJsonFile, Mount-SPSContentDatabase, Remove-SPSScheduledTask, Set-SPSSecret, Set-SPSSideBySideToken, Start-SPSConfigExe, Start-SPSConfigExeRemote, Start-SPSProductUpdate, Start-SPSScheduledTask, Test-SPSPendingReboot, Update-SPSContentDatabase. Private: Invoke-SPSCommand, Clear-ComObject, Get-SPSLocalVersionInfo, Get-SPSConfigRoot. Add-SPSUpdateEvent is now self-contained (version/user resolved from the module instead of script-scope variables) and re-points a mismapped event source to the SPSUpdate log. Get-SPSSecret/Set-SPSSecret add the DPAPI secrets.psd1 store. PSScriptAnalyzer clean; module imports with 17 functions + 1 alias. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the per-farm JSON configs with a single documented psd1 template (src/Config/CONTOSO-PROD.example.psd1) that lists every option with its possible values inline. Add secrets.example.psd1 for the DPAPI credential store. Rename the StoredCredential key to CredentialKey to match the new Get-SPSSecret/Set-SPSSecret model. Runtime/output files (ContentDB inventory, logs) stay JSON by design; only the hand-edited environment config moves to psd1. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- Move entry script to src/SPSUpdate.ps1 and import SPSUpdate.Common from src/Modules instead of the flat util.psm1/sps.util.psm1 helpers. - Read the environment config with Import-PowerShellDataFile (*.psd1); validate required keys and apply safe defaults for optional behaviour keys (ProductUpdate/ShutdownServices/UpgradeContentDatabase default to $true, MountContentDatabase/SideBySide default to off). - Replace Windows Credential Manager (Get/New/Remove-StoredCredential) with the DPAPI secret store: Install writes via Set-SPSSecret, Uninstall removes it, Default/sequence runs read via Get-SPSSecret. CredentialKey replaces StoredCredential. - Derive the version banner from the module manifest. - Delete the legacy scripts/ tree, including the bundled credentialmanager binaries and the old JSON configs. Parse OK and PSScriptAnalyzer clean. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Replace the legacy scripts/JSON-oriented tests with a cross-platform suite: - SPSUpdate.Common.Tests.ps1: manifest validity, exact public export set, private helpers hidden, alias export, one-function-per-file, parse and UTF-8 BOM conventions, ShouldProcess/mandatory parameter contracts, Add-SPSUpdateEvent self-heal, and a DPAPI secret round-trip (Windows-only). - Configuration.Tests.ps1: example psd1 config and secrets parse, required keys present, StoredCredential removed, PASTE placeholder preserved. 103 passed / 0 failed / 1 skipped (DPAPI test is Windows-only) on pwsh 7. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- release.yml: zip the *contents* of src/ (cd src && zip -r) so the archive extracts to Config/, Modules/, SPSUpdate.ps1 with no src/ wrapper, and add contents:write permission. - pester.yml: trigger on src/**, tests/**, PSScriptAnalyzerSettings.psd1; run PSScriptAnalyzer against src/SPSUpdate.ps1 and the SPSUpdate.Common module; grant checks/pull-requests write for the results publisher. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
- README.md: trim to a short overview + quick links to the wiki, matching the SPSWeather/SPSUserSync style. - wiki/: rewrite Home, Getting-Started, Configuration and Usage for the src/ layout, psd1 config (CredentialKey), DPAPI secret store and the SPSUpdate.Common module; add a Release-Process page and a _Sidebar.md navigation. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Align with the SPSWeather CredSSP improvements: open the remote session with -ErrorAction Stop inside try/catch and always attach it, so a failed New-PSSession throws a clear error instead of letting Invoke-Command run the SharePoint scriptblock locally on the master server with no session (which silently targeted the wrong host for PSConfig and side-by-side operations). Add an OpenTimeout (30s) and clearer remote-failure messages. Preserves the version-aware base script (PSSnapin on 2016/2019, none on SE). Documented under [4.0.0] Fixed. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Re-add src/SPSUpdate_README.md so an offline server still has a self- contained installation guide inside the release ZIP (next to SPSUpdate.ps1). Rewritten for v4.0.0: psd1 config with CredentialKey, DPAPI secrets.psd1 (no Credential Manager), the Modules\ layout, and corrected behaviour notes (no DSC dependency, no DSC cleanup, no reboot-status step). Documents the read-only InitContentDB action and clarifies that ProductUpdate runs locally without InstallAccount. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Gate the step-2 inventory read/prime on $Action -eq 'Default' so that -Action ProductUpdate (and Install/Uninstall) no longer generate or refresh the ContentDatabase inventory JSON. The Default master run and the -Sequence sub-runs still read/prime it; InitContentDB keeps regenerating it through its own dedicated action block, avoiding a double snapshot. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Cast RegisterTaskDefinition to [void] so the returned RegisteredTask COM object (Name/Path/State/Xml...) is no longer emitted to the output stream and dumped into the transcript on every task creation, aligning with the SPSWeather Add-SPSSheduledTask behaviour. Keeps the success message only. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Pester Test Results 1 files 10 suites 1s ⏱️ Results for commit 45c0451. ♻️ This comment has been updated with latest results. |
Off a SharePoint server the function emits a non-terminating Write-Error and returns nothing. On the windows-latest CI runner Pester treats that stray error stream as a test failure (it passed on macOS only by luck of error handling). Redirect the error stream (2>$null) and assert on the captured null result instead, so the test is deterministic on every OS. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Add [CmdletBinding()] so the helper honours -ErrorAction. Off a SharePoint server it surfaces a non-terminating error and returns nothing; without CmdletBinding the previous test could not suppress that error, and the windows-latest CI runner promoted it to a failure. The test now calls it with -ErrorAction SilentlyContinue and asserts the null result, which is deterministic across macOS and Windows (verified with ErrorActionPreference set to Stop). Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #17.
Major modernization release aligning SPSUpdate with SPSWeather / SPSUserSync. Breaking (package layout, config format, credential storage).
Highlights
SPSUpdate.Commonmodule (Public/ + Private/, one function per file, manifest version4.0.0).Get-SPSSecret/Set-SPSSecret,Config\secrets.psd1) replacing the bundledcredentialmanagermodule.StoredCredential->CredentialKey; runtime/output files stay JSON. Single documentedCONTOSO-PROD.example.psd1with safe defaults.Invoke-SPSCommand(fail fast, no silent local fallback, OpenTimeout).Add-SPSScheduledTaskno longer dumps the RegisteredTask COM object.release.ymlzips the contents of src/;pester.ymltargets src/. Cross-platform Pester suite._Sidebar.md,Release-Process) + restored offline install guide.Validation
ProductUpdate(idempotent), fullDefaultrun with the four parallel sequences and per-server patch-status checks, and the DPAPI secret read end-to-end.See
RELEASE-NOTES.mdfor the full notes and the 3.x -> 4.0.0 migration steps.