Skip to content

Releases: luigilink/SPSConfigKit

v1.7.0

Choose a tag to compare

@github-actions github-actions released this 08 Jul 10:16
6dde88e

SPSConfigKit - Release Notes

[1.7.0] - 2026-07-08

Added

  • SQL Server connection encryption (TLS) (#27, #42)
    • CfgAppSql can now force TLS encryption of SQL Server connections, opt-in via
      NonNodeData.SQL.ForceEncryption (secure-by-default in the sample). It imports the
      pre-staged SQL certificate (CertificateName, default SQLServerCert) into
      LocalMachine\My with PfxImport and binds it to the instance with
      SqlSecureConnection (ForceEncryption, ServiceAccount). CfgAppSps imports the
      SQL certificate's public .cer into LocalMachine\Root on every SharePoint node so
      it trusts the SQL TLS chain, and drives the SPFarm DatabaseConnectionEncryption
      from NonNodeData.SQL.DatabaseConnectionEncryption.
    • The default level is Optional (traffic is encrypted because the SQL tier forces it;
      robust with the kit's SQL aliases and applies on both new and existing farms).
      Mandatory / Strict additionally validate the certificate chain and host name and
      require NonNodeData.SQL.DatabaseServerCertificateHostName to be set to a name in the
      SQL certificate SAN (the SQL alias never matches it). Note that
      DatabaseConnectionEncryption is honoured only when the configuration database is
      first created / joined — SPFarm does not change it on an already-joined farm.
  • SQL maintenance plan — Ola Hallengren Maintenance Solution (#31)
    • CfgAppSql can install the SQL Server Maintenance Solution
      (backups, index maintenance, integrity checks), opt-in via
      NonNodeData.SQL.InstallMaintenanceSolution. Initialize-SoftwarePackages downloads
      MaintenanceSolution.sql into the SQL source folder, so it is staged to the node with
      the rest of the SQL media (no runtime download on offline nodes). A SqlScript
      resource runs it under the SQL sysadmin RunAs and is idempotent (skipped once the
      CommandExecute procedure exists). The script is not bundled with the kit;
      scripts/sql/README.md documents the feature, the tunable DECLARE parameters, and
      credits Ola Hallengren. Job schedules are intentionally left to the SQL administrator.

Changelog

A full list of changes in each version can be found in the change log

v1.6.1

Choose a tag to compare

@github-actions github-actions released this 08 Jul 09:30
ac1a7b8

SPSConfigKit - Release Notes

[1.6.1] - 2026-07-08

Fixed

  • CfgAppSql no longer sets an invalid RestartService property on the SQL protocol
    resources (#40)
    • The SqlProtocol (MIDDLEWARE_SqlProtocolTcpEnabled) and SqlProtocolTcpIP
      (MIDDLEWARE_SqlProtocolTcpIP) resources set RestartService = $true, which is not a
      valid property in SqlServerDsc 17.5.1 — the DSC parser rejects it and MOF compilation
      fails. Both resources expose SuppressRestart (default $false) and RestartTimeout
      instead. The property is removed; the default SuppressRestart = $false already
      restarts the service when a protocol change requires it, so TCP/IP enablement still
      takes effect.

Changelog

A full list of changes in each version can be found in the change log

v1.6.0

Choose a tag to compare

@github-actions github-actions released this 07 Jul 17:40
49e6c0a

SPSConfigKit - Release Notes

[1.6.0] - 2026-07-07

Changed

  • Office Online Server integration is skipped when no OOS node is declared (#37)
    • On the SharePoint master, the OOS trusted root authority (SPTrustedRootAuthority
      for the Office Online CA certificate), the WOPI binding
      (SPOfficeOnlineServerBinding) and the PDF suppression settings
      (SPOfficeOnlineServerSupressionSettings) were provisioned unconditionally.
      On a farm that declares no IsOOSServer node this referenced
      NonNodeData.OOS / the OfficeOnlineCert that such a farm may legitimately
      omit, and pushed a WOPI binding for a server that does not exist. The three
      resources are now gated on the presence of at least one IsOOSServer node,
      mirroring the gating already applied to the OOS install Node block.

Fixed

  • NonNodeData.OOS.AllServers is validated against the declared OOS nodes (#38)
    • AllServers feeds the Servers list of the OOS cumulative update
      (OfficeOnlineServerProductUpdate). When it did not list every node carrying
      the IsOOSServer role, the CU was applied to an incomplete set of machines
      while the farm still reported those nodes (the shipped sample even drifted,
      with AllServers = @('OOS') while the node is OOS1). CfgAppSps.ps1 now
      throws at compile time when any IsOOSServer NodeName is missing from
      AllServers (only when the farm declares an OOS node), a matching Pester
      assertion covers the invariant, and the sample AllServers is corrected to
      @('OOS1').

Changelog

A full list of changes in each version can be found in the change log

v1.5.0

Choose a tag to compare

@github-actions github-actions released this 07 Jul 16:02
d548dfd

SPSConfigKit - Release Notes

[1.5.0] - 2026-07-07

Added

  • The domain controller publishes DNS A records for the farm host names (#33)
    • CfgAppPdc gains an optional NonNodeData.DnsRecords list
      (@{ Name; IPAddress }) and creates each A record in the domain zone with
      Add-DnsServerResourceRecordA, so the SharePoint web-application and Office
      Online host names (sharepoint.<domain>, oosweb.<domain>) resolve.
      Without them, farm creation fails at the WOPI binding step with
      "The server did not respond". Native DnsServer module (no new dependency),
      idempotent per record.
  • Optional domain-join helper for cloud nodes (#18)
    • New scripts/init/Add-DscNodeToDomain.ps1 (+ .psd1) points a node's DNS at
      the domain controller and joins it to Active Directory before the node's DSC
      configuration is applied. A freshly provisioned cloud VM (e.g. Azure, whose
      default DNS is 168.63.129.16) cannot otherwise resolve or join the domain.
      The helper is idempotent (skips when already a member), sets DNS only when
      DnsServers is provided (on-prem nodes with working DNS leave it @()),
      waits for the domain LDAP SRV record, joins with the Secrets.psd1
      JoinAccount credential (ADSETUP by default) honouring an optional
      OUPath, and restarts after a readable countdown (RestartDelaySec).
  • The pull server now publishes the SoftwarePackages SMB share (#19)
    • CfgAppPull.ps1 creates <Drives.Data>\SoftwarePackages and publishes it as
      the SMB share named after the last segment of NonNodeData.SourcePath
      (native New-SmbShare, no new DSC module, idempotent). A new optional
      NonNodeData.SoftwarePackagesShare.ReadAccess list (default
      'Authenticated Users') lets production lock the share down. Nodes no longer
      need the share created by hand before they can pull binaries.
  • Dashboard -Action Install provisions the node manifest share (#23)
    • SPSDscDashboard.ps1 -Action Install now creates the NodeManifestPath
      folder and publishes it as an SMB share (member nodes write their
      <NodeName>.json there at LCM registration via CfgLcmPull.ps1 -NodeManifestPath). Name and write access come from an optional
      NodeManifestShare block in SPSDscDashboard.psd1 (default share name = the
      folder leaf, default ChangeAccess = 'Authenticated Users'). A UNC
      NodeManifestPath is left untouched. -Action Default is unchanged.

Changed

  • Faster software-package downloads (#16)
    • Initialize-SoftwarePackages.ps1 sets $ProgressPreference = 'SilentlyContinue'
      (the Invoke-WebRequest progress bar made multi-GB downloads an order of
      magnitude slower on Windows PowerShell 5.1) and adds an Invoke-SPSDownload
      helper that prefers Start-BitsTransfer (resumable, faster) and falls back to
      Invoke-WebRequest when BITS is unavailable.

Fixed

  • Remote Event Log Management firewall rule no longer drifts every pass (#35)
    • The SYSTEM_EnableRemoteEventLogManagement Script tested the Domain profile
      but enabled the rule with -Profile Any, so its Test never matched its Set and
      the resource re-ran every consistency check (a permanent, error-free drift on
      all four configs). The Test now checks the Any profile.
  • CfgAppSps default disk Ids match the SharePoint VMs (no temp disk) (#32)
    • CfgAppSps.psd1 shipped the temp-disk layout (0/2/3), but the SharePoint VM
      sizes (APP / SCH / WFE) have no Azure temp disk, so their real layout is 0/1/2.
      Defaulted DATA to disk Number 1 and LOGS to Number 2; a VM with a temp disk
      still shifts to 0/2/3 (as PDC/PULL/SQL use).
  • Extracted ISO content is now unblocked (Mark-of-the-Web) (#30)
    • Initialize-SoftwarePackages unblocked directly-downloaded files but not
      content extracted from ISOs. Mounting a downloaded ISO propagates the
      Mark-of-the-Web to the copied files, so prerequisiteinstaller.exe stayed
      blocked and SharePoint's SPInstallPrereqs failed. The extracted content is
      now unblocked recursively.
  • SQL Server TCP/IP protocol is now enabled, not just its port (#29)
    • CfgAppSql set the IPAll TCP port but never enabled the TCP/IP protocol, so
      Configuration Manager showed TCP/IP = Disabled and the instance listened on no
      TCP port — SharePoint and remote clients failed with "SQL Server does not exist
      or access denied". A SqlProtocol resource now enables TcpIp (with a service
      restart) before the port is set.
  • CfgAppSps CU references now match the package manifest (#28)
    • The SharePoint (UberCumulativeUpdate) and OOS (CUFileName) cumulative
      updates referenced by CfgAppSps.psd1 pointed at older KBs than
      Initialize-SoftwarePackages.psd1 downloads, so a fresh farm's patch step
      looked for a CU that was never fetched. Aligned to the downloaded CUs
      (SharePoint kb5002863, OOS kb5002871).
  • Dashboard shows a node's last real state while a run is in flight (#34)
    • A node whose LCM is mid-consistency-check has an in-progress report on top
      (no Status, sentinel EndTime); the dashboard picked it and showed Unknown,
      hiding the real state. It now selects the most recent report with a definitive
      Status (Success/Failure).
  • Dashboard renders node errors and timestamps cleanly (#25)
    • Failed-node error banners showed raw report JSON with undecoded \uXXXX
      escapes; they now display the human-readable ErrorMessage. A node with no
      valid report yet (e.g. mid Update-DscConfiguration) showed the sentinel
      date 1899-12-30; it now renders .
  • CfgAppSql no longer creates a duplicate SqlLogin for the FARM account (#24)
    • When the farm account is also a SQL sysadmin (the default posture), the
      SQLSysAdministrators loop and the separate MIDDLEWARE_SqlLogin_FARM block
      created two SqlLogin resources for the same login, which DSC rejected with
      "conflicting values of PsDscRunAsCredential". The FARM login is now created
      only when it is not already in SQLSysAdministrators, and the dependent
      dbcreator / securityadmin SqlRole grants point at whichever login exists.
  • SQL configuration resources run under a SQL sysadmin account (#26)
    • SqlLogin / SqlRole / SqlMemory / SqlMaxDop / SqlProtocolTcpIP ran
      with PsDscRunAsCredential = $ADSETUP, which SqlSetup never grants sysadmin,
      so every SQL resource failed with "Failed to connect to SQL instance"
      (SQLCOMMON0019). They now run under $SETUP (a member of the default
      SQLSysAdministrators, so a sysadmin from install).
  • PDC WaitForADDomain no longer loops after a new-forest promotion (#17)
    • Removed Credential = $ADSETUP / WaitForValidCredentials = $true from
      WaitForADDomain WaitForDCReady: on the DC itself (running as SYSTEM) that
      impersonated a domain account this configuration has not created yet, so the
      resource never found the DC and looped WaitTimeout × RestartCount.
  • Pull server MOF can now be applied when document encryption is enabled (#20)
    • Added CertificateID = $Node.Thumbprint to the pull server's
      LocalConfigurationManager block (matching SQL/SPS/PDC), so the LCM can
      decrypt the encrypted MOF instead of failing with "The Local Configuration
      Manager is not configured with a certificate". The pull quick-start now also
      documents the Set-DscLocalConfigurationManager meta-config step.
  • Pull server resolves its own certificate paths locally (#22)
    • CfgAppPull.ps1 derives the DscPull .cer / .pfx paths from the local
      Data drive (<Drives.Data>\<share leaf>, e.g. F:\SoftwarePackages) instead
      of its own UNC share, removing a chicken-and-egg (the share is published by
      the same MOF, so the UNC did not resolve at first apply and xDscWebService
      failed on the 0000… sentinel thumbprint). The other configurations keep
      reading from the UNC share.

Changelog

A full list of changes in each version can be found in the change log

v1.4.0

Choose a tag to compare

@github-actions github-actions released this 06 Jul 14:32
ea8a5a9

SPSConfigKit - Release Notes

[1.4.0] - 2026-07-06

Added

  • Automatic data-disk initialisation during node bootstrap (#15)
    • New scripts/init/Initialize-DscDisks.ps1 prepares a node's data disks from
      the same NonNodeData.Disks block the configuration uses (read via
      -ConfigPath). It onlines each raw non-OS disk, applies a GPT partition,
      NTFS-formats it with the requested FSLabel / AllocationUnitSize and
      assigns the drive letter — so a brand-new farm has its volumes before
      anything writes to them, with no manual Get-Disk / Format-Volume step.
      Disk preparation is a one-time node-prep action, so it runs during bootstrap
      (like the domain join and module install) rather than inside the recurring
      application MOF. The script uses native Windows Storage cmdlets (no extra DSC
      module), is idempotent, and is non-destructive — a disk already carrying
      data is reported and left intact, never reformatted.
    • Every configuration (CfgAppSql / CfgAppSps / CfgAppPdc / CfgAppPull)
      declares its physical disks in a new authoritative NonNodeData.Disks array
      (Id / Letter / Type / FSLabel / AllocationUnitSize). Disks are keyed
      by disk Number (Get-Disk), portable across bare-metal, VMware, Hyper-V
      and Azure — not an Azure LUN. The OS disk (Type = 'OS') is never touched.
    • New NonNodeData.ManageDisks boolean (default $true). Set it to $false
      when the customer manages their own storage: Initialize-DscDisks.ps1 then
      does nothing, but the derived Drives hashtable is still produced so every
      path resolves.

Changed

  • NonNodeData.Drives is now DERIVED, not hand-written (#15)
    • Each Cfg*.ps1 builds NonNodeData.Drives = @{ Data; Logs; Temp } from the
      new Disks array (keyed by Type) immediately after loading the psd1, so a
      drive letter is declared exactly once (in Disks) instead of duplicated.
      All existing Drives.Data / Drives.Logs / Drives.Temp consumers keep
      working unchanged; Temp falls back to the Data letter when no dedicated
      Temp disk is declared. FSLabels follow an UPPERCASE convention
      (SYSTEM / DATA / LOGS / TEMP), and every tier declares at least the
      three baseline disks. SQL DATA / LOGS volumes use a 64KB allocation
      unit size per SQL Server best practice.
    • ConfigData.Tests.ps1 derives Drives from Disks the same way and adds a
      NonNodeData Disks check block (required per-disk keys, one OS disk,
      unique Ids and Letters, SYSTEM / DATA / LOGS present).

Changelog

A full list of changes in each version can be found in the change log

v1.3.1

Choose a tag to compare

@github-actions github-actions released this 02 Jul 17:39
ce129c6

SPSConfigKit - Release Notes

[1.3.1] - 2026-07-02

Changed

  • Sample share host moved off the domain controller (#13)
    • Every sample and wiki reference to the SoftwarePackages share now points at
      \\PULL\Softwarepackages (a member server) instead of \\PDC1\Softwarepackages
      (the domain controller). The v1.2.2 docs already required hosting the share on
      a member server — a node holds a machine session to the DC, and Windows refuses
      a second identity to the same server, so a share on the DC fails at apply with
      "Access is denied" — but the samples still pointed at the DC.
  • Certificate paths are now DRY (#13)
    • CfgAppSql/CfgAppSps/CfgAppPdc/CfgAppPull psd1 cert entries carry only
      the .cer / .pfx file name (CerFileName / PfxFileName); the full path
      is derived by the Cfg*.ps1 scripts from the single NonNodeData.SourcePath.
      The share host is therefore declared exactly once per configuration — changing
      servers is a one-line edit and the SourcePath/CertPath divergence that
      caused earlier PDC1↔PULL mismatches can no longer happen. An explicit
      CertPath / PfxPath on an entry is still honoured (backward compatible).
      NonNodeData.SourcePath was added to the PDC and PULL configurations, and the
      ConfigData.Tests.ps1 cert checks accept either the file-name or explicit-path
      form.

Changelog

A full list of changes in each version can be found in the change log

v1.3.0

Choose a tag to compare

@github-actions github-actions released this 02 Jul 17:07
0ae0580

SPSConfigKit - Release Notes

[1.3.0] - 2026-07-02

Added

  • scripts/dashboard/SPSDscDashboard.ps1 + SPSDscDashboard.psd1 (#6, #8, #9, #10, #11)
    • New DSC compliance dashboard tool, driven by -Action and configured by a
      tracked SPSDscDashboard.psd1 settings file (matching the SPSWakeUp -Action
      and SPSUserSync .psd1 conventions). Actions: Default generates a
      self-contained, dependency-free Dashboard.html (inline CSS/JS, SVG donut — no
      CDN) classifying every node as Compliant / Non-Compliant / Failed /
      Unresponsive with drift counts, last-report time, a per-node detail view and a
      persisted OS-aware light/dark theme toggle; Install registers/updates a
      Scheduled Task that refreshes it on a schedule into the IIS-served folder;
      Uninstall removes it. -MockDataPath renders offline. The node list comes
      from a shared manifest folder (populated by CfgLcmPull.ps1) queried via the
      keyed OData endpoint Nodes(AgentId='…')/Reports, because the classic pull
      server's OData API cannot enumerate nodes — GET /Nodes returns HTTP 400
      "resourceKeys is unexpected for MSFT.DSCNode" (#8). The refresh schedule
      enforces a 30-minute floor: nodes only report on their LCM consistency interval
      (typically 60-120 min), so a shorter refresh adds load without newer data (#10).
      Runs the task as SYSTEM by default; supports a domain RunAsUser for remote
      manifests. (Consolidates the earlier New-SPSDscDashboard.ps1 and
      Register-SPSDscDashboardTask.ps1 into one -Action-driven script (#11).)
      The script exposes only -Action, -InstallAccount and -InputFile; every
      other setting lives in the tracked SPSDscDashboard.psd1. The refresh task is
      created in the \SharePoint\ Task Scheduler folder (configurable via
      Schedule.TaskPath), alongside the other SPS* project tasks.
  • scripts/dashboard/README.md and scripts/dashboard/samples/
    • Dashboard documentation plus a mock-data.json fixture and New-MockData.ps1
      so the page can be generated and reviewed without a live pull server.

Changed

  • scripts/pull/CfgLcmPull.ps1 (#7, #8)
    • Enriched the LCM pull registration: added -UpdateNow (trigger the first pull
      immediately so the node applies its config and sends its first status report
      right away) and -DomainDefaultsPath, which resolves -DSCRegistrationKey /
      -DSCPullServerUrl per Active Directory domain from a git-ignored
      CfgLcmPull.DomainDefaults.psd1 (template *.sample.psd1 tracked). HTTPS/443
      and the ReportServerWeb block are kept so nodes report to the dashboard.
    • Added -NodeManifestPath: after registering, each node publishes a
      <NodeName>.json (NodeName + AgentId + ConfigurationNames) to a shared folder
      so the compliance dashboard can enumerate nodes (also resolvable per-domain via
      the NodeManifestPath key in the defaults file).

Changelog

A full list of changes in each version can be found in the change log

v1.2.2

Choose a tag to compare

@github-actions github-actions released this 02 Jul 15:11
93aaee1

SPSConfigKit - Release Notes

[1.2.2] - 2026-07-02

Fixed

  • LCM decryption certificate (CertificateID)
    • Since 1.2.0 made MOF encryption mandatory, every node's MOF carries encrypted
      credentials, but no LCM configuration told the LCM which certificate to
      decrypt them with. Start-DscConfiguration / Test-DscConfiguration failed
      on the first resource with "The Local Configuration Manager is not configured
      with a certificate"
      . CfgAppSql.ps1, CfgAppSps.ps1 and CfgAppPdc.ps1 now
      set LocalConfigurationManager.CertificateID = $Node.Thumbprint, and
      CfgLcmPull.ps1 sets Settings.CertificateID (resolved from the local
      CN=DSC Encryption certificate or the new -CertificateThumbprint).
  • Share-copy credential harmonised on $SETUP
    • The File resources that copy binaries from the SoftwarePackages share used
      three different accounts ($PULLSETUP in SQL, $ADSETUP for the SharePoint
      and OOS copies). They now all use $SETUP (svcspssetup), so a single account
      needs Read on the share. Genuine Active Directory operations keep $ADSETUP.
  • Initialize-DscEncryption.ps1 certificate drift
    • The script always re-exported the public .cer but only exported the private
      .pfx when -PfxPassword was supplied, so rotating without it left a stale
      .pfx and nodes failed with "Decryption failed". -Force now requires
      -PfxPassword, and the script verifies the .cer, the .pfx and the active
      certificate all share one thumbprint.

Added

  • Initialize-DscNode.ps1 hardening
    • Post-import validation that the certificate installed in the node's store
      matches the share's .cer thumbprint (and has its private key), flagging the
      mismatch that otherwise surfaces later as "Decryption failed".
    • -PullMode / -SkipModules switches to skip the local Install-Module phase
      (in Pull mode the pull server serves the modules as .zip packages).
    • -ShareAccessCredential to verify the share-copy account can actually read
      the SoftwarePackages share before the DSC apply does.
  • CfgLcmPull.ps1: -CertificateThumbprint / -CertificateSubject parameters to
    control the LCM decryption certificate lookup.

Changed

  • Wiki (Securing-Credentials, Usage, Getting-Started)
    • Document that the LCM CertificateID must be set (apply the *.meta.mof with
      Set-DscLocalConfigurationManager before pushing), the -Force/-PfxPassword
      rotation guard-rail, hosting the SoftwarePackages share on a member server
      (not a domain controller) with svcspssetup Read, and running
      Initialize-DscEncryption.ps1 on the authority host only. New troubleshooting
      rows for "LCM is not configured with a certificate" and "Decryption failed".

Changelog

A full list of changes in each version can be found in the change log

v1.2.1

Choose a tag to compare

@github-actions github-actions released this 02 Jul 09:15
b1d7d4d

SPSConfigKit - Release Notes

[1.2.1] - 2026-07-02

Fixed

  • scripts/pull/CfgAppPull.ps1
    • Removed the Script MIDDLEWARE_PullServer_DscServiceAcl resource that granted
      the pull-server AppPool identity write access to the DSC service folder via
      Get-Acl / Set-Acl. That folder is owned by NT SERVICE\TrustedInstaller
      and grants SYSTEM / Administrators only Modify (no Change-Permissions /
      WRITE_DAC), so Set-Acl failed at apply time with
      "Attempted to perform an unauthorized operation" — breaking the whole PULL
      Start-DscConfiguration run. The grant is now a dedicated post-configuration
      script (see Added) that takes ownership first, which the DSC consistency loop
      should not do.

Added

  • scripts/pull/Set-SPSPullServerPermission.ps1
    • New one-shot, elevated post-configuration script that grants the pull-server
      AppPool identity Modify on the DSC service folder (takeown /a then
      icacls /grant …:(OI)(CI)M), so the ESENT repository (Devices.edb) can be
      created. The AppPool identity is resolved from Secrets.psd1 (IISPULLAPP)
      by default so it always matches the account CfgAppPull.ps1 assigns, with
      -AppPoolIdentity as an explicit override. Idempotent, -WhatIf-aware, and
      parameterised by -SecretsFile / -AppPoolSecretName / -DscServicePath /
      -TakeOwnership, with a final verification.
  • scripts/pull/Publish-SPSPullModules.ps1
    • New script that packages the pinned DSC resource modules as
      <Name>_<Version>.zip + checksum into the pull server's Modules folder, so
      Pull-mode nodes can download the resources their MOF imports (without them the
      LCM fails at apply time with "could not find the module"). Reads the module
      list from Initialize-DscNode.psd1 by default, or derives it from a
      configuration's Import-DscResource lines via the AST with
      -ConfigurationScriptPath (replacing the fragile string-matching of the older
      ad-hoc PrepareModules.ps1). Idempotent, -WhatIf-aware, and parameterised by
      -ManifestPath / -ModulePath / -SourceModulesPath.
  • scripts/pull/README.md
    • Documents the end-to-end pull workflow (stand up server → grant permission →
      publish modules → publish MOFs → register LCMs with -UpdateNow → watch the
      dashboard) and why the ACL grant is a separate privileged step rather than a
      DSC resource.
  • .gitignore
    • Added a properly tracked .gitignore (ignoring .vscode/, **/.DS_Store,
      and the real CfgLcmPull.DomainDefaults.psd1), dropping the historical
      self-ignore line that kept .gitignore untracked across branches.

Changed

  • wiki/Usage.md
    • The pull-server option now documents the mandatory
      Set-SPSPullServerPermission.ps1 step and points at scripts/pull/README.md.

Changelog

A full list of changes in each version can be found in the change log

v1.2.0

Choose a tag to compare

@github-actions github-actions released this 01 Jul 14:11
fdf6081

SPSConfigKit - Release Notes

[1.2.0] - 2026-07-01

Added

  • scripts/test/MofEncryption.Tests.ps1 / scripts/test/Invoke-MofEncryptionTest.ps1
    • New post-compile Pester v5 guard-rail that scans compiled MOF files and fails
      (exit code 1) if any credential Password value is not a CMS-encrypted blob,
      or if a credential-bearing MOF is missing the ContentType="PasswordEncrypted"
      marker. Catches the most dangerous DSC mistake — shipping a MOF whose
      credentials were compiled in clear text — and is wired for CI / release gates.
  • wiki/Securing-Credentials.md
    • New dedicated page documenting why MOF credential encryption is mandatory, the
      end-to-end flow (Initialize-DscEncryption → import .pfx per node → compile →
      verify), the clear-text-vs-CMS before/after, certificate rotation with -Force,
      and a troubleshooting table.
  • .editorconfig
    • Locks repository encoding and formatting: *.ps1 / *.psd1 / *.psm1 are
      utf-8-bom (Windows PowerShell 5.1 reads a BOM-less file as ANSI, corrupting
      non-ASCII characters at runtime); *.md / *.yml / *.yaml / *.json stay
      BOM-less (YAML linters and dsc.exe reject a BOM).

Changed

  • scripts/test/ConfigData.Tests.ps1
    • The wildcard AllNodes baseline check no longer requires
      PSDscAllowPlainTextPassword = $true — which wrongly failed a secured
      configuration (the state left by Initialize-DscEncryption.ps1). It now
      validates the encrypted branch instead: when
      PSDscAllowPlainTextPassword = $false, the wildcard must carry a
      CertificateFile and a 40-hex-char Thumbprint; when the config isn't yet
      encrypted it is skipped with a reminder (the post-compile MofEncryption
      guard-rail is the hard gate).
  • Encoding — every *.ps1 / *.psd1 under scripts/ is now UTF-8 with BOM
    (13 previously BOM-less files converted; the 4 already-BOM files unchanged), so
    Windows PowerShell 5.1 always reads them as UTF-8. No functional content change.
  • README.md
    • New Security section stating that credentials are encrypted and that
      compiling them in clear text is not a supported configuration, with the
      four-step mandatory flow and a link to the new wiki page.
  • wiki/Getting-Started.md
    • Certificate generation (step 3) is now flagged mandatory with a security
      call-out; a new post-compile step runs Invoke-MofEncryptionTest.ps1 as a gate.
  • wiki/Usage.md
    • New "Verify the MOFs are encrypted" gate documented right after compilation.

Changelog

A full list of changes in each version can be found in the change log