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
| 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) |
- 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
productionenv:puppetlabs-security_policy 0.1.0(built from PR #32)puppetlabs-pwshlib 2.0.1puppetlabs-registry 5.0.3puppetlabs-stdlib 9.7.0
| 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.
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.
| 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 |
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 ✓ |
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).
These are intermediate keys that didn't exist on a fresh Windows Server 2022:
HKLM\Software\Microsoft\Windows\CurrentVersion\Policies\System\Kerberos\ParametersHKLM\System\CurrentControlSet\Control\Lsa\pku2uHKLM\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.
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 |
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.
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).
The provider's three exercises live here:
| 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.
| 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 |
| 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 |
| 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 |
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_sid → Pwsh::Manager.execute() translating the literal name from the manifest. This confirms the §4.3 PowerShell fallback works end-to-end through pluginsync.
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.
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 2 — PuppetX::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. |
Polish — se_time_zone_privilege declares 'NT AUTHORITY\LOCAL SERVICE' explicitly |
Second apply was exit 0 with zero changes — no corrective drift loop on SeTimeZonePrivilege. |
None blocking. Two items worth noting for follow-up tickets:
- 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. - 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.
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.
| 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.
| # | 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.
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.
| # | 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:
- Add the YAML entry under
lib/puppet_x/security_policy/data/(if used by the module's data path) or directly tomanifests/init.ppif it's a registry-only setting. - Wire up the parameter +
registry::valueblock inmanifests/init.pp. - Add a line in
examples/comprehensive_security_policy.ppunder the Audit section.
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 replicationMost 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).
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 inspec/unit/puppet_x/security_policy_data_spec.rband 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
SCENoApplyLegacyAuditPolicyregistry parameter (1 setting; init.pp + example + spec). - D.3 — Add 9 missing
Se*privilege right declarations toexamples/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 fileexamples/customizable_security_policy.ppthat walks through each one with a placeholder value and a comment explaining what to put there.
The exact commands used are in the PE Manual Integration Testing Guide gist. Key points from this run:
- Tarball was built with
pdk build --forcefromfix-data-pluginsync-path @ 8001c01. - Module + 3 Forge deps installed in
/etc/puppetlabs/code/environments/production/modules/on the master. pe-puppetserverrestarted; environment cache flushed viacurl -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 -ton 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 asSYSTEM. OpenSSH-spawned interactive sessions on Windows Server 2022 cannot runsecedit /exporteven when the user isAdministratorand the token hasHigh Mandatory Level. - Exported INF is UTF-16LE; convert to UTF-8 with
iconv -f UTF-16LE -t UTF-8before grepping.
- PR: https://github.com/puppetlabs/puppetlabs-security_policy/pull/32
- Jira: https://perforce.atlassian.net/browse/MODULES-11814
- Manifest under test: https://github.com/puppetlabs/puppetlabs-security_policy/blob/fix-data-pluginsync-path/examples/comprehensive_security_policy.pp
- Testing guide: https://gist.github.com/mehul-jain1/5f4b5f10dbf9a07b9c4536ef41c84555
- SPEC: https://github.com/puppetlabs/puppetlabs-security_policy/blob/fix-data-pluginsync-path/plan/SPEC.md
- Parent epic: MODULES-11664