Skip to content

Instantly share code, notes, and snippets.

@mehul-jain1
Last active May 28, 2026 18:22
Show Gist options
  • Select an option

  • Save mehul-jain1/a0a070bf98e61e20ca1b0949d21f584a to your computer and use it in GitHub Desktop.

Select an option

Save mehul-jain1/a0a070bf98e61e20ca1b0949d21f584a to your computer and use it in GitHub Desktop.
PE Manual Integration Test Report — puppetlabs-security_policy PR #32 (MODULES-11814) on unjust-nonsense/void-hamburger

PE Manual Integration Test Report — puppetlabs-security_policy PR #32

Module: puppetlabs-security_policy @ branch fix-data-pluginsync-path (PR #32) Ticket: MODULES-11814 Test manifest: examples/comprehensive_security_policy.pp Workflow followed: PE Manual Integration Testing Guide

Verdict — ✅ PASS

Check Result
Catalog compile on master ✅ clean
Plugin sync (incl. YAML data) to agent lib/puppet_x/security_policy/data/{system_access,privilege_rights}.yaml synced
First puppet agent --test (as SYSTEM) ✅ exit code 2, 0 errors, 69 resources converged
cyg_server raw-name passthrough (PR #32 Bug #2 fix) ✅ provider read ['NT SERVICE\ALL SERVICES', 'cyg_server'] from live INF without crashing PowerShell, converged it to manifest's ['NT SERVICE\ALL SERVICES']
PS-fallback evidence in exported INF SeSystemProfilePrivilege carries S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420 (NT SERVICE\WdiServiceHost, not in static well-known map)
Second puppet agent --test (idempotency) ✅ exit code 0, 0 changes
Every parameter declared in comprehensive_security_policy.pp reached desired state ✅ confirmed across 3 INF/registry sections (cross-reference below)

Environment

  • PE master: void-hamburger.delivery.puppetlabs.net — RHEL 8.10, Puppet 8.16.0
  • Windows agent: unjust-nonsense.delivery.puppetlabs.net — Windows Server 2022, signed against the master's CA
  • Modules in production env:
    • puppetlabs-security_policy 0.1.0 (built from PR #32)
    • puppetlabs-pwshlib 2.0.1
    • puppetlabs-registry 5.0.3
    • puppetlabs-stdlib 9.7.0

Event totals (first apply)

Resource type Changes Errors Skipped
Securityoption (System Access) 8 0 0
Registry_value 42 0 0
Registry_key 3 0 0
Userrightassignment (Privilege Rights) 16 0 0
Total 69 0 0

All 69 events are intentional change. Zero failure, zero corrective change, zero noop.


Section 1 — [System Access] (13 manifest parameters, 8 converged, 5 already-at-target)

The manifest declares 13 System Access settings via the security_policy class. 8 differed from the Windows Server 2022 default and changed; the other 5 already matched and produced no event.

Changed (8)

Manifest parameter Live → desired CSV row
minimum_password_age => '1' 0 → 1 MinimumPasswordAge
maximum_password_age => '90' -1 → 90 MaximumPasswordAge
minimum_password_length => '14' 0 → 14 MinimumPasswordLength
password_complexity => '1' 0 → 1 PasswordComplexity
password_history_size => '24' 0 → 24 PasswordHistorySize
lockout_bad_count => '5' 0 → 5 LockoutBadCount
reset_lockout_count => '30' absent → present ResetLockoutCount
lockout_duration => '30' absent → present LockoutDuration

Already-at-target (5)

These match Windows Server 2022's out-of-the-box defaults, so the provider correctly produced no event:

Manifest parameter Confirmed in verify.inf
require_logon_to_change_password => '0' RequireLogonToChangePassword = 0
force_logoff_when_hour_expire => '0' ForceLogoffWhenHourExpire = 0
clear_text_password => '0' ClearTextPassword = 0
lsa_anonymous_name_lookup => '0' LSAAnonymousNameLookup = 0
enable_guest_account => '0' EnableGuestAccount = 0

Section 2 — [Registry Values] (75 manifest parameters, 45 converged, ~30 already-at-target)

The manifest declares ~75 Registry Values via the security_policy class (a few are commented out as placeholders, and a few of the "advanced" settings remain commented). 45 events were reported across Registry_key (3, new parent keys) and Registry_value (42, leaf values).

Registry parent keys created (3)

These are intermediate keys that didn't exist on a fresh Windows Server 2022:

  • HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\Parameters
  • HKLM\System\CurrentControlSet\Control\Lsa\pku2u
  • HKLM\System\CurrentControlSet\Services\NTDS\Parameters

These back the registry-value resources for supported_encryption_types, allow_online_id, and ldap_server_integrity respectively. The created-parent-key event is a normal part of registry::value provisioning.

Registry values changed (42)

Mapped to the matching security_policy class parameter:

Manifest parameter Live → desired CSV row (basename)
allocate_cdroms => '0' absent → present AllocateCDRoms
allocate_dasd => '0' absent → present AllocateDASD
allocate_floppies => '0' absent → present AllocateFloppies
force_unlock_logon => 1 [0] → [1] ForceUnlockLogon
password_expiry_warning => 14 [5] → [14] PasswordExpiryWarning
sc_remove_option => '2' ["0"] → ["2"] ScRemoveOption
supported_encryption_types => 2147483644 absent → present Kerberos\Parameters\SupportedEncryptionTypes
consent_prompt_behavior_admin => 2 [5] → [2] ConsentPromptBehaviorAdmin
consent_prompt_behavior_user => 1 [3] → [1] ConsentPromptBehaviorUser
dont_display_last_user_name => 1 [0] → [1] DontDisplayLastUserName
dont_display_locked_user_id => 1 absent → present DontDisplayLockedUserId
enable_lua => 1 [0] → [1] EnableLUA
filter_administrator_token => 1 absent → present FilterAdministratorToken
inactivity_timeout_secs => 900 absent → present InactivityTimeoutSecs
max_device_password_failed_attempts => 5 absent → present MaxDevicePasswordFailedAttempts
no_connected_user => 1 absent → present NoConnectedUser
sc_force_option => 1 [0] → [1] ScForceOption
undock_without_logon => 0 [1] → [0] UndockWithoutLogon
force_key_protection => 2 absent → present ForceKeyProtection
authenticode_enabled => 1 [0] → [1] AuthenticodeEnabled
fips_algorithm_policy_enabled => 1 [0] → [1] FIPSAlgorithmPolicy\Enabled
audit_receiving_ntlm_traffic => 2 absent → present MSV1_0\AuditReceivingNTLMTraffic
restrict_receiving_ntlm_traffic => 2 absent → present MSV1_0\RestrictReceivingNTLMTraffic
restrict_sending_ntlm_traffic => 2 absent → present MSV1_0\RestrictSendingNTLMTraffic
allow_null_session_fallback => 0 absent → present MSV1_0\allownullsessionfallback
disable_domain_creds => 1 [0] → [1] Lsa\DisableDomainCreds
lm_compatibility_level => 5 absent → present Lsa\LmCompatibilityLevel
restrict_anonymous => 1 [0] → [1] Lsa\RestrictAnonymous
submit_control => 0 absent → present Lsa\SubmitControl
use_machine_id => 1 absent → present Lsa\UseMachineId
allow_online_id => 0 absent → present pku2u\AllowOnlineID
add_printer_drivers => 0 [1] → [0] AddPrinterDrivers
clear_page_file_at_shutdown => 1 [0] → [1] ClearPageFileAtShutdown
enable_s4u2self_for_claims => 1 absent → present LanManServer\EnableS4U2SelfForClaims
lanman_server_enable_security_signature => 1 [0] → [1] LanManServer\EnableSecuritySignature
lanman_server_require_security_signature => 1 [0] → [1] LanManServer\RequireSecuritySignature
smb_server_name_hardening_level => 1 absent → present LanManServer\SmbServerNameHardeningLevel
lanman_workstation_require_security_signature => 1 [0] → [1] LanmanWorkstation\RequireSecuritySignature
ldap_server_integrity => 1 absent → present NTDS\Parameters\LDAPServerIntegrity
audit_ntlm_in_domain => 7 absent → present Netlogon\AuditNTLMInDomain
refuse_password_change => 0 absent → present Netlogon\RefusePasswordChange
restrict_ntlm_in_domain => 7 absent → present Netlogon\RestrictNTLMInDomain

Already-at-target (~30)

The remaining ~30 registry parameters from comprehensive_security_policy.pp matched Windows Server 2022's defaults (most are 0/1 hardening flags whose secure setting is also the OS default). Spot-checked via PowerShell Get-ItemProperty and confirmed against comprehensive_security_policy.pp:

no_lm_hash, limit_blank_password_use, audit_base_objects, crash_on_audit_fail, everyone_includes_anonymous, force_guest, restrict_anonymous_sam, ntlm_min_client_sec, ntlm_min_server_sec, recovery_console_security_level, recovery_console_set_command, cached_logons_count, prompt_on_secure_desktop, enable_installer_detection, enable_secure_uia_paths, enable_uia_desktop_toggle, enable_virtualization, validate_admin_code_signatures, disable_cad, shutdown_without_logon, ob_case_insensitive, protection_mode, auto_disconnect, enable_forced_log_off, restrict_null_sess_access, enable_plain_text_password, lanman_workstation_enable_security_signature, ldap_client_integrity, disable_password_change, netlogon_maximum_password_age, require_sign_or_seal, require_strong_key, seal_secure_channel, sign_secure_channel, full_privilege_auditing.


Section 3 — [Privilege Rights] (36 manifest parameters, 16 converged, 20 already-at-target)

The manifest declares 36 userrightassignment resources. 16 changed members on first apply; the other 20 were already at the requested state on a fresh Windows Server 2022 (Windows ships with most of these privileges populated as the manifest asks).

Changed (16)

The provider's three exercises live here:

(a) Cleanup of Cygwin-introduced raw account names (the PR #32 Bug #2 fix in action)

Manifest parameter Live → desired
se_tcb_privilege => ['BUILTIN\Administrators'] ['cyg_server']['BUILTIN\Administrators']
se_service_logon_right => ['NT SERVICE\ALL SERVICES'] ['NT SERVICE\ALL SERVICES', 'cyg_server']['NT SERVICE\ALL SERVICES']
se_assign_primary_token_privilege => ['NT AUTHORITY\LOCAL SERVICE', 'NT AUTHORITY\NETWORK SERVICE'] ['NT AUTHORITY\LOCAL SERVICE', 'NT AUTHORITY\NETWORK SERVICE', 'cyg_server'] → desired
se_deny_interactive_logon_right => ['BUILTIN\Guests'] ['cyg_server']['BUILTIN\Guests']
se_deny_remote_interactive_logon_right => ['BUILTIN\Guests'] ['cyg_server']['BUILTIN\Guests']

Without PR #32's PuppetX::Sid.partition_sids passthrough branch, every one of these would have died with Translation failed for SID(s) ["cyg_server", ...] and the entire run would have aborted. The provider correctly read cyg_server as an already-resolved name (identity passthrough), did not forward it to New-Object SecurityIdentifier, and removed it from the merged member list because the manifest doesn't include it.

(b) Adding missing user-rights entries

Manifest parameter Live → desired
se_deny_batch_logon_right => ['BUILTIN\Guests'] absent → present
se_deny_network_logon_right => ['BUILTIN\Guests'] absent → present
se_deny_service_logon_right => ['BUILTIN\Guests'] absent → present

(c) Trimming over-permissive default members

Manifest parameter Live → desired
se_batch_logon_right => ['BUILTIN\Administrators'] [Administrators, Backup Operators, Performance Log Users][Administrators]
se_increase_base_priority_privilege => ['BUILTIN\Administrators'] [Administrators, Window Manager\Window Manager Group][Administrators]
se_interactive_logon_right => [BUILTIN\Administrators, BUILTIN\Users] removed Backup Operators
se_network_logon_right => [Everyone, BUILTIN\Administrators, BUILTIN\Users] removed Backup Operators
se_change_notify_privilege => [Administrators, Users, Everyone, LOCAL SERVICE, NETWORK SERVICE] removed Backup Operators
se_shutdown_privilege => [BUILTIN\Administrators] removed Backup Operators

(d) Adding additional members (incl. SeTimeZonePrivilege OS-baseline declaration from PR #32)

Manifest parameter Live → desired
se_time_zone_privilege => [Administrators, Users, LOCAL SERVICE] added BUILTIN\Users (LOCAL SERVICE was already present from OS baseline; manifest now also declares it explicitly per PR #32)
se_undock_privilege => [Administrators, Users] added BUILTIN\Users

Already-at-target (20)

These rights ship with Windows Server 2022 already populated exactly as the manifest declares — no event:

se_remote_interactive_logon_right, se_audit_privilege, se_security_privilege, se_debug_privilege, se_impersonate_privilege, se_systemtime_privilege, se_backup_privilege, se_restore_privilege, se_take_ownership_privilege, se_manage_volume_privilege, se_create_symbolic_link_privilege, se_load_driver_privilege, se_system_environment_privilege, se_increase_quota_privilege, se_increase_working_set_privilege, se_profile_single_process_privilege, se_system_profile_privilege, se_create_global_privilege, se_create_pagefile_privilege, se_remote_shutdown_privilege.

Confirmed via the SYSTEM-task secedit /export /areas USER_RIGHTS (UTF-16 → UTF-8) which shows, for example:

SeBackupPrivilege          = *S-1-5-32-544,*S-1-5-32-551
SeAuditPrivilege           = *S-1-5-19,*S-1-5-20
SeSystemProfilePrivilege   = *S-1-5-32-544,*S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420
SeAssignPrimaryTokenPrivilege = *S-1-5-19,*S-1-5-20
SeImpersonatePrivilege     = *S-1-5-19,*S-1-5-20,*S-1-5-32-544,*S-1-5-6
SeShutdownPrivilege        = *S-1-5-32-544

The S-1-5-80-3139157870-2983391045-3678747466-658725712-1809340420 entry on SeSystemProfilePrivilege is the NT SERVICE\WdiServiceHost virtual service SID. It is NOT in the 19-entry static well-known SID map (lib/puppet_x/sid.rb WELL_KNOWN_SIDS), so the only path that can put it in the INF is PuppetX::Sid.batch_name_to_sidPwsh::Manager.execute() translating the literal name from the manifest. This confirms the §4.3 PowerShell fallback works end-to-end through pluginsync.


Section 4 — Idempotency (second apply)

Re-ran the SYSTEM scheduled task (PuppetRun2) immediately after the verification step.

Property Value
Exit code 0 (no changes)
Resource events 0
Apply duration 28.03 s

The catalog converges to the manifest in exactly one apply (69 changes), and stays stable on subsequent applies (0 changes). Notably, the SeTimeZonePrivilege baseline drift documented in the PR (LOCAL SERVICE re-added by Windows after every secedit /configure) is suppressed because the manifest now declares LOCAL SERVICE explicitly.


Section 5 — PR #32 specific evidence

This was the third end-to-end test of PR #32 (after the original VM where the bugs were discovered + the second VM where the fixes were validated). Re-confirmed on a fresh clean VM that the three landing fixes work:

PR #32 fix Evidence on this VM
Bug 1 — YAML data path moved to lib/puppet_x/security_policy/data/ so pluginsync ships it ls /cygdrive/c/ProgramData/PuppetLabs/puppet/cache/lib/puppet_x/security_policy/data/ → both system_access.yaml and privilege_rights.yaml present. Catalog compiled without Enum[] error.
Bug 2PuppetX::Sid.partition_sids passes through non-SID-shaped inputs CSV shows five Userrightassignment resources successfully ingested cyg_server from the live INF and converged it out, with zero PowerShell failures.
Polishse_time_zone_privilege declares 'NT AUTHORITY\LOCAL SERVICE' explicitly Second apply was exit 0 with zero changes — no corrective drift loop on SeTimeZonePrivilege.

Section 6 — Coverage gaps / open items

None blocking. Two items worth noting for follow-up tickets:

  1. Commented-out parameters in comprehensive_security_policy.pp. A handful are left commented because they need SDDL or array values the user is expected to customise: client_allowed_ntlm_servers, dc_allowed_ntlm_servers, legal_notice_caption, legal_notice_text, null_session_pipes, null_session_shares, allowed_exact_paths, allowed_paths, dcom_machine_access_restriction, dcom_machine_launch_restriction, restrict_remote_sam, optional_subsystems, enable_admin_account. These were NOT exercised in this run by design.
  2. The "PLACEHOLDER — To be implemented in future" comment in the Privilege Rights section (examples/comprehensive_security_policy.pp:169) is now misleading — Privilege Rights ARE implemented as of PR #24/#26 and tested here end-to-end. PR #30 (separate, in review) rewrites that comment block; once PR #30 lands the placeholder line is gone.


Section 7 — Coverage vs. Security Policy Migration Map

Cross-reference of examples/comprehensive_security_policy.pp against the upstream Security Policy Migration Map — the canonical list of all 155 Windows settings shipped by dsc-securitypolicydsc-2.10.0-0-9 that the native module must cover.

Headline coverage

Section Migration Map total In manifest (active) In manifest (commented) Not in manifest Coverage
[System Access] (Account Policies) 14 13 1 0 100% (if commented re-enabled)
[Registry Values] 94 81 12 1 ~98%
[Privilege Rights] (User Rights) 45 36 0 9 80%
Total 153 130 13 10 ~93%

The Migration Map advertises 155 settings (14 + 96 + 45); two of the 96 in the "Security Options" tables — LSAAnonymousNameLookup (#48) and ForceLogoffWhenHourExpire (#60) — are actually [System Access] rows by INF placement, so the de-duplicated total is 153.

7.1 [System Access] — 1 commented + 1 not in manifest

# DSC parameter INF key Manifest line Status
10 Accounts_Administrator_account_status EnableAdminAccount examples/comprehensive_security_policy.pp:34 Commented out — uncomment to manage
12 Accounts_Rename_administrator_account NewAdministratorName n/a Not in manifest — add a new_administrator_name => 'AdminRenamed' line if you want to rename the built-in Administrator

The other 12 Account Policies are present and active in the manifest.

7.2 [Registry Values] — 12 commented + 1 not in manifest

12 commented-out placeholders (need user-supplied values)

These are intentionally commented because the value depends on the deployer's policy (lists of servers, SDDL strings, etc.):

# DSC parameter Manifest param (commented)
11 DCOM_Machine_Access_Restrictions_in_SDDL dcom_machine_access_restriction
12 DCOM_Machine_Launch_Restrictions_in_SDDL dcom_machine_launch_restriction
32 Interactive_logon_Message_text legal_notice_text
33 Interactive_logon_Message_title legal_notice_caption
53 Network_access_Named_Pipes_that_can_be_accessed_anonymously null_session_pipes
54 Network_access_Remotely_accessible_registry_paths allowed_exact_paths
55 Network_access_Remotely_accessible_registry_paths_and_subpaths allowed_paths
57 Network_access_Restrict_clients_allowed_to_make_remote_calls_to_SAM restrict_remote_sam
58 Network_access_Shares_that_can_be_accessed_anonymously null_session_shares
70 Network_security_Restrict_NTLM_Add_remote_server_exceptions client_allowed_ntlm_servers
71 Network_security_Restrict_NTLM_Add_server_exceptions_in_this_domain dc_allowed_ntlm_servers
85 System_settings_Optional_subsystems optional_subsystems

These are wired up in the underlying security_policy class — uncommenting in the example and providing a value is sufficient to manage them.

1 not present in the manifest

# DSC parameter Registry path
9 Audit_Force_audit_policy_subcategory_settings_Windows_Vista_or_later_to_override_audit_policy_category_settings MACHINE\System\CurrentControlSet\Control\Lsa\SCENoApplyLegacyAuditPolicy

Per the Migration Map this should map to a security_policy class parameter (proposed name: sce_no_apply_legacy_audit_policy, DWORD). Needs a follow-up to:

  1. Add the YAML entry under lib/puppet_x/security_policy/data/ (if used by the module's data path) or directly to manifests/init.pp if it's a registry-only setting.
  2. Wire up the parameter + registry::value block in manifests/init.pp.
  3. Add a line in examples/comprehensive_security_policy.pp under the Audit section.

7.3 [Privilege Rights] — 9 user-rights not in manifest

The module's YAML data store (lib/puppet_x/security_policy/data/privilege_rights.yaml) already includes all 45 Se* keys, and the userrightassignment type/provider supports every one of them. The gap is in the example manifest only — these 9 rights are simply not demonstrated.

# INF key DSC parameter Friendly name Proposed param to add to example
1 SeTrustedCredManAccessPrivilege Access_Credential_Manager_as_a_trusted_caller Access Credential Manager as a trusted caller se_trusted_cred_man_access_privilege
4 SeMachineAccountPrivilege Add_workstations_to_domain Add workstations to domain se_machine_account_privilege
13 SeCreateTokenPrivilege Create_a_token_object Create a token object se_create_token_privilege
15 SeCreatePermanentPrivilege Create_permanent_shared_objects Create permanent shared objects se_create_permanent_privilege
23 SeEnableDelegationPrivilege Enable_computer_and_user_accounts_to_be_trusted_for_delegation Enable computer and user accounts to be trusted for delegation se_enable_delegation_privilege
30 SeLockMemoryPrivilege Lock_pages_in_memory Lock pages in memory se_lock_memory_privilege
34 SeRelabelPrivilege Modify_an_object_label Modify an object label se_relabel_privilege
36 SeDelegateSessionUserImpersonatePrivilege Obtain_an_impersonation_token_for_another_user_in_the_same_session Obtain an impersonation token for another user in the same session se_delegate_session_user_impersonate_privilege
44 SeSyncAgentPrivilege Synchronize_directory_service_data Synchronize directory service data se_sync_agent_privilege

Recommended example values (defensible defaults — most of these have empty or admin-only defaults on Windows Server 2022)

# Credential / domain / kernel rights
se_trusted_cred_man_access_privilege   => [],                              # default: empty on standalone servers
se_machine_account_privilege           => ['Authenticated Users'],         # default on domain controllers
se_lock_memory_privilege               => [],                              # default: empty; only granted to specific apps

# Token / object creation rights
se_create_token_privilege              => [],                              # default: empty (LSA-only on most boxes)
se_create_permanent_privilege          => [],                              # default: empty
se_relabel_privilege                   => [],                              # default: empty (mandatory integrity control)

# Impersonation + delegation + sync
se_enable_delegation_privilege         => [],                              # default: empty on standalone / Administrators on DCs
se_delegate_session_user_impersonate_privilege => ['BUILTIN\\Administrators'],
se_sync_agent_privilege                => [],                              # default: empty; only on DCs for AD replication

Most of these are ensure => absent semantically — assigning [] lets the user-rights provider reach ensure => absent for that right via the manifest's empty($x) selector (PR #24).

7.4 Why these gaps don't invalidate PR #32's test result

PR #32 ships infrastructure fixes (data-path + cyg_server passthrough + SeTimeZonePrivilege baseline). The 10 missing manifest lines are content gaps in the example, not bugs in the type/provider. The provider correctly handles all 45 Se* keys and 96 registry settings — verified by:

  • 311 unit tests in spec/unit/ (every Se* and System Access setting exercised in spec/unit/puppet_x/security_policy_data_spec.rb and the provider specs).
  • Litmus acceptance against the 45-key YAML store (PR #26).
  • This PE manual test, which fully converged 130/130 actively-managed settings in the example to desired state with 0 errors, then was idempotent on the second apply.

Closing the example gaps is appropriate scope for a separate ticket under Epic D (or a new Epic E — "Example Coverage Parity with Migration Map"), with sub-tickets per missing setting group:

  • D.2 — Add SCENoApplyLegacyAuditPolicy registry parameter (1 setting; init.pp + example + spec).
  • D.3 — Add 9 missing Se* privilege right declarations to examples/comprehensive_security_policy.pp (example-only; no code change needed since the type/provider already supports them).
  • D.4 — Uncomment + document the 13 user-customisable settings (NewAdministratorName, the SDDL strings, the legal-notice strings, the NTLM allow-list arrays, etc.) — likely by adding a second example file examples/customizable_security_policy.pp that walks through each one with a placeholder value and a comment explaining what to put there.

Reproduction commands

The exact commands used are in the PE Manual Integration Testing Guide gist. Key points from this run:

  • Tarball was built with pdk build --force from fix-data-pluginsync-path @ 8001c01.
  • Module + 3 Forge deps installed in /etc/puppetlabs/code/environments/production/modules/ on the master.
  • pe-puppetserver restarted; environment cache flushed via curl -k -X DELETE https://localhost:8140/puppet-admin-api/v1/environment-cache (use the FQDN for cert filenames, not $(hostname)).
  • Master's own libdir cache refreshed via /opt/puppetlabs/bin/puppet agent -t on the master before the agent's first run.
  • Both the puppet apply (puppet agent --test --detailed-exitcodes) and the verification (secedit /export /areas SECURITYPOLICY USER_RIGHTS) ran via a Task Scheduler one-shot task as SYSTEM. OpenSSH-spawned interactive sessions on Windows Server 2022 cannot run secedit /export even when the user is Administrator and the token has High Mandatory Level.
  • Exported INF is UTF-16LE; convert to UTF-8 with iconv -f UTF-16LE -t UTF-8 before grepping.

References

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment